/********************************************* ** modbus_req_canEstimateLength() ** modbus_rsp_canEstimateLength() ** ** DESC: Given an arriving Modbus message, see if can estimate it's length ** ** INPUT: pBuf = ptr to modbus/RTU message (starting at slave address) ** len = how many bytes are in pBuf ** ** OUTPUT: rtn > 0, then this is the estimated length with CRC16 ** rtn == EXPECT_NOT_YET, then we need to receive more bytes ** rtn == EXPECT_CANNOT, then unsupported function code ** **********************************************/ /* Example psuedo-code to use #define EXPECT_NOT_YET 0xFFFE #define EXPECT_CANNOT 0xFFFF unit16 len = 0; uint16 expected = EXPECT_NOT_YET; uint8 pBuf[256]; while( len < expected) { get_next_byte() - non-blocking or wait for char_timeout handle_timeout() - break from while & check CRC if( expected == EXPECT_NOT_YET) { if( is_request) expected = modbus_req_canEstimateLength( pBuf, len); else expected = modbus_rsp_canEstimateLength( pBuf, len); } } */ // estimate requests uint16 modbus_req_canEstimateLength( uint8 *pBuf, uint16 len) { uint16 expected = EXPECT_NOT_YET; if( len >= 2) { // then we have at least the slave address and function code switch( pBuf[1]) { case 1: // read N coils; func 1 for 0x00000 area case 2: // read N status; func 2 for 1x00000 area case 3: // read N regs; func 3 for 4x00000 area case 4: // read N inputs; func 4 for 3x00000 area case 5: // write 1 coil; func 5 for 0x00000 area case 6: // write 1 reg; func 6 for 4x00000 area // these are: SS FF AA AA LL LL CR CR expected = 8; break; case 15: // write N coil; func 15 for 0x00000 area case 16: // write N regs; func 16 for 4x00000 area if( len >= 7) { // then have byte count // these are: SS FF AA AA LL LL BC ?? CR CR expected = 9 + pBuf[6]; } break; default: // else we have no idea which function this is // you can add any additional function codes yourself expected = EXPECT_CANNOT; break; } } return( expected); } // estimate responses uint16 modbus_rsp_canEstimateLength( uint8 *pBuf, uint16 len) { uint16 expected = EXPECT_NOT_YET; if( len >= 2) { // then we have at least the slave address and function code if( pBuf[1] & 0x80) { // then is expection response // these are: SS FF CD CR CR expected = 5; } else switch( pBuf[1]) { case 1: // read N coils; func 1 for 0x00000 area case 2: // read N status; func 2 for 1x00000 area case 3: // read N regs; func 3 for 4x00000 area case 4: // read N inputs; func 4 for 3x00000 area case 5: // write 1 coil; func 5 for 0x00000 area case 6: // write 1 reg; func 6 for 4x00000 area if( len >= 3) { // then have byte count // these are: SS FF BC ?? CR CR expected = 5 + pBuf[2]; } break; case 15: // write N coil; func 15 for 0x00000 area case 16: // write N regs; func 16 for 4x00000 area // these are: SS FF AA AA LL LL CR CR expected = 8; break; default: // else we have no idea which function this is // you can add any additional function codes yourself expected = EXPECT_CANNOT; break; } } return( expected); }