Исправления
This commit is contained in:
323
Modbus.cpp
323
Modbus.cpp
@@ -11,12 +11,12 @@ std::vector<TRegister> _regs;
|
|||||||
std::vector<TCallback> _callbacks;
|
std::vector<TCallback> _callbacks;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint16_t Modbus::mbCallback(TRegister* reg, uint16_t val, TCallback::CallbackType t)
|
uint16_t Modbus::mbCallback(TRegister *reg, uint16_t val, TCallback::CallbackType t) {
|
||||||
{
|
|
||||||
uint16_t newVal = val;
|
uint16_t newVal = val;
|
||||||
std::vector<TCallback>::iterator it = _callbacks.begin();
|
auto it = _callbacks.begin();
|
||||||
do {
|
do {
|
||||||
it = std::find_if(it, _callbacks.end(), [reg, t](TCallback& cb) { return cb.address == reg->address && cb.type == t; });
|
it = std::find_if(it, _callbacks.end(),
|
||||||
|
[reg, t](TCallback &cb) { return cb.address == reg->address && cb.type == t; });
|
||||||
if (it != _callbacks.end()) {
|
if (it != _callbacks.end()) {
|
||||||
newVal = it->cb(reg, newVal);
|
newVal = it->cb(reg, newVal);
|
||||||
it++;
|
it++;
|
||||||
@@ -25,31 +25,28 @@ uint16_t Modbus::mbCallback(TRegister* reg, uint16_t val, TCallback::CallbackTyp
|
|||||||
return newVal;
|
return newVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRegister* Modbus::searchRegister(TAddress address)
|
TRegister *Modbus::searchRegister(TAddress address) {
|
||||||
{
|
auto it = std::find_if(_regs.begin(), _regs.end(), [address](TRegister &addr) { return addr.address == address; });
|
||||||
std::vector<TRegister>::iterator it = std::find_if(_regs.begin(), _regs.end(), [address](TRegister& addr) { return addr.address == address; });
|
|
||||||
if (it != _regs.end())
|
if (it != _regs.end())
|
||||||
return &*it;
|
return &*it;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Modbus::addReg(TAddress address, uint16_t value, uint16_t numregs)
|
bool Modbus::addReg(TAddress address, uint16_t value, uint16_t numregs) {
|
||||||
{
|
|
||||||
#ifdef MB_MAX_REGS
|
#ifdef MB_MAX_REGS
|
||||||
if (_regs.size() + numregs > MB_MAX_REGS)
|
if (_regs.size() + numregs > MB_MAX_REGS)
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
for (uint16_t i = 0; i < numregs; i++) {
|
for (uint16_t i = 0; i < numregs; i++) {
|
||||||
if (!searchRegister(address + i))
|
if (!searchRegister(address + i))
|
||||||
_regs.push_back({ address + i, value });
|
_regs.push_back({address + i, value});
|
||||||
}
|
}
|
||||||
//std::sort(_regs.begin(), _regs.end());
|
//std::sort(_regs.begin(), _regs.end());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Modbus::Reg(TAddress address, uint16_t value)
|
bool Modbus::Reg(TAddress address, uint16_t value) {
|
||||||
{
|
TRegister *reg;
|
||||||
TRegister* reg;
|
|
||||||
reg = searchRegister(address); //search for the register address
|
reg = searchRegister(address); //search for the register address
|
||||||
if (reg) { //if found then assign the register value to the new value.
|
if (reg) { //if found then assign the register value to the new value.
|
||||||
if (cbEnabled) {
|
if (cbEnabled) {
|
||||||
@@ -62,9 +59,8 @@ bool Modbus::Reg(TAddress address, uint16_t value)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t Modbus::Reg(TAddress address)
|
uint16_t Modbus::Reg(TAddress address) {
|
||||||
{
|
TRegister *reg;
|
||||||
TRegister* reg;
|
|
||||||
reg = searchRegister(address);
|
reg = searchRegister(address);
|
||||||
if (reg)
|
if (reg)
|
||||||
if (cbEnabled) {
|
if (cbEnabled) {
|
||||||
@@ -76,9 +72,8 @@ uint16_t Modbus::Reg(TAddress address)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Modbus::removeReg(TAddress address, uint16_t numregs)
|
bool Modbus::removeReg(TAddress address, uint16_t numregs) {
|
||||||
{
|
TRegister *reg;
|
||||||
TRegister* reg;
|
|
||||||
bool atLeastOne = false;
|
bool atLeastOne = false;
|
||||||
for (uint16_t i = 0; i < numregs; i++) {
|
for (uint16_t i = 0; i < numregs; i++) {
|
||||||
reg = searchRegister(address + i);
|
reg = searchRegister(address + i);
|
||||||
@@ -92,11 +87,10 @@ bool Modbus::removeReg(TAddress address, uint16_t numregs)
|
|||||||
return atLeastOne;
|
return atLeastOne;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Modbus::slavePDU(uint8_t* frame)
|
void Modbus::slavePDU(uint8_t *frame) {
|
||||||
{
|
auto fcode = (FunctionCode) frame[0];
|
||||||
FunctionCode fcode = (FunctionCode)frame[0];
|
uint16_t field1 = (uint16_t) frame[1] << 8 | (uint16_t) frame[2];
|
||||||
uint16_t field1 = (uint16_t)frame[1] << 8 | (uint16_t)frame[2];
|
uint16_t field2 = (uint16_t) frame[3] << 8 | (uint16_t) frame[4];
|
||||||
uint16_t field2 = (uint16_t)frame[3] << 8 | (uint16_t)frame[4];
|
|
||||||
uint16_t bytecount_calc;
|
uint16_t bytecount_calc;
|
||||||
uint16_t k;
|
uint16_t k;
|
||||||
switch (fcode) {
|
switch (fcode) {
|
||||||
@@ -131,7 +125,7 @@ void Modbus::slavePDU(uint8_t* frame)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (k >= field2) {
|
if (k >= field2) {
|
||||||
setMultipleWords((uint16_t*)(frame + 6), HREG(field1), field2);
|
setMultipleWords((uint16_t *) (frame + 6), HREG(field1), field2);
|
||||||
successResponce(HREG(field1), field2, fcode);
|
successResponce(HREG(field1), field2, fcode);
|
||||||
_reply = REPLY_NORMAL;
|
_reply = REPLY_NORMAL;
|
||||||
}
|
}
|
||||||
@@ -174,7 +168,8 @@ void Modbus::slavePDU(uint8_t* frame)
|
|||||||
bytecount_calc = field2 / 8;
|
bytecount_calc = field2 / 8;
|
||||||
if (field2 % 8)
|
if (field2 % 8)
|
||||||
bytecount_calc++;
|
bytecount_calc++;
|
||||||
if (field2 < 0x0001 || field2 > 0x07B0 || frame[5] != bytecount_calc) { //Check registers range and data size maches
|
if (field2 < 0x0001 || field2 > 0x07B0 ||
|
||||||
|
frame[5] != bytecount_calc) { //Check registers range and data size maches
|
||||||
exceptionResponse(fcode, EX_ILLEGAL_VALUE);
|
exceptionResponse(fcode, EX_ILLEGAL_VALUE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -196,11 +191,10 @@ void Modbus::slavePDU(uint8_t* frame)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Modbus::successResponce(TAddress startreg, uint16_t numoutputs, FunctionCode fn)
|
void Modbus::successResponce(TAddress startreg, uint16_t numoutputs, FunctionCode fn) {
|
||||||
{
|
|
||||||
free(_frame);
|
free(_frame);
|
||||||
_len = 5;
|
_len = 5;
|
||||||
_frame = (uint8_t*)malloc(_len);
|
_frame = (uint8_t *) malloc(_len);
|
||||||
_frame[0] = fn;
|
_frame[0] = fn;
|
||||||
_frame[1] = startreg.address >> 8;
|
_frame[1] = startreg.address >> 8;
|
||||||
_frame[2] = startreg.address & 0x00FF;
|
_frame[2] = startreg.address & 0x00FF;
|
||||||
@@ -208,18 +202,16 @@ void Modbus::successResponce(TAddress startreg, uint16_t numoutputs, FunctionCod
|
|||||||
_frame[4] = numoutputs & 0x00FF;
|
_frame[4] = numoutputs & 0x00FF;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Modbus::exceptionResponse(FunctionCode fn, ResultCode excode)
|
void Modbus::exceptionResponse(FunctionCode fn, ResultCode excode) {
|
||||||
{
|
|
||||||
free(_frame);
|
free(_frame);
|
||||||
_len = 2;
|
_len = 2;
|
||||||
_frame = (uint8_t*)malloc(_len);
|
_frame = (uint8_t *) malloc(_len);
|
||||||
_frame[0] = fn + 0x80;
|
_frame[0] = fn + 0x80;
|
||||||
_frame[1] = excode;
|
_frame[1] = excode;
|
||||||
_reply = REPLY_NORMAL;
|
_reply = REPLY_NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Modbus::getMultipleBits(uint8_t* frame, TAddress startreg, uint16_t numregs)
|
void Modbus::getMultipleBits(uint8_t *frame, TAddress startreg, uint16_t numregs) {
|
||||||
{
|
|
||||||
uint8_t bitn = 0;
|
uint8_t bitn = 0;
|
||||||
uint16_t i = 0;
|
uint16_t i = 0;
|
||||||
while (numregs--) {
|
while (numregs--) {
|
||||||
@@ -236,15 +228,13 @@ void Modbus::getMultipleBits(uint8_t* frame, TAddress startreg, uint16_t numregs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Modbus::getMultipleWords(uint16_t* frame, TAddress startreg, uint16_t numregs)
|
void Modbus::getMultipleWords(uint16_t *frame, TAddress startreg, uint16_t numregs) {
|
||||||
{
|
for (uint16_t i = 0; i < numregs; i++) {
|
||||||
for (uint8_t i = 0; i < numregs; i++) {
|
|
||||||
frame[i] = __bswap_16(Reg(startreg + i));
|
frame[i] = __bswap_16(Reg(startreg + i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Modbus::readBits(TAddress startreg, uint16_t numregs, FunctionCode fn)
|
void Modbus::readBits(TAddress startreg, uint16_t numregs, FunctionCode fn) {
|
||||||
{
|
|
||||||
if (numregs < 0x0001 || numregs > 0x07D0) { //Check value (numregs)
|
if (numregs < 0x0001 || numregs > 0x07D0) { //Check value (numregs)
|
||||||
exceptionResponse(fn, EX_ILLEGAL_VALUE);
|
exceptionResponse(fn, EX_ILLEGAL_VALUE);
|
||||||
return;
|
return;
|
||||||
@@ -264,7 +254,7 @@ void Modbus::readBits(TAddress startreg, uint16_t numregs, FunctionCode fn)
|
|||||||
_len = 2 + numregs / 8;
|
_len = 2 + numregs / 8;
|
||||||
if (numregs % 8)
|
if (numregs % 8)
|
||||||
_len++; //Add 1 to the message length for the partial byte.
|
_len++; //Add 1 to the message length for the partial byte.
|
||||||
_frame = (uint8_t*)malloc(_len);
|
_frame = (uint8_t *) malloc(_len);
|
||||||
if (!_frame) {
|
if (!_frame) {
|
||||||
exceptionResponse(fn, EX_SLAVE_FAILURE);
|
exceptionResponse(fn, EX_SLAVE_FAILURE);
|
||||||
return;
|
return;
|
||||||
@@ -276,8 +266,7 @@ void Modbus::readBits(TAddress startreg, uint16_t numregs, FunctionCode fn)
|
|||||||
_reply = REPLY_NORMAL;
|
_reply = REPLY_NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Modbus::readWords(TAddress startreg, uint16_t numregs, FunctionCode fn)
|
void Modbus::readWords(TAddress startreg, uint16_t numregs, FunctionCode fn) {
|
||||||
{
|
|
||||||
//Check value (numregs)
|
//Check value (numregs)
|
||||||
if (numregs < 0x0001 || numregs > 0x007D) {
|
if (numregs < 0x0001 || numregs > 0x007D) {
|
||||||
exceptionResponse(fn, EX_ILLEGAL_VALUE);
|
exceptionResponse(fn, EX_ILLEGAL_VALUE);
|
||||||
@@ -289,19 +278,18 @@ void Modbus::readWords(TAddress startreg, uint16_t numregs, FunctionCode fn)
|
|||||||
}
|
}
|
||||||
free(_frame);
|
free(_frame);
|
||||||
_len = 2 + numregs * 2; //calculate the query reply message length. 2 bytes per register + 2 bytes for header
|
_len = 2 + numregs * 2; //calculate the query reply message length. 2 bytes per register + 2 bytes for header
|
||||||
_frame = (uint8_t*)malloc(_len);
|
_frame = (uint8_t *) malloc(_len);
|
||||||
if (!_frame) {
|
if (!_frame) {
|
||||||
exceptionResponse(fn, EX_SLAVE_FAILURE);
|
exceptionResponse(fn, EX_SLAVE_FAILURE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_frame[0] = fn;
|
_frame[0] = fn;
|
||||||
_frame[1] = _len - 2; //byte count
|
_frame[1] = _len - 2; //byte count
|
||||||
getMultipleWords((uint16_t*)(_frame + 2), startreg, numregs);
|
getMultipleWords((uint16_t *) (_frame + 2), startreg, numregs);
|
||||||
_reply = REPLY_NORMAL;
|
_reply = REPLY_NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Modbus::setMultipleBits(uint8_t* frame, TAddress startreg, uint16_t numoutputs)
|
void Modbus::setMultipleBits(const uint8_t *frame, TAddress startreg, uint16_t numoutputs) {
|
||||||
{
|
|
||||||
uint8_t bitn = 0;
|
uint8_t bitn = 0;
|
||||||
uint16_t i = 0;
|
uint16_t i = 0;
|
||||||
while (numoutputs--) {
|
while (numoutputs--) {
|
||||||
@@ -315,16 +303,14 @@ void Modbus::setMultipleBits(uint8_t* frame, TAddress startreg, uint16_t numoutp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Modbus::setMultipleWords(uint16_t* frame, TAddress startreg, uint16_t numregs)
|
void Modbus::setMultipleWords(const uint16_t *frame, TAddress startreg, uint16_t numregs) {
|
||||||
{
|
for (uint16_t i = 0; i < numregs; i++) {
|
||||||
for (uint8_t i = 0; i < numregs; i++) {
|
|
||||||
Reg(startreg + i, __bswap_16(frame[i]));
|
Reg(startreg + i, __bswap_16(frame[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Modbus::onGet(TAddress address, cbModbus cb, uint16_t numregs)
|
bool Modbus::onGet(TAddress address, cbModbus cb, uint16_t numregs) {
|
||||||
{
|
TRegister *reg;
|
||||||
TRegister* reg;
|
|
||||||
bool atLeastOne = false;
|
bool atLeastOne = false;
|
||||||
if (!cb) {
|
if (!cb) {
|
||||||
return removeOnGet(address);
|
return removeOnGet(address);
|
||||||
@@ -332,25 +318,7 @@ bool Modbus::onGet(TAddress address, cbModbus cb, uint16_t numregs)
|
|||||||
while (numregs > 0) {
|
while (numregs > 0) {
|
||||||
reg = searchRegister(address);
|
reg = searchRegister(address);
|
||||||
if (reg) {
|
if (reg) {
|
||||||
_callbacks.push_back({ TCallback::ON_GET, address, cb });
|
_callbacks.push_back({TCallback::ON_GET, address, cb});
|
||||||
atLeastOne = true;
|
|
||||||
}
|
|
||||||
address++;
|
|
||||||
numregs--;
|
|
||||||
}
|
|
||||||
return atLeastOne;
|
|
||||||
}
|
|
||||||
bool Modbus::onSet(TAddress address, cbModbus cb, uint16_t numregs)
|
|
||||||
{
|
|
||||||
TRegister* reg;
|
|
||||||
bool atLeastOne = false;
|
|
||||||
if (!cb) {
|
|
||||||
return removeOnGet(address);
|
|
||||||
}
|
|
||||||
while (numregs > 0) {
|
|
||||||
reg = searchRegister(address);
|
|
||||||
if (reg) {
|
|
||||||
_callbacks.push_back({ TCallback::ON_SET, address, cb });
|
|
||||||
atLeastOne = true;
|
atLeastOne = true;
|
||||||
}
|
}
|
||||||
address++;
|
address++;
|
||||||
@@ -359,28 +327,48 @@ bool Modbus::onSet(TAddress address, cbModbus cb, uint16_t numregs)
|
|||||||
return atLeastOne;
|
return atLeastOne;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Modbus::removeOnSet(TAddress address, cbModbus cb, uint16_t numregs)
|
bool Modbus::onSet(TAddress address, cbModbus cb, uint16_t numregs) {
|
||||||
{
|
TRegister *reg;
|
||||||
while (numregs--) {
|
bool atLeastOne = false;
|
||||||
_callbacks.erase(remove_if(_callbacks.begin(), _callbacks.end(), [address, cb](TCallback entry) { return entry.type == TCallback::ON_SET && entry.address == address && (!cb || entry.cb == cb); }), _callbacks.end());
|
if (!cb) {
|
||||||
address++;
|
return removeOnGet(address);
|
||||||
}
|
}
|
||||||
return false;
|
while (numregs > 0) {
|
||||||
|
reg = searchRegister(address);
|
||||||
|
if (reg) {
|
||||||
|
_callbacks.push_back({TCallback::ON_SET, address, cb});
|
||||||
|
atLeastOne = true;
|
||||||
|
}
|
||||||
|
address++;
|
||||||
|
numregs--;
|
||||||
|
}
|
||||||
|
return atLeastOne;
|
||||||
}
|
}
|
||||||
bool Modbus::removeOnGet(TAddress address, cbModbus cb, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::removeOnSet(TAddress address, cbModbus cb, uint16_t numregs) {
|
||||||
while (numregs--) {
|
while (numregs--) {
|
||||||
_callbacks.erase(remove_if(_callbacks.begin(), _callbacks.end(), [address, cb](TCallback entry) { return entry.type == TCallback::ON_GET && entry.address == address && (!cb || entry.cb == cb); }), _callbacks.end());
|
_callbacks.erase(remove_if(_callbacks.begin(), _callbacks.end(), [address, cb](TCallback entry) {
|
||||||
|
return entry.type == TCallback::ON_SET && entry.address == address && (!cb || entry.cb == cb);
|
||||||
|
}), _callbacks.end());
|
||||||
address++;
|
address++;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Modbus::readSlave(uint16_t address, uint16_t numregs, FunctionCode fn)
|
bool Modbus::removeOnGet(TAddress address, cbModbus cb, uint16_t numregs) {
|
||||||
{
|
while (numregs--) {
|
||||||
|
_callbacks.erase(remove_if(_callbacks.begin(), _callbacks.end(), [address, cb](TCallback entry) {
|
||||||
|
return entry.type == TCallback::ON_GET && entry.address == address && (!cb || entry.cb == cb);
|
||||||
|
}), _callbacks.end());
|
||||||
|
address++;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Modbus::readSlave(uint16_t address, uint16_t numregs, FunctionCode fn) {
|
||||||
free(_frame);
|
free(_frame);
|
||||||
_len = 5;
|
_len = 5;
|
||||||
_frame = (uint8_t*)malloc(_len);
|
_frame = (uint8_t *) malloc(_len);
|
||||||
_frame[0] = fn;
|
_frame[0] = fn;
|
||||||
_frame[1] = address >> 8;
|
_frame[1] = address >> 8;
|
||||||
_frame[2] = address & 0x00FF;
|
_frame[2] = address & 0x00FF;
|
||||||
@@ -389,13 +377,12 @@ bool Modbus::readSlave(uint16_t address, uint16_t numregs, FunctionCode fn)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Modbus::writeSlaveBits(TAddress startreg, uint16_t to, uint16_t numregs, FunctionCode fn, bool* data)
|
bool Modbus::writeSlaveBits(TAddress startreg, uint16_t to, uint16_t numregs, FunctionCode fn, bool *data) {
|
||||||
{
|
|
||||||
free(_frame);
|
free(_frame);
|
||||||
_len = 6 + numregs / 8;
|
_len = 6 + numregs / 8;
|
||||||
if (numregs % 8)
|
if (numregs % 8)
|
||||||
_len++; //Add 1 to the message length for the partial byte.
|
_len++; //Add 1 to the message length for the partial byte.
|
||||||
_frame = (uint8_t*)malloc(_len);
|
_frame = (uint8_t *) malloc(_len);
|
||||||
if (_frame) {
|
if (_frame) {
|
||||||
_frame[0] = fn;
|
_frame[0] = fn;
|
||||||
_frame[1] = to >> 8;
|
_frame[1] = to >> 8;
|
||||||
@@ -416,11 +403,10 @@ bool Modbus::writeSlaveBits(TAddress startreg, uint16_t to, uint16_t numregs, Fu
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Modbus::writeSlaveWords(TAddress startreg, uint16_t to, uint16_t numregs, FunctionCode fn, uint16_t* data)
|
bool Modbus::writeSlaveWords(TAddress startreg, uint16_t to, uint16_t numregs, FunctionCode fn, const uint16_t *data) {
|
||||||
{
|
|
||||||
free(_frame);
|
free(_frame);
|
||||||
_len = 6 + 2 * numregs;
|
_len = 6 + 2 * numregs;
|
||||||
_frame = (uint8_t*)malloc(_len);
|
_frame = (uint8_t *) malloc(_len);
|
||||||
if (_frame) {
|
if (_frame) {
|
||||||
_frame[0] = fn;
|
_frame[0] = fn;
|
||||||
_frame[1] = to >> 8;
|
_frame[1] = to >> 8;
|
||||||
@@ -429,12 +415,12 @@ bool Modbus::writeSlaveWords(TAddress startreg, uint16_t to, uint16_t numregs, F
|
|||||||
_frame[4] = numregs & 0x00FF;
|
_frame[4] = numregs & 0x00FF;
|
||||||
_frame[5] = _len - 6;
|
_frame[5] = _len - 6;
|
||||||
if (data) {
|
if (data) {
|
||||||
uint16_t* frame = (uint16_t*)(_frame + 6);
|
auto *frame = (uint16_t *) (_frame + 6);
|
||||||
for (uint8_t i = 0; i < numregs; i++) {
|
for (uint16_t i = 0; i < numregs; i++) {
|
||||||
frame[i] = __bswap_16(data[i]);
|
frame[i] = __bswap_16(data[i]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
getMultipleWords((uint16_t*)(_frame + 6), startreg, numregs);
|
getMultipleWords((uint16_t *) (_frame + 6), startreg, numregs);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -442,8 +428,7 @@ bool Modbus::writeSlaveWords(TAddress startreg, uint16_t to, uint16_t numregs, F
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Modbus::boolToBits(uint8_t* dst, bool* src, uint16_t numregs)
|
void Modbus::boolToBits(uint8_t *dst, const bool *src, uint16_t numregs) {
|
||||||
{
|
|
||||||
uint8_t bitn = 0;
|
uint8_t bitn = 0;
|
||||||
uint16_t i = 0;
|
uint16_t i = 0;
|
||||||
uint16_t j = 0;
|
uint16_t j = 0;
|
||||||
@@ -461,8 +446,7 @@ void Modbus::boolToBits(uint8_t* dst, bool* src, uint16_t numregs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Modbus::bitsToBool(bool* dst, uint8_t* src, uint16_t numregs)
|
void Modbus::bitsToBool(bool *dst, const uint8_t *src, uint16_t numregs) {
|
||||||
{
|
|
||||||
uint8_t bitn = 0;
|
uint8_t bitn = 0;
|
||||||
uint16_t i = 0;
|
uint16_t i = 0;
|
||||||
uint16_t j = 0;
|
uint16_t j = 0;
|
||||||
@@ -477,15 +461,14 @@ void Modbus::bitsToBool(bool* dst, uint8_t* src, uint16_t numregs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Modbus::masterPDU(uint8_t* frame, uint8_t* sourceFrame, TAddress startreg, uint16_t* output)
|
void Modbus::masterPDU(uint8_t *frame, const uint8_t *sourceFrame, TAddress startreg, uint16_t *output) {
|
||||||
{
|
|
||||||
uint8_t fcode = frame[0];
|
uint8_t fcode = frame[0];
|
||||||
_reply = EX_SUCCESS;
|
_reply = EX_SUCCESS;
|
||||||
if ((fcode & 0x80) != 0) {
|
if ((fcode & 0x80) != 0) {
|
||||||
_reply = frame[1];
|
_reply = frame[1];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint16_t field2 = (uint16_t)sourceFrame[3] << 8 | (uint16_t)sourceFrame[4];
|
uint16_t field2 = (uint16_t) sourceFrame[3] << 8 | (uint16_t) sourceFrame[4];
|
||||||
uint8_t bytecount_calc;
|
uint8_t bytecount_calc;
|
||||||
switch (fcode) {
|
switch (fcode) {
|
||||||
case FC_READ_REGS:
|
case FC_READ_REGS:
|
||||||
@@ -498,13 +481,13 @@ void Modbus::masterPDU(uint8_t* frame, uint8_t* sourceFrame, TAddress startreg,
|
|||||||
if (output) {
|
if (output) {
|
||||||
frame += 2;
|
frame += 2;
|
||||||
while (field2) {
|
while (field2) {
|
||||||
*((uint16_t*)output) = __bswap_16(*((uint16_t*)frame));
|
*((uint16_t *) output) = __bswap_16(*((uint16_t *) frame));
|
||||||
frame += 2;
|
frame += 2;
|
||||||
output += 2;
|
output += 2;
|
||||||
field2--;
|
field2--;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setMultipleWords((uint16_t*)(frame + 2), startreg, field2);
|
setMultipleWords((uint16_t *) (frame + 2), startreg, field2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FC_READ_COILS:
|
case FC_READ_COILS:
|
||||||
@@ -518,7 +501,7 @@ void Modbus::masterPDU(uint8_t* frame, uint8_t* sourceFrame, TAddress startreg,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (output) {
|
if (output) {
|
||||||
bitsToBool((bool*)output, frame + 2, field2);
|
bitsToBool((bool *) output, frame + 2, field2);
|
||||||
} else {
|
} else {
|
||||||
setMultipleBits(frame + 2, startreg, field2);
|
setMultipleBits(frame + 2, startreg, field2);
|
||||||
}
|
}
|
||||||
@@ -533,146 +516,142 @@ void Modbus::masterPDU(uint8_t* frame, uint8_t* sourceFrame, TAddress startreg,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Modbus::cbEnable(bool state)
|
void Modbus::cbEnable(bool state) {
|
||||||
{
|
|
||||||
cbEnabled = state;
|
cbEnabled = state;
|
||||||
}
|
}
|
||||||
void Modbus::cbDisable()
|
|
||||||
{
|
void Modbus::cbDisable() {
|
||||||
cbEnable(false);
|
cbEnable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Modbus::addHreg(uint16_t offset, uint16_t value, uint16_t numregs)
|
bool Modbus::addHreg(uint16_t offset, uint16_t value, uint16_t numregs) {
|
||||||
{
|
|
||||||
return addReg(HREG(offset), value, numregs);
|
return addReg(HREG(offset), value, numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::Hreg(uint16_t offset, uint16_t value)
|
|
||||||
{
|
bool Modbus::Hreg(uint16_t offset, uint16_t value) {
|
||||||
return Reg(HREG(offset), value);
|
return Reg(HREG(offset), value);
|
||||||
}
|
}
|
||||||
uint16_t Modbus::Hreg(uint16_t offset)
|
|
||||||
{
|
uint16_t Modbus::Hreg(uint16_t offset) {
|
||||||
return Reg(HREG(offset));
|
return Reg(HREG(offset));
|
||||||
}
|
}
|
||||||
uint16_t Modbus::removeHreg(uint16_t offset, uint16_t numregs)
|
|
||||||
{
|
uint16_t Modbus::removeHreg(uint16_t offset, uint16_t numregs) {
|
||||||
return removeReg(HREG(offset), numregs);
|
return removeReg(HREG(offset), numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::addCoil(uint16_t offset, bool value, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::addCoil(uint16_t offset, bool value, uint16_t numregs) {
|
||||||
return addReg(COIL(offset), COIL_VAL(value), numregs);
|
return addReg(COIL(offset), COIL_VAL(value), numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::addIsts(uint16_t offset, bool value, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::addIsts(uint16_t offset, bool value, uint16_t numregs) {
|
||||||
return addReg(ISTS(offset), ISTS_VAL(value), numregs);
|
return addReg(ISTS(offset), ISTS_VAL(value), numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::addIreg(uint16_t offset, uint16_t value, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::addIreg(uint16_t offset, uint16_t value, uint16_t numregs) {
|
||||||
return addReg(IREG(offset), value, numregs);
|
return addReg(IREG(offset), value, numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::Coil(uint16_t offset, bool value)
|
|
||||||
{
|
bool Modbus::Coil(uint16_t offset, bool value) {
|
||||||
return Reg(COIL(offset), COIL_VAL(value));
|
return Reg(COIL(offset), COIL_VAL(value));
|
||||||
}
|
}
|
||||||
bool Modbus::Ists(uint16_t offset, bool value)
|
|
||||||
{
|
bool Modbus::Ists(uint16_t offset, bool value) {
|
||||||
return Reg(ISTS(offset), ISTS_VAL(value));
|
return Reg(ISTS(offset), ISTS_VAL(value));
|
||||||
}
|
}
|
||||||
bool Modbus::Ireg(uint16_t offset, uint16_t value)
|
|
||||||
{
|
bool Modbus::Ireg(uint16_t offset, uint16_t value) {
|
||||||
return Reg(IREG(offset), value);
|
return Reg(IREG(offset), value);
|
||||||
}
|
}
|
||||||
bool Modbus::Coil(uint16_t offset)
|
|
||||||
{
|
bool Modbus::Coil(uint16_t offset) {
|
||||||
return COIL_BOOL(Reg(COIL(offset)));
|
return COIL_BOOL(Reg(COIL(offset)));
|
||||||
}
|
}
|
||||||
bool Modbus::Ists(uint16_t offset)
|
|
||||||
{
|
bool Modbus::Ists(uint16_t offset) {
|
||||||
return ISTS_BOOL(Reg(ISTS(offset)));
|
return ISTS_BOOL(Reg(ISTS(offset)));
|
||||||
}
|
}
|
||||||
uint16_t Modbus::Ireg(uint16_t offset)
|
|
||||||
{
|
uint16_t Modbus::Ireg(uint16_t offset) {
|
||||||
return Reg(IREG(offset));
|
return Reg(IREG(offset));
|
||||||
}
|
}
|
||||||
bool Modbus::removeCoil(uint16_t offset, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::removeCoil(uint16_t offset, uint16_t numregs) {
|
||||||
return removeReg(COIL(offset), numregs);
|
return removeReg(COIL(offset), numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::removeIsts(uint16_t offset, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::removeIsts(uint16_t offset, uint16_t numregs) {
|
||||||
return removeReg(ISTS(offset), numregs);
|
return removeReg(ISTS(offset), numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::removeIreg(uint16_t offset, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::removeIreg(uint16_t offset, uint16_t numregs) {
|
||||||
return removeReg(IREG(offset), numregs);
|
return removeReg(IREG(offset), numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::onGetCoil(uint16_t offset, cbModbus cb, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::onGetCoil(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||||||
return onGet(COIL(offset), cb, numregs);
|
return onGet(COIL(offset), cb, numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::onSetCoil(uint16_t offset, cbModbus cb, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::onSetCoil(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||||||
return onSet(COIL(offset), cb, numregs);
|
return onSet(COIL(offset), cb, numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::onGetHreg(uint16_t offset, cbModbus cb, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::onGetHreg(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||||||
return onGet(HREG(offset), cb, numregs);
|
return onGet(HREG(offset), cb, numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::onSetHreg(uint16_t offset, cbModbus cb, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::onSetHreg(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||||||
return onSet(HREG(offset), cb, numregs);
|
return onSet(HREG(offset), cb, numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::onGetIsts(uint16_t offset, cbModbus cb, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::onGetIsts(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||||||
return onGet(ISTS(offset), cb, numregs);
|
return onGet(ISTS(offset), cb, numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::onSetIsts(uint16_t offset, cbModbus cb, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::onSetIsts(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||||||
return onSet(ISTS(offset), cb, numregs);
|
return onSet(ISTS(offset), cb, numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::onGetIreg(uint16_t offset, cbModbus cb, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::onGetIreg(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||||||
return onGet(IREG(offset), cb, numregs);
|
return onGet(IREG(offset), cb, numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::onSetIreg(uint16_t offset, cbModbus cb, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::onSetIreg(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||||||
return onSet(IREG(offset), cb, numregs);
|
return onSet(IREG(offset), cb, numregs);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Modbus::removeOnGetCoil(uint16_t offset, cbModbus cb, uint16_t numregs)
|
bool Modbus::removeOnGetCoil(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||||||
{
|
|
||||||
return removeOnGet(COIL(offset), cb, numregs);
|
return removeOnGet(COIL(offset), cb, numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::removeOnSetCoil(uint16_t offset, cbModbus cb, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::removeOnSetCoil(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||||||
return removeOnSet(COIL(offset), cb, numregs);
|
return removeOnSet(COIL(offset), cb, numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::removeOnGetHreg(uint16_t offset, cbModbus cb, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::removeOnGetHreg(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||||||
return removeOnGet(HREG(offset), cb, numregs);
|
return removeOnGet(HREG(offset), cb, numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::removeOnSetHreg(uint16_t offset, cbModbus cb, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::removeOnSetHreg(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||||||
return removeOnSet(HREG(offset), cb, numregs);
|
return removeOnSet(HREG(offset), cb, numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::removeOnGetIsts(uint16_t offset, cbModbus cb, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::removeOnGetIsts(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||||||
return removeOnGet(ISTS(offset), cb, numregs);
|
return removeOnGet(ISTS(offset), cb, numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::removeOnSetIsts(uint16_t offset, cbModbus cb, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::removeOnSetIsts(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||||||
return removeOnSet(ISTS(offset), cb, numregs);
|
return removeOnSet(ISTS(offset), cb, numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::removeOnGetIreg(uint16_t offset, cbModbus cb, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::removeOnGetIreg(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||||||
return removeOnGet(IREG(offset), cb, numregs);
|
return removeOnGet(IREG(offset), cb, numregs);
|
||||||
}
|
}
|
||||||
bool Modbus::removeOnSetIreg(uint16_t offset, cbModbus cb, uint16_t numregs)
|
|
||||||
{
|
bool Modbus::removeOnSetIreg(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||||||
return removeOnSet(IREG(offset), cb, numregs);
|
return removeOnSet(IREG(offset), cb, numregs);
|
||||||
}
|
}
|
||||||
|
|
||||||
Modbus::~Modbus()
|
Modbus::~Modbus() {
|
||||||
{
|
|
||||||
free(_frame);
|
free(_frame);
|
||||||
}
|
}
|
||||||
|
|||||||
138
Modbus.h
138
Modbus.h
@@ -8,6 +8,7 @@
|
|||||||
#include "mbed.h"
|
#include "mbed.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
#include <byteswap.h>
|
#include <byteswap.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -39,66 +40,70 @@
|
|||||||
|
|
||||||
struct TRegister;
|
struct TRegister;
|
||||||
|
|
||||||
typedef uint16_t (*cbModbus)(TRegister* reg, uint16_t val); // Callback function Type
|
typedef uint16_t (*cbModbus)(TRegister *reg, uint16_t val); // Callback function Type
|
||||||
|
|
||||||
struct TAddress {
|
struct TAddress {
|
||||||
enum RegType { COIL,
|
enum RegType {
|
||||||
|
COIL,
|
||||||
ISTS,
|
ISTS,
|
||||||
IREG,
|
IREG,
|
||||||
HREG };
|
HREG
|
||||||
|
};
|
||||||
RegType type;
|
RegType type;
|
||||||
uint16_t address;
|
uint16_t address;
|
||||||
bool operator==(const TAddress& obj) const
|
|
||||||
{ // TAddress == TAddress
|
bool operator==(const TAddress &obj) const { // TAddress == TAddress
|
||||||
return type == obj.type && address == obj.address;
|
return type == obj.type && address == obj.address;
|
||||||
}
|
}
|
||||||
bool operator!=(const TAddress& obj) const
|
|
||||||
{ // TAddress != TAddress
|
bool operator!=(const TAddress &obj) const { // TAddress != TAddress
|
||||||
return type != obj.type || address != obj.address;
|
return type != obj.type || address != obj.address;
|
||||||
}
|
}
|
||||||
TAddress& operator++()
|
|
||||||
{ // ++TAddress
|
TAddress &operator++() { // ++TAddress
|
||||||
address++;
|
address++;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
TAddress operator++(int)
|
|
||||||
{ // TAddress++
|
const TAddress operator++(int) { // TAddress++
|
||||||
TAddress result(*this);
|
TAddress result(*this);
|
||||||
++(*this);
|
++(*this);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
TAddress& operator+=(const int& inc)
|
|
||||||
{ // TAddress += integer
|
TAddress &operator+=(const int &inc) { // TAddress += integer
|
||||||
address += inc;
|
address += inc;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
const TAddress operator+(const int& inc) const
|
|
||||||
{ // TAddress + integer
|
TAddress operator+(const int &inc) const { // TAddress + integer
|
||||||
TAddress result(*this);
|
TAddress result(*this);
|
||||||
result.address += inc;
|
result.address += inc;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
bool isCoil()
|
|
||||||
{
|
bool isCoil() const {
|
||||||
return type == COIL;
|
return type == COIL;
|
||||||
}
|
}
|
||||||
bool isIsts()
|
|
||||||
{
|
bool isIsts() const {
|
||||||
return type == ISTS;
|
return type == ISTS;
|
||||||
}
|
}
|
||||||
bool isIreg()
|
|
||||||
{
|
bool isIreg() const {
|
||||||
return type == IREG;
|
return type == IREG;
|
||||||
}
|
}
|
||||||
bool isHreg()
|
|
||||||
{
|
bool isHreg() const {
|
||||||
return type == HREG;
|
return type == HREG;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TCallback {
|
struct TCallback {
|
||||||
enum CallbackType { ON_SET,
|
enum CallbackType {
|
||||||
ON_GET };
|
ON_SET,
|
||||||
|
ON_GET
|
||||||
|
};
|
||||||
CallbackType type;
|
CallbackType type;
|
||||||
TAddress address;
|
TAddress address;
|
||||||
cbModbus cb;
|
cbModbus cb;
|
||||||
@@ -107,8 +112,8 @@ struct TCallback {
|
|||||||
struct TRegister {
|
struct TRegister {
|
||||||
TAddress address;
|
TAddress address;
|
||||||
uint16_t value;
|
uint16_t value;
|
||||||
bool operator==(const TRegister& obj) const
|
|
||||||
{
|
bool operator==(const TRegister &obj) const {
|
||||||
return address == obj.address;
|
return address == obj.address;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -151,23 +156,41 @@ public:
|
|||||||
EX_CONNECTION_LOST = 0xE5, // Custom. Connection with device lost
|
EX_CONNECTION_LOST = 0xE5, // Custom. Connection with device lost
|
||||||
EX_CANCEL = 0xE6 // Custom. Transaction/request canceled
|
EX_CANCEL = 0xE6 // Custom. Transaction/request canceled
|
||||||
};
|
};
|
||||||
|
|
||||||
~Modbus();
|
~Modbus();
|
||||||
|
|
||||||
bool addHreg(uint16_t offset, uint16_t value = 0, uint16_t numregs = 1);
|
bool addHreg(uint16_t offset, uint16_t value = 0, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool Hreg(uint16_t offset, uint16_t value);
|
bool Hreg(uint16_t offset, uint16_t value);
|
||||||
|
|
||||||
uint16_t Hreg(uint16_t offset);
|
uint16_t Hreg(uint16_t offset);
|
||||||
|
|
||||||
uint16_t removeHreg(uint16_t offset, uint16_t numregs = 1);
|
uint16_t removeHreg(uint16_t offset, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool addCoil(uint16_t offset, bool value = false, uint16_t numregs = 1);
|
bool addCoil(uint16_t offset, bool value = false, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool addIsts(uint16_t offset, bool value = false, uint16_t numregs = 1);
|
bool addIsts(uint16_t offset, bool value = false, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool addIreg(uint16_t offset, uint16_t value = 0, uint16_t numregs = 1);
|
bool addIreg(uint16_t offset, uint16_t value = 0, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool Coil(uint16_t offset, bool value);
|
bool Coil(uint16_t offset, bool value);
|
||||||
|
|
||||||
bool Ists(uint16_t offset, bool value);
|
bool Ists(uint16_t offset, bool value);
|
||||||
|
|
||||||
bool Ireg(uint16_t offset, uint16_t value);
|
bool Ireg(uint16_t offset, uint16_t value);
|
||||||
|
|
||||||
bool Coil(uint16_t offset);
|
bool Coil(uint16_t offset);
|
||||||
|
|
||||||
bool Ists(uint16_t offset);
|
bool Ists(uint16_t offset);
|
||||||
|
|
||||||
uint16_t Ireg(uint16_t offset);
|
uint16_t Ireg(uint16_t offset);
|
||||||
|
|
||||||
bool removeCoil(uint16_t offset, uint16_t numregs = 1);
|
bool removeCoil(uint16_t offset, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool removeIsts(uint16_t offset, uint16_t numregs = 1);
|
bool removeIsts(uint16_t offset, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool removeIreg(uint16_t offset, uint16_t numregs = 1);
|
bool removeIreg(uint16_t offset, uint16_t numregs = 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
bool Hreg(uint16_t offset, uint16_t* value);
|
bool Hreg(uint16_t offset, uint16_t* value);
|
||||||
bool Coil(uint16_t offset, bool* value);
|
bool Coil(uint16_t offset, bool* value);
|
||||||
@@ -175,38 +198,57 @@ public:
|
|||||||
bool Ireg(uint16_t offset, uint16_t* value);
|
bool Ireg(uint16_t offset, uint16_t* value);
|
||||||
*/
|
*/
|
||||||
void cbEnable(bool state = true);
|
void cbEnable(bool state = true);
|
||||||
|
|
||||||
void cbDisable();
|
void cbDisable();
|
||||||
|
|
||||||
bool onGetCoil(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
bool onGetCoil(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool onSetCoil(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
bool onSetCoil(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool onGetHreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
bool onGetHreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool onSetHreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
bool onSetHreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool onGetIsts(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
bool onGetIsts(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool onSetIsts(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
bool onSetIsts(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool onGetIreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
bool onGetIreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool onSetIreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
bool onSetIreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool removeOnGetCoil(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
bool removeOnGetCoil(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool removeOnSetCoil(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
bool removeOnSetCoil(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool removeOnGetHreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
bool removeOnGetHreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool removeOnSetHreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
bool removeOnSetHreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool removeOnGetIsts(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
bool removeOnGetIsts(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool removeOnSetIsts(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
bool removeOnSetIsts(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool removeOnGetIreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
bool removeOnGetIreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool removeOnSetIreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
bool removeOnSetIreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void readBits(TAddress startreg, uint16_t numregs, FunctionCode fn);
|
void readBits(TAddress startreg, uint16_t numregs, FunctionCode fn);
|
||||||
|
|
||||||
void readWords(TAddress startreg, uint16_t numregs, FunctionCode fn);
|
void readWords(TAddress startreg, uint16_t numregs, FunctionCode fn);
|
||||||
|
|
||||||
void setMultipleBits(uint8_t* frame, TAddress startreg, uint16_t numoutputs);
|
void setMultipleBits(const uint8_t *frame, TAddress startreg, uint16_t numoutputs);
|
||||||
void setMultipleWords(uint16_t* frame, TAddress startreg, uint16_t numoutputs);
|
|
||||||
|
|
||||||
void getMultipleBits(uint8_t* frame, TAddress startreg, uint16_t numregs);
|
void setMultipleWords(const uint16_t *frame, TAddress startreg, uint16_t numoutputs);
|
||||||
void getMultipleWords(uint16_t* frame, TAddress startreg, uint16_t numregs);
|
|
||||||
|
|
||||||
void bitsToBool(bool* dst, uint8_t* src, uint16_t numregs);
|
void getMultipleBits(uint8_t *frame, TAddress startreg, uint16_t numregs);
|
||||||
void boolToBits(uint8_t* dst, bool* src, uint16_t numregs);
|
|
||||||
|
void getMultipleWords(uint16_t *frame, TAddress startreg, uint16_t numregs);
|
||||||
|
|
||||||
|
static void bitsToBool(bool *dst, const uint8_t *src, uint16_t numregs);
|
||||||
|
|
||||||
|
static void boolToBits(uint8_t *dst, const bool *src, uint16_t numregs);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//Reply Types
|
//Reply Types
|
||||||
@@ -221,24 +263,31 @@ protected:
|
|||||||
std::vector<TRegister> _regs;
|
std::vector<TRegister> _regs;
|
||||||
std::vector<TCallback> _callbacks;
|
std::vector<TCallback> _callbacks;
|
||||||
#endif
|
#endif
|
||||||
uint8_t* _frame = nullptr;
|
uint8_t *_frame = nullptr;
|
||||||
uint16_t _len = 0;
|
uint16_t _len = 0;
|
||||||
uint8_t _reply = 0;
|
uint8_t _reply = 0;
|
||||||
bool cbEnabled = true;
|
bool cbEnabled = true;
|
||||||
uint16_t mbCallback(TRegister* reg, uint16_t val, TCallback::CallbackType t);
|
|
||||||
TRegister* searchRegister(TAddress addr);
|
uint16_t mbCallback(TRegister *reg, uint16_t val, TCallback::CallbackType t);
|
||||||
|
|
||||||
|
TRegister *searchRegister(TAddress addr);
|
||||||
|
|
||||||
void exceptionResponse(FunctionCode fn, ResultCode excode); // Fills _frame with response
|
void exceptionResponse(FunctionCode fn, ResultCode excode); // Fills _frame with response
|
||||||
void successResponce(TAddress startreg, uint16_t numoutputs, FunctionCode fn); // Fills frame with response
|
void successResponce(TAddress startreg, uint16_t numoutputs, FunctionCode fn); // Fills frame with response
|
||||||
void slavePDU(uint8_t* frame); //For Slave
|
void slavePDU(uint8_t *frame); //For Slave
|
||||||
void masterPDU(uint8_t* frame, uint8_t* sourceFrame, TAddress startreg, uint16_t* output = nullptr); //For Master
|
void
|
||||||
|
masterPDU(uint8_t *frame, const uint8_t *sourceFrame, TAddress startreg, uint16_t *output = nullptr); //For Master
|
||||||
// frame - data received form slave
|
// frame - data received form slave
|
||||||
// sourceFrame - data have sent fo slave
|
// sourceFrame - data have sent fo slave
|
||||||
// startreg - local register to start put data to
|
// startreg - local register to start put data to
|
||||||
// output - if not null put data to the buffer insted local registers. output assumed to by array of uint16_t or boolean
|
// output - if not null put data to the buffer insted local registers. output assumed to by array of uint16_t or boolean
|
||||||
|
|
||||||
bool readSlave(uint16_t address, uint16_t numregs, FunctionCode fn);
|
bool readSlave(uint16_t address, uint16_t numregs, FunctionCode fn);
|
||||||
bool writeSlaveBits(TAddress startreg, uint16_t to, uint16_t numregs, FunctionCode fn, bool* data = nullptr);
|
|
||||||
bool writeSlaveWords(TAddress startreg, uint16_t to, uint16_t numregs, FunctionCode fn, uint16_t* data = nullptr);
|
bool writeSlaveBits(TAddress startreg, uint16_t to, uint16_t numregs, FunctionCode fn, bool *data = nullptr);
|
||||||
|
|
||||||
|
bool
|
||||||
|
writeSlaveWords(TAddress startreg, uint16_t to, uint16_t numregs, FunctionCode fn, const uint16_t *data = nullptr);
|
||||||
// startreg - local register to get data from
|
// startreg - local register to get data from
|
||||||
// to - slave register to write data to
|
// to - slave register to write data to
|
||||||
// numregs - number of registers
|
// numregs - number of registers
|
||||||
@@ -246,16 +295,23 @@ protected:
|
|||||||
// data - if null use local registers. Otherwise use data from array to erite to slave
|
// data - if null use local registers. Otherwise use data from array to erite to slave
|
||||||
|
|
||||||
bool addReg(TAddress address, uint16_t value = 0, uint16_t numregs = 1);
|
bool addReg(TAddress address, uint16_t value = 0, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool Reg(TAddress address, uint16_t value);
|
bool Reg(TAddress address, uint16_t value);
|
||||||
|
|
||||||
uint16_t Reg(TAddress address);
|
uint16_t Reg(TAddress address);
|
||||||
|
|
||||||
bool removeReg(TAddress address, uint16_t numregs = 1);
|
bool removeReg(TAddress address, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool onGet(TAddress address, cbModbus cb = nullptr, uint16_t numregs = 1);
|
bool onGet(TAddress address, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool onSet(TAddress address, cbModbus cb = nullptr, uint16_t numregs = 1);
|
bool onSet(TAddress address, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool removeOnSet(TAddress address, cbModbus cb = nullptr, uint16_t numregs = 1);
|
bool removeOnSet(TAddress address, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||||||
|
|
||||||
bool removeOnGet(TAddress address, cbModbus cb = nullptr, uint16_t numregs = 1);
|
bool removeOnGet(TAddress address, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||||||
|
|
||||||
virtual uint32_t eventSource() { return 0; }
|
virtual uint32_t eventSource() { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef bool (*cbTransaction)(Modbus::ResultCode event, uint16_t transactionId, void* data); // Callback skeleton for requests
|
typedef bool (*cbTransaction)(Modbus::ResultCode event, uint16_t transactionId,
|
||||||
|
void *data); // Callback skeleton for requests
|
||||||
|
|||||||
153
ModbusRTU.cpp
153
ModbusRTU.cpp
@@ -11,28 +11,44 @@
|
|||||||
|
|
||||||
// Table of CRC values
|
// Table of CRC values
|
||||||
static const uint16_t _auchCRC[] = {
|
static const uint16_t _auchCRC[] = {
|
||||||
0x0000, 0xC1C0, 0x81C1, 0x4001, 0x01C3, 0xC003, 0x8002, 0x41C2, 0x01C6, 0xC006, 0x8007, 0x41C7, 0x0005, 0xC1C5, 0x81C4,
|
0x0000, 0xC1C0, 0x81C1, 0x4001, 0x01C3, 0xC003, 0x8002, 0x41C2, 0x01C6, 0xC006, 0x8007, 0x41C7, 0x0005, 0xC1C5,
|
||||||
0x4004, 0x01CC, 0xC00C, 0x800D, 0x41CD, 0x000F, 0xC1CF, 0x81CE, 0x400E, 0x000A, 0xC1CA, 0x81CB, 0x400B, 0x01C9, 0xC009,
|
0x81C4,
|
||||||
0x8008, 0x41C8, 0x01D8, 0xC018, 0x8019, 0x41D9, 0x001B, 0xC1DB, 0x81DA, 0x401A, 0x001E, 0xC1DE, 0x81DF, 0x401F, 0x01DD,
|
0x4004, 0x01CC, 0xC00C, 0x800D, 0x41CD, 0x000F, 0xC1CF, 0x81CE, 0x400E, 0x000A, 0xC1CA, 0x81CB, 0x400B, 0x01C9,
|
||||||
0xC01D, 0x801C, 0x41DC, 0x0014, 0xC1D4, 0x81D5, 0x4015, 0x01D7, 0xC017, 0x8016, 0x41D6, 0x01D2, 0xC012, 0x8013, 0x41D3,
|
0xC009,
|
||||||
0x0011, 0xC1D1, 0x81D0, 0x4010, 0x01F0, 0xC030, 0x8031, 0x41F1, 0x0033, 0xC1F3, 0x81F2, 0x4032, 0x0036, 0xC1F6, 0x81F7,
|
0x8008, 0x41C8, 0x01D8, 0xC018, 0x8019, 0x41D9, 0x001B, 0xC1DB, 0x81DA, 0x401A, 0x001E, 0xC1DE, 0x81DF, 0x401F,
|
||||||
0x4037, 0x01F5, 0xC035, 0x8034, 0x41F4, 0x003C, 0xC1FC, 0x81FD, 0x403D, 0x01FF, 0xC03F, 0x803E, 0x41FE, 0x01FA, 0xC03A,
|
0x01DD,
|
||||||
0x803B, 0x41FB, 0x0039, 0xC1F9, 0x81F8, 0x4038, 0x0028, 0xC1E8, 0x81E9, 0x4029, 0x01EB, 0xC02B, 0x802A, 0x41EA, 0x01EE,
|
0xC01D, 0x801C, 0x41DC, 0x0014, 0xC1D4, 0x81D5, 0x4015, 0x01D7, 0xC017, 0x8016, 0x41D6, 0x01D2, 0xC012, 0x8013,
|
||||||
0xC02E, 0x802F, 0x41EF, 0x002D, 0xC1ED, 0x81EC, 0x402C, 0x01E4, 0xC024, 0x8025, 0x41E5, 0x0027, 0xC1E7, 0x81E6, 0x4026,
|
0x41D3,
|
||||||
0x0022, 0xC1E2, 0x81E3, 0x4023, 0x01E1, 0xC021, 0x8020, 0x41E0, 0x01A0, 0xC060, 0x8061, 0x41A1, 0x0063, 0xC1A3, 0x81A2,
|
0x0011, 0xC1D1, 0x81D0, 0x4010, 0x01F0, 0xC030, 0x8031, 0x41F1, 0x0033, 0xC1F3, 0x81F2, 0x4032, 0x0036, 0xC1F6,
|
||||||
0x4062, 0x0066, 0xC1A6, 0x81A7, 0x4067, 0x01A5, 0xC065, 0x8064, 0x41A4, 0x006C, 0xC1AC, 0x81AD, 0x406D, 0x01AF, 0xC06F,
|
0x81F7,
|
||||||
0x806E, 0x41AE, 0x01AA, 0xC06A, 0x806B, 0x41AB, 0x0069, 0xC1A9, 0x81A8, 0x4068, 0x0078, 0xC1B8, 0x81B9, 0x4079, 0x01BB,
|
0x4037, 0x01F5, 0xC035, 0x8034, 0x41F4, 0x003C, 0xC1FC, 0x81FD, 0x403D, 0x01FF, 0xC03F, 0x803E, 0x41FE, 0x01FA,
|
||||||
0xC07B, 0x807A, 0x41BA, 0x01BE, 0xC07E, 0x807F, 0x41BF, 0x007D, 0xC1BD, 0x81BC, 0x407C, 0x01B4, 0xC074, 0x8075, 0x41B5,
|
0xC03A,
|
||||||
0x0077, 0xC1B7, 0x81B6, 0x4076, 0x0072, 0xC1B2, 0x81B3, 0x4073, 0x01B1, 0xC071, 0x8070, 0x41B0, 0x0050, 0xC190, 0x8191,
|
0x803B, 0x41FB, 0x0039, 0xC1F9, 0x81F8, 0x4038, 0x0028, 0xC1E8, 0x81E9, 0x4029, 0x01EB, 0xC02B, 0x802A, 0x41EA,
|
||||||
0x4051, 0x0193, 0xC053, 0x8052, 0x4192, 0x0196, 0xC056, 0x8057, 0x4197, 0x0055, 0xC195, 0x8194, 0x4054, 0x019C, 0xC05C,
|
0x01EE,
|
||||||
0x805D, 0x419D, 0x005F, 0xC19F, 0x819E, 0x405E, 0x005A, 0xC19A, 0x819B, 0x405B, 0x0199, 0xC059, 0x8058, 0x4198, 0x0188,
|
0xC02E, 0x802F, 0x41EF, 0x002D, 0xC1ED, 0x81EC, 0x402C, 0x01E4, 0xC024, 0x8025, 0x41E5, 0x0027, 0xC1E7, 0x81E6,
|
||||||
0xC048, 0x8049, 0x4189, 0x004B, 0xC18B, 0x818A, 0x404A, 0x004E, 0xC18E, 0x818F, 0x404F, 0x018D, 0xC04D, 0x804C, 0x418C,
|
0x4026,
|
||||||
0x0044, 0xC184, 0x8185, 0x4045, 0x0187, 0xC047, 0x8046, 0x4186, 0x0182, 0xC042, 0x8043, 0x4183, 0x0041, 0xC181, 0x8180,
|
0x0022, 0xC1E2, 0x81E3, 0x4023, 0x01E1, 0xC021, 0x8020, 0x41E0, 0x01A0, 0xC060, 0x8061, 0x41A1, 0x0063, 0xC1A3,
|
||||||
|
0x81A2,
|
||||||
|
0x4062, 0x0066, 0xC1A6, 0x81A7, 0x4067, 0x01A5, 0xC065, 0x8064, 0x41A4, 0x006C, 0xC1AC, 0x81AD, 0x406D, 0x01AF,
|
||||||
|
0xC06F,
|
||||||
|
0x806E, 0x41AE, 0x01AA, 0xC06A, 0x806B, 0x41AB, 0x0069, 0xC1A9, 0x81A8, 0x4068, 0x0078, 0xC1B8, 0x81B9, 0x4079,
|
||||||
|
0x01BB,
|
||||||
|
0xC07B, 0x807A, 0x41BA, 0x01BE, 0xC07E, 0x807F, 0x41BF, 0x007D, 0xC1BD, 0x81BC, 0x407C, 0x01B4, 0xC074, 0x8075,
|
||||||
|
0x41B5,
|
||||||
|
0x0077, 0xC1B7, 0x81B6, 0x4076, 0x0072, 0xC1B2, 0x81B3, 0x4073, 0x01B1, 0xC071, 0x8070, 0x41B0, 0x0050, 0xC190,
|
||||||
|
0x8191,
|
||||||
|
0x4051, 0x0193, 0xC053, 0x8052, 0x4192, 0x0196, 0xC056, 0x8057, 0x4197, 0x0055, 0xC195, 0x8194, 0x4054, 0x019C,
|
||||||
|
0xC05C,
|
||||||
|
0x805D, 0x419D, 0x005F, 0xC19F, 0x819E, 0x405E, 0x005A, 0xC19A, 0x819B, 0x405B, 0x0199, 0xC059, 0x8058, 0x4198,
|
||||||
|
0x0188,
|
||||||
|
0xC048, 0x8049, 0x4189, 0x004B, 0xC18B, 0x818A, 0x404A, 0x004E, 0xC18E, 0x818F, 0x404F, 0x018D, 0xC04D, 0x804C,
|
||||||
|
0x418C,
|
||||||
|
0x0044, 0xC184, 0x8185, 0x4045, 0x0187, 0xC047, 0x8046, 0x4186, 0x0182, 0xC042, 0x8043, 0x4183, 0x0041, 0xC181,
|
||||||
|
0x8180,
|
||||||
0x4040, 0x0000
|
0x4040, 0x0000
|
||||||
};
|
};
|
||||||
|
|
||||||
uint16_t ModbusRTU::crc16(uint8_t address, uint8_t* frame, uint8_t pduLen)
|
uint16_t ModbusRTU::crc16(uint8_t address, uint8_t *frame, uint8_t pduLen) {
|
||||||
{
|
|
||||||
uint8_t i = 0xFF ^ address;
|
uint8_t i = 0xFF ^ address;
|
||||||
uint16_t val = pgm_read_word(_auchCRC + i);
|
uint16_t val = pgm_read_word(_auchCRC + i);
|
||||||
uint8_t CRCHi = 0xFF ^ highByte(val); // Hi
|
uint8_t CRCHi = 0xFF ^ highByte(val); // Hi
|
||||||
@@ -46,8 +62,7 @@ uint16_t ModbusRTU::crc16(uint8_t address, uint8_t* frame, uint8_t pduLen)
|
|||||||
return (CRCHi << 8) | CRCLo;
|
return (CRCHi << 8) | CRCLo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModbusRTU::setBaudrate(uint32_t baud)
|
void ModbusRTU::setBaudrate(uint32_t baud) {
|
||||||
{
|
|
||||||
if (baud > 19200) {
|
if (baud > 19200) {
|
||||||
_t = 50ms;
|
_t = 50ms;
|
||||||
} else {
|
} else {
|
||||||
@@ -56,16 +71,14 @@ void ModbusRTU::setBaudrate(uint32_t baud)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModbusRTU::begin(UnbufferedSerial* port)
|
bool ModbusRTU::begin(UnbufferedSerial *port) {
|
||||||
{
|
|
||||||
_port = port;
|
_port = port;
|
||||||
_t = 50ms;
|
_t = 50ms;
|
||||||
_port->attach(callback(this, &ModbusRTU::SerialRXHandler), SerialBase::RxIrq);
|
_port->attach(callback(this, &ModbusRTU::SerialRXHandler), SerialBase::RxIrq);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModbusRTU::begin(UnbufferedSerial* port, PinName txPin)
|
bool ModbusRTU::begin(UnbufferedSerial *port, PinName txPin) {
|
||||||
{
|
|
||||||
uint32_t baud = 0;
|
uint32_t baud = 0;
|
||||||
#if defined(ESP32) || defined(ESP8266)
|
#if defined(ESP32) || defined(ESP8266)
|
||||||
// baudRate() only available with ESP32+ESP8266
|
// baudRate() only available with ESP32+ESP8266
|
||||||
@@ -85,17 +98,15 @@ bool ModbusRTU::begin(UnbufferedSerial* port, PinName txPin)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModbusRTU::SerialRXHandler()
|
void ModbusRTU::SerialRXHandler() {
|
||||||
{
|
|
||||||
char c;
|
char c;
|
||||||
if (_port->readable()) {
|
if (_port->readable()) {
|
||||||
_port->read(&c, 1);
|
_port->read(&c, 1);
|
||||||
RX_RingBuff.push((uint8_t)(c & (uint8_t)0xFFU));
|
RX_RingBuff.push((uint8_t) (c & (uint8_t) 0xFFU));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModbusRTU::SerialTXHandler()
|
void ModbusRTU::SerialTXHandler() {
|
||||||
{
|
|
||||||
//Здесь проверка на TC а не на RX!!!!
|
//Здесь проверка на TC а не на RX!!!!
|
||||||
//Изменено в serial_api.c
|
//Изменено в serial_api.c
|
||||||
if (_port->writeable()) {
|
if (_port->writeable()) {
|
||||||
@@ -104,17 +115,15 @@ void ModbusRTU::SerialTXHandler()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t ModbusRTU::Read(void)
|
uint8_t ModbusRTU::Read() {
|
||||||
{
|
|
||||||
uint8_t cur = 0xff;
|
uint8_t cur = 0xff;
|
||||||
if (!RX_RingBuff.empty()) {
|
if (!RX_RingBuff.empty()) {
|
||||||
RX_RingBuff.pop((char&)cur);
|
RX_RingBuff.pop((char &) cur);
|
||||||
}
|
}
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t ModbusRTU::isDataAvailable(void)
|
uint8_t ModbusRTU::isDataAvailable() {
|
||||||
{
|
|
||||||
if (RX_RingBuff.full()) {
|
if (RX_RingBuff.full()) {
|
||||||
RX_RingBuff.reset();
|
RX_RingBuff.reset();
|
||||||
}
|
}
|
||||||
@@ -133,8 +142,7 @@ bool ModbusRTU::begin(SoftwareSerial* port, int16_t txPin)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool ModbusRTU::rawSend(uint8_t slaveId, uint8_t* frame, uint8_t len)
|
bool ModbusRTU::rawSend(uint8_t slaveId, uint8_t *frame, uint8_t len) {
|
||||||
{
|
|
||||||
uint16_t newCrc = crc16(slaveId, frame, len);
|
uint16_t newCrc = crc16(slaveId, frame, len);
|
||||||
char crc[2];
|
char crc[2];
|
||||||
crc[0] = newCrc >> 8;
|
crc[0] = newCrc >> 8;
|
||||||
@@ -153,8 +161,7 @@ bool ModbusRTU::rawSend(uint8_t slaveId, uint8_t* frame, uint8_t len)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModbusRTU::send(uint8_t slaveId, TAddress startreg, cbTransaction cb, void* data, bool waitResponse)
|
bool ModbusRTU::send(uint8_t slaveId, TAddress startreg, cbTransaction cb, void *data, bool waitResponse) {
|
||||||
{
|
|
||||||
if (_slaveId)
|
if (_slaveId)
|
||||||
return false; // Break if waiting for previous request result
|
return false; // Break if waiting for previous request result
|
||||||
rawSend(slaveId, _frame, _len);
|
rawSend(slaveId, _frame, _len);
|
||||||
@@ -171,8 +178,7 @@ bool ModbusRTU::send(uint8_t slaveId, TAddress startreg, cbTransaction cb, void*
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModbusRTU::task()
|
void ModbusRTU::task() {
|
||||||
{
|
|
||||||
|
|
||||||
if (RX_RingBuff.size() > _len) {
|
if (RX_RingBuff.size() > _len) {
|
||||||
_len = RX_RingBuff.size();
|
_len = RX_RingBuff.size();
|
||||||
@@ -201,13 +207,13 @@ void ModbusRTU::task()
|
|||||||
}
|
}
|
||||||
|
|
||||||
free(_frame); //Just in case
|
free(_frame); //Just in case
|
||||||
_frame = (uint8_t*)malloc(_len);
|
_frame = (uint8_t *) malloc(_len);
|
||||||
if (!_frame) { // Fail to allocate buffer
|
if (!_frame) { // Fail to allocate buffer
|
||||||
RX_RingBuff.reset(); // Skip packet if can't allocate buffer
|
RX_RingBuff.reset(); // Skip packet if can't allocate buffer
|
||||||
_len = 0;
|
_len = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (uint8_t i = 0; i < _len; i++) {
|
for (uint16_t i = 0; i < _len; i++) {
|
||||||
_frame[i] = Read(); // read data + crc
|
_frame[i] = Read(); // read data + crc
|
||||||
#if defined(MODBUSRTU_DEBUG)
|
#if defined(MODBUSRTU_DEBUG)
|
||||||
Serial.printf("%02X ", _frame[i]);
|
Serial.printf("%02X ", _frame[i]);
|
||||||
@@ -229,9 +235,9 @@ void ModbusRTU::task()
|
|||||||
_reply = EX_SUCCESS;
|
_reply = EX_SUCCESS;
|
||||||
if ((_frame[0] & 0x7F) == _sentFrame[0]) { // Check if function code the same as requested
|
if ((_frame[0] & 0x7F) == _sentFrame[0]) { // Check if function code the same as requested
|
||||||
// Procass incoming frame as master
|
// Procass incoming frame as master
|
||||||
masterPDU(_frame, _sentFrame, _sentReg, (uint16_t*)_data);
|
masterPDU(_frame, _sentFrame, _sentReg, (uint16_t *) _data);
|
||||||
if (_cb) {
|
if (_cb) {
|
||||||
_cb((ResultCode)_reply, 0, nullptr);
|
_cb((ResultCode) _reply, 0, nullptr);
|
||||||
}
|
}
|
||||||
free(_sentFrame);
|
free(_sentFrame);
|
||||||
_sentFrame = nullptr;
|
_sentFrame = nullptr;
|
||||||
@@ -253,8 +259,7 @@ void ModbusRTU::task()
|
|||||||
_len = 0;
|
_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModbusRTU::cleanup()
|
bool ModbusRTU::cleanup() {
|
||||||
{
|
|
||||||
// Remove timeouted request and forced event
|
// Remove timeouted request and forced event
|
||||||
if (_slaveId && (Kernel::Clock::now() - _timestamp > MODBUSRTU_TIMEOUT)) {
|
if (_slaveId && (Kernel::Clock::now() - _timestamp > MODBUSRTU_TIMEOUT)) {
|
||||||
if (_cb)
|
if (_cb)
|
||||||
@@ -269,68 +274,59 @@ bool ModbusRTU::cleanup()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ModbusRTU::writeHreg(uint8_t slaveId, uint16_t offset, uint16_t value, cbTransaction cb)
|
uint16_t ModbusRTU::writeHreg(uint8_t slaveId, uint16_t offset, uint16_t value, cbTransaction cb) {
|
||||||
{
|
|
||||||
readSlave(offset, value, FC_WRITE_REG);
|
readSlave(offset, value, FC_WRITE_REG);
|
||||||
return send(slaveId, HREG(offset), cb, nullptr, cb);
|
return send(slaveId, HREG(offset), cb, nullptr, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ModbusRTU::writeCoil(uint8_t slaveId, uint16_t offset, bool value, cbTransaction cb)
|
uint16_t ModbusRTU::writeCoil(uint8_t slaveId, uint16_t offset, bool value, cbTransaction cb) {
|
||||||
{
|
|
||||||
readSlave(offset, COIL_VAL(value), FC_WRITE_COIL);
|
readSlave(offset, COIL_VAL(value), FC_WRITE_COIL);
|
||||||
return send(slaveId, COIL(offset), cb, nullptr, cb);
|
return send(slaveId, COIL(offset), cb, nullptr, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ModbusRTU::readCoil(uint8_t slaveId, uint16_t offset, bool* value, uint16_t numregs, cbTransaction cb)
|
uint16_t ModbusRTU::readCoil(uint8_t slaveId, uint16_t offset, bool *value, uint16_t numregs, cbTransaction cb) {
|
||||||
{
|
|
||||||
if (numregs < 0x0001 || numregs > maxRegs << 4)
|
if (numregs < 0x0001 || numregs > maxRegs << 4)
|
||||||
return false;
|
return false;
|
||||||
readSlave(offset, numregs, FC_READ_COILS);
|
readSlave(offset, numregs, FC_READ_COILS);
|
||||||
return send(slaveId, COIL(offset), cb, value);
|
return send(slaveId, COIL(offset), cb, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ModbusRTU::writeCoil(uint8_t slaveId, uint16_t offset, bool* value, uint16_t numregs, cbTransaction cb)
|
uint16_t ModbusRTU::writeCoil(uint8_t slaveId, uint16_t offset, bool *value, uint16_t numregs, cbTransaction cb) {
|
||||||
{
|
|
||||||
if (numregs < 0x0001 || numregs > 0x07D0)
|
if (numregs < 0x0001 || numregs > 0x07D0)
|
||||||
return false;
|
return false;
|
||||||
writeSlaveBits(COIL(offset), offset, numregs, FC_WRITE_COILS, value);
|
writeSlaveBits(COIL(offset), offset, numregs, FC_WRITE_COILS, value);
|
||||||
return send(slaveId, COIL(offset), cb, nullptr, cb);
|
return send(slaveId, COIL(offset), cb, nullptr, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ModbusRTU::writeHreg(uint8_t slaveId, uint16_t offset, uint16_t* value, uint16_t numregs, cbTransaction cb)
|
uint16_t ModbusRTU::writeHreg(uint8_t slaveId, uint16_t offset, uint16_t *value, uint16_t numregs, cbTransaction cb) {
|
||||||
{
|
|
||||||
if (numregs < 0x0001 || numregs > 0x007D)
|
if (numregs < 0x0001 || numregs > 0x007D)
|
||||||
return false;
|
return false;
|
||||||
writeSlaveWords(HREG(offset), offset, numregs, FC_WRITE_REGS, value);
|
writeSlaveWords(HREG(offset), offset, numregs, FC_WRITE_REGS, value);
|
||||||
return send(slaveId, HREG(offset), cb, nullptr, cb);
|
return send(slaveId, HREG(offset), cb, nullptr, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ModbusRTU::readHreg(uint8_t slaveId, uint16_t offset, uint16_t* value, uint16_t numregs, cbTransaction cb)
|
uint16_t ModbusRTU::readHreg(uint8_t slaveId, uint16_t offset, uint16_t *value, uint16_t numregs, cbTransaction cb) {
|
||||||
{
|
|
||||||
if (numregs < 0x0001 || numregs > maxRegs)
|
if (numregs < 0x0001 || numregs > maxRegs)
|
||||||
return false;
|
return false;
|
||||||
readSlave(offset, numregs, FC_READ_REGS);
|
readSlave(offset, numregs, FC_READ_REGS);
|
||||||
return send(slaveId, HREG(offset), cb, value);
|
return send(slaveId, HREG(offset), cb, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ModbusRTU::readIsts(uint8_t slaveId, uint16_t offset, bool* value, uint16_t numregs, cbTransaction cb)
|
uint16_t ModbusRTU::readIsts(uint8_t slaveId, uint16_t offset, bool *value, uint16_t numregs, cbTransaction cb) {
|
||||||
{
|
|
||||||
if (numregs < 0x0001 || numregs > maxRegs << 4)
|
if (numregs < 0x0001 || numregs > maxRegs << 4)
|
||||||
return false;
|
return false;
|
||||||
readSlave(offset, numregs, FC_READ_INPUT_STAT);
|
readSlave(offset, numregs, FC_READ_INPUT_STAT);
|
||||||
return send(slaveId, ISTS(offset), cb, value);
|
return send(slaveId, ISTS(offset), cb, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ModbusRTU::readIreg(uint8_t slaveId, uint16_t offset, uint16_t* value, uint16_t numregs, cbTransaction cb)
|
uint16_t ModbusRTU::readIreg(uint8_t slaveId, uint16_t offset, uint16_t *value, uint16_t numregs, cbTransaction cb) {
|
||||||
{
|
|
||||||
if (numregs < 0x0001 || numregs > maxRegs)
|
if (numregs < 0x0001 || numregs > maxRegs)
|
||||||
return false;
|
return false;
|
||||||
readSlave(offset, numregs, FC_READ_INPUT_REGS);
|
readSlave(offset, numregs, FC_READ_INPUT_REGS);
|
||||||
return send(slaveId, IREG(offset), cb, value);
|
return send(slaveId, IREG(offset), cb, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ModbusRTU::pushCoil(uint8_t slaveId, uint16_t to, uint16_t from, uint16_t numregs, cbTransaction cb)
|
uint16_t ModbusRTU::pushCoil(uint8_t slaveId, uint16_t to, uint16_t from, uint16_t numregs, cbTransaction cb) {
|
||||||
{
|
|
||||||
if (numregs < 0x0001 || numregs > 0x07D0)
|
if (numregs < 0x0001 || numregs > 0x07D0)
|
||||||
return false;
|
return false;
|
||||||
if (!searchRegister(COIL(from)))
|
if (!searchRegister(COIL(from)))
|
||||||
@@ -343,8 +339,7 @@ uint16_t ModbusRTU::pushCoil(uint8_t slaveId, uint16_t to, uint16_t from, uint16
|
|||||||
return send(slaveId, COIL(from), cb);
|
return send(slaveId, COIL(from), cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ModbusRTU::pullCoil(uint8_t slaveId, uint16_t from, uint16_t to, uint16_t numregs, cbTransaction cb)
|
uint16_t ModbusRTU::pullCoil(uint8_t slaveId, uint16_t from, uint16_t to, uint16_t numregs, cbTransaction cb) {
|
||||||
{
|
|
||||||
if (numregs < 0x0001 || numregs > maxRegs << 4)
|
if (numregs < 0x0001 || numregs > maxRegs << 4)
|
||||||
return false;
|
return false;
|
||||||
#ifdef MODBUSRTU_ADD_REG
|
#ifdef MODBUSRTU_ADD_REG
|
||||||
@@ -354,8 +349,7 @@ uint16_t ModbusRTU::pullCoil(uint8_t slaveId, uint16_t from, uint16_t to, uint16
|
|||||||
return send(slaveId, COIL(to), cb);
|
return send(slaveId, COIL(to), cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ModbusRTU::pullIsts(uint8_t slaveId, uint16_t from, uint16_t to, uint16_t numregs, cbTransaction cb)
|
uint16_t ModbusRTU::pullIsts(uint8_t slaveId, uint16_t from, uint16_t to, uint16_t numregs, cbTransaction cb) {
|
||||||
{
|
|
||||||
if (numregs < 0x0001 || numregs > maxRegs << 4)
|
if (numregs < 0x0001 || numregs > maxRegs << 4)
|
||||||
return false;
|
return false;
|
||||||
#ifdef MODBUSRTU_ADD_REG
|
#ifdef MODBUSRTU_ADD_REG
|
||||||
@@ -365,8 +359,7 @@ uint16_t ModbusRTU::pullIsts(uint8_t slaveId, uint16_t from, uint16_t to, uint16
|
|||||||
return send(slaveId, ISTS(to), cb);
|
return send(slaveId, ISTS(to), cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ModbusRTU::pushHreg(uint8_t slaveId, uint16_t to, uint16_t from, uint16_t numregs, cbTransaction cb)
|
uint16_t ModbusRTU::pushHreg(uint8_t slaveId, uint16_t to, uint16_t from, uint16_t numregs, cbTransaction cb) {
|
||||||
{
|
|
||||||
if (numregs < 0x0001 || numregs > 0x007D)
|
if (numregs < 0x0001 || numregs > 0x007D)
|
||||||
return false;
|
return false;
|
||||||
if (!searchRegister(HREG(from)))
|
if (!searchRegister(HREG(from)))
|
||||||
@@ -379,8 +372,7 @@ uint16_t ModbusRTU::pushHreg(uint8_t slaveId, uint16_t to, uint16_t from, uint16
|
|||||||
return send(slaveId, HREG(from), cb);
|
return send(slaveId, HREG(from), cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ModbusRTU::pullHreg(uint8_t slaveId, uint16_t from, uint16_t to, uint16_t numregs, cbTransaction cb)
|
uint16_t ModbusRTU::pullHreg(uint8_t slaveId, uint16_t from, uint16_t to, uint16_t numregs, cbTransaction cb) {
|
||||||
{
|
|
||||||
if (numregs < 0x0001 || numregs > maxRegs)
|
if (numregs < 0x0001 || numregs > maxRegs)
|
||||||
return false;
|
return false;
|
||||||
#ifdef MODBUSRTU_ADD_REG
|
#ifdef MODBUSRTU_ADD_REG
|
||||||
@@ -390,8 +382,7 @@ uint16_t ModbusRTU::pullHreg(uint8_t slaveId, uint16_t from, uint16_t to, uint16
|
|||||||
return send(slaveId, HREG(to), cb);
|
return send(slaveId, HREG(to), cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ModbusRTU::pullIreg(uint8_t slaveId, uint16_t from, uint16_t to, uint16_t numregs, cbTransaction cb)
|
uint16_t ModbusRTU::pullIreg(uint8_t slaveId, uint16_t from, uint16_t to, uint16_t numregs, cbTransaction cb) {
|
||||||
{
|
|
||||||
if (numregs < 0x0001 || numregs > maxRegs)
|
if (numregs < 0x0001 || numregs > maxRegs)
|
||||||
return false;
|
return false;
|
||||||
#ifdef MODBUSRTU_ADD_REG
|
#ifdef MODBUSRTU_ADD_REG
|
||||||
@@ -401,8 +392,7 @@ uint16_t ModbusRTU::pullIreg(uint8_t slaveId, uint16_t from, uint16_t to, uint16
|
|||||||
return send(slaveId, IREG(to), cb);
|
return send(slaveId, IREG(to), cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ModbusRTU::pushIregToHreg(uint8_t slaveId, uint16_t to, uint16_t from, uint16_t numregs, cbTransaction cb)
|
uint16_t ModbusRTU::pushIregToHreg(uint8_t slaveId, uint16_t to, uint16_t from, uint16_t numregs, cbTransaction cb) {
|
||||||
{
|
|
||||||
if (numregs < 0x0001 || numregs > 0x007D)
|
if (numregs < 0x0001 || numregs > 0x007D)
|
||||||
return false;
|
return false;
|
||||||
if (!searchRegister(IREG(from)))
|
if (!searchRegister(IREG(from)))
|
||||||
@@ -415,8 +405,7 @@ uint16_t ModbusRTU::pushIregToHreg(uint8_t slaveId, uint16_t to, uint16_t from,
|
|||||||
return send(slaveId, IREG(from), cb);
|
return send(slaveId, IREG(from), cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ModbusRTU::pushIstsToCoil(uint8_t slaveId, uint16_t to, uint16_t from, uint16_t numregs, cbTransaction cb)
|
uint16_t ModbusRTU::pushIstsToCoil(uint8_t slaveId, uint16_t to, uint16_t from, uint16_t numregs, cbTransaction cb) {
|
||||||
{
|
|
||||||
if (numregs < 0x0001 || numregs > maxRegs << 4)
|
if (numregs < 0x0001 || numregs > maxRegs << 4)
|
||||||
return false;
|
return false;
|
||||||
if (!searchRegister(ISTS(from)))
|
if (!searchRegister(ISTS(from)))
|
||||||
@@ -429,8 +418,7 @@ uint16_t ModbusRTU::pushIstsToCoil(uint8_t slaveId, uint16_t to, uint16_t from,
|
|||||||
return send(slaveId, ISTS(from), cb);
|
return send(slaveId, ISTS(from), cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ModbusRTU::pullHregToIreg(uint8_t slaveId, uint16_t from, uint16_t to, uint16_t numregs, cbTransaction cb)
|
uint16_t ModbusRTU::pullHregToIreg(uint8_t slaveId, uint16_t from, uint16_t to, uint16_t numregs, cbTransaction cb) {
|
||||||
{
|
|
||||||
if (numregs < 0x0001 || numregs > maxRegs)
|
if (numregs < 0x0001 || numregs > maxRegs)
|
||||||
return false;
|
return false;
|
||||||
#ifdef MODBUSRTU_ADD_REG
|
#ifdef MODBUSRTU_ADD_REG
|
||||||
@@ -440,8 +428,7 @@ uint16_t ModbusRTU::pullHregToIreg(uint8_t slaveId, uint16_t from, uint16_t to,
|
|||||||
return send(slaveId, IREG(to), cb);
|
return send(slaveId, IREG(to), cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ModbusRTU::pullCoilToIsts(uint8_t slaveId, uint16_t from, uint16_t to, uint16_t numregs, cbTransaction cb)
|
uint16_t ModbusRTU::pullCoilToIsts(uint8_t slaveId, uint16_t from, uint16_t to, uint16_t numregs, cbTransaction cb) {
|
||||||
{
|
|
||||||
if (numregs < 0x0001 || numregs > maxRegs << 4)
|
if (numregs < 0x0001 || numregs > maxRegs << 4)
|
||||||
return false;
|
return false;
|
||||||
#ifdef MODBUSRTU_ADD_REG
|
#ifdef MODBUSRTU_ADD_REG
|
||||||
|
|||||||
84
ModbusRTU.h
84
ModbusRTU.h
@@ -5,6 +5,7 @@
|
|||||||
This code is licensed under the BSD New License. See LICENSE.txt for more info.
|
This code is licensed under the BSD New License. See LICENSE.txt for more info.
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "mbed.h"
|
#include "mbed.h"
|
||||||
#include <Modbus.h>
|
#include <Modbus.h>
|
||||||
|
|
||||||
@@ -24,12 +25,17 @@
|
|||||||
class ModbusRTU : public Modbus {
|
class ModbusRTU : public Modbus {
|
||||||
protected:
|
protected:
|
||||||
CircularBuffer<char, 200> RX_RingBuff;
|
CircularBuffer<char, 200> RX_RingBuff;
|
||||||
UnbufferedSerial* _port;
|
UnbufferedSerial *_port;
|
||||||
DigitalOut* _txPin;
|
DigitalOut *_txPin;
|
||||||
|
|
||||||
void SerialRXHandler();
|
void SerialRXHandler();
|
||||||
|
|
||||||
void SerialTXHandler();
|
void SerialTXHandler();
|
||||||
uint8_t isDataAvailable(void);
|
|
||||||
uint8_t Read(void);
|
uint8_t isDataAvailable();
|
||||||
|
|
||||||
|
uint8_t Read();
|
||||||
|
|
||||||
// unsigned int
|
// unsigned int
|
||||||
Kernel::Clock::duration MODBUSRTU_TIMEOUT = 1s;
|
Kernel::Clock::duration MODBUSRTU_TIMEOUT = 1s;
|
||||||
Kernel::Clock::duration _t; // inter-frame delay in mS
|
Kernel::Clock::duration _t; // inter-frame delay in mS
|
||||||
@@ -38,53 +44,87 @@ protected:
|
|||||||
uint8_t _slaveId;
|
uint8_t _slaveId;
|
||||||
Kernel::Clock::time_point _timestamp;
|
Kernel::Clock::time_point _timestamp;
|
||||||
cbTransaction _cb = nullptr;
|
cbTransaction _cb = nullptr;
|
||||||
void* _data = nullptr;
|
void *_data = nullptr;
|
||||||
uint8_t* _sentFrame = nullptr;
|
uint8_t *_sentFrame = nullptr;
|
||||||
TAddress _sentReg = COIL(0);
|
TAddress _sentReg = COIL(0);
|
||||||
uint16_t maxRegs = 0x007D;
|
uint16_t maxRegs = 0x007D;
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
|
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
|
||||||
#endif
|
#endif
|
||||||
bool send(uint8_t slaveId, TAddress startreg, cbTransaction cb, void* data = nullptr, bool waitResponse = true);
|
|
||||||
|
bool send(uint8_t slaveId, TAddress startreg, cbTransaction cb, void *data = nullptr, bool waitResponse = true);
|
||||||
|
|
||||||
// Prepare and send ModbusRTU frame. _frame buffer and _len should be filled with Modbus data
|
// Prepare and send ModbusRTU frame. _frame buffer and _len should be filled with Modbus data
|
||||||
// slaveId - slave id
|
// slaveId - slave id
|
||||||
// startreg - first local register to save returned data to (miningless for write to slave operations)
|
// startreg - first local register to save returned data to (miningless for write to slave operations)
|
||||||
// cb - transaction callback function
|
// cb - transaction callback function
|
||||||
// data - if not null use buffer to save returned data instead of local registers
|
// data - if not null use buffer to save returned data instead of local registers
|
||||||
bool rawSend(uint8_t slaveId, uint8_t* frame, uint8_t len);
|
bool rawSend(uint8_t slaveId, uint8_t *frame, uint8_t len);
|
||||||
|
|
||||||
bool cleanup(); // Free clients if not connected and remove timedout transactions and transaction with forced events
|
bool cleanup(); // Free clients if not connected and remove timedout transactions and transaction with forced events
|
||||||
uint16_t crc16(uint8_t address, uint8_t* frame, uint8_t pdulen);
|
static uint16_t crc16(uint8_t address, uint8_t *frame, uint8_t pdulen);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void setBaudrate(uint32_t baud = -1);
|
void setBaudrate(uint32_t baud = -1);
|
||||||
|
|
||||||
#if defined(ESP8266)
|
#if defined(ESP8266)
|
||||||
bool begin(BufferedSerial* port, int16_t txPin = -1);
|
bool begin(BufferedSerial* port, int16_t txPin = -1);
|
||||||
#endif
|
#endif
|
||||||
bool begin(UnbufferedSerial* port, PinName txPin = NC);
|
|
||||||
bool begin(UnbufferedSerial* port);
|
bool begin(UnbufferedSerial *port, PinName txPin = NC);
|
||||||
|
|
||||||
|
bool begin(UnbufferedSerial *port);
|
||||||
|
|
||||||
void task();
|
void task();
|
||||||
|
|
||||||
void master() { isMaster = true; };
|
void master() { isMaster = true; };
|
||||||
|
|
||||||
void slave(uint8_t slaveId) { _slaveId = slaveId; };
|
void slave(uint8_t slaveId) { _slaveId = slaveId; };
|
||||||
uint8_t slave() { return _slaveId; }
|
|
||||||
|
uint8_t slave() const { return _slaveId; }
|
||||||
|
|
||||||
uint32_t eventSource() override { return _slaveId; }
|
uint32_t eventSource() override { return _slaveId; }
|
||||||
|
|
||||||
uint16_t writeHreg(uint8_t slaveId, uint16_t offset, uint16_t value, cbTransaction cb = nullptr);
|
uint16_t writeHreg(uint8_t slaveId, uint16_t offset, uint16_t value, cbTransaction cb = nullptr);
|
||||||
|
|
||||||
uint16_t writeCoil(uint8_t slaveId, uint16_t offset, bool value, cbTransaction cb = nullptr);
|
uint16_t writeCoil(uint8_t slaveId, uint16_t offset, bool value, cbTransaction cb = nullptr);
|
||||||
uint16_t readCoil(uint8_t slaveId, uint16_t offset, bool* value, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
|
||||||
uint16_t writeCoil(uint8_t slaveId, uint16_t offset, bool* value, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
uint16_t readCoil(uint8_t slaveId, uint16_t offset, bool *value, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
||||||
uint16_t writeHreg(uint8_t slaveId, uint16_t offset, uint16_t* value, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
|
||||||
uint16_t readIsts(uint8_t slaveId, uint16_t offset, bool* value, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
uint16_t writeCoil(uint8_t slaveId, uint16_t offset, bool *value, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
||||||
uint16_t readHreg(uint8_t slaveId, uint16_t offset, uint16_t* value, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
|
||||||
uint16_t readIreg(uint8_t slaveId, uint16_t offset, uint16_t* value, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
uint16_t
|
||||||
|
writeHreg(uint8_t slaveId, uint16_t offset, uint16_t *value, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
||||||
|
|
||||||
|
uint16_t readIsts(uint8_t slaveId, uint16_t offset, bool *value, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
||||||
|
|
||||||
|
uint16_t
|
||||||
|
readHreg(uint8_t slaveId, uint16_t offset, uint16_t *value, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
||||||
|
|
||||||
|
uint16_t
|
||||||
|
readIreg(uint8_t slaveId, uint16_t offset, uint16_t *value, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
||||||
|
|
||||||
uint16_t pushCoil(uint8_t slaveId, uint16_t to, uint16_t from, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
uint16_t pushCoil(uint8_t slaveId, uint16_t to, uint16_t from, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
||||||
|
|
||||||
uint16_t pullCoil(uint8_t slaveId, uint16_t from, uint16_t to, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
uint16_t pullCoil(uint8_t slaveId, uint16_t from, uint16_t to, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
||||||
|
|
||||||
uint16_t pullIsts(uint8_t slaveId, uint16_t from, uint16_t to, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
uint16_t pullIsts(uint8_t slaveId, uint16_t from, uint16_t to, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
||||||
|
|
||||||
uint16_t pushHreg(uint8_t slaveId, uint16_t to, uint16_t from, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
uint16_t pushHreg(uint8_t slaveId, uint16_t to, uint16_t from, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
||||||
|
|
||||||
uint16_t pullHreg(uint8_t slaveId, uint16_t from, uint16_t to, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
uint16_t pullHreg(uint8_t slaveId, uint16_t from, uint16_t to, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
||||||
|
|
||||||
uint16_t pullIreg(uint8_t slaveId, uint16_t from, uint16_t to, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
uint16_t pullIreg(uint8_t slaveId, uint16_t from, uint16_t to, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
||||||
|
|
||||||
uint16_t pullHregToIreg(uint8_t slaveId, uint16_t offset, uint16_t startreg, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
uint16_t pullHregToIreg(uint8_t slaveId, uint16_t offset, uint16_t startreg, uint16_t numregs = 1,
|
||||||
uint16_t pullCoilToIsts(uint8_t slaveId, uint16_t offset, uint16_t startreg, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
cbTransaction cb = nullptr);
|
||||||
uint16_t pushIstsToCoil(uint8_t slaveId, uint16_t to, uint16_t from, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
|
||||||
uint16_t pushIregToHreg(uint8_t slaveId, uint16_t to, uint16_t from, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
uint16_t pullCoilToIsts(uint8_t slaveId, uint16_t offset, uint16_t startreg, uint16_t numregs = 1,
|
||||||
|
cbTransaction cb = nullptr);
|
||||||
|
|
||||||
|
uint16_t
|
||||||
|
pushIstsToCoil(uint8_t slaveId, uint16_t to, uint16_t from, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
||||||
|
|
||||||
|
uint16_t
|
||||||
|
pushIregToHreg(uint8_t slaveId, uint16_t to, uint16_t from, uint16_t numregs = 1, cbTransaction cb = nullptr);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user