diff --git a/freemodbus/modbus/functions/mbfuncother.c b/freemodbus/modbus/functions/mbfuncother.c index 91c8d1f..9a1ddd9 100644 --- a/freemodbus/modbus/functions/mbfuncother.c +++ b/freemodbus/modbus/functions/mbfuncother.c @@ -53,11 +53,11 @@ #if MB_FUNC_OTHER_REP_SLAVEID_ENABLED -#define MB_PDU_FUNC_READ_BYTECNT_OFF ( MB_PDU_DATA_OFF + 0 ) -#define MB_PDU_FUNC_READ_VALUES_OFF ( MB_PDU_DATA_OFF + 1 ) +#define MB_PDU_BYTECNT_OFF ( MB_PDU_DATA_OFF + 0 ) +#define MB_PDU_FUNC_DATA_OFF ( MB_PDU_DATA_OFF + 1 ) /* ----------------------- Static variables ---------------------------------*/ -static UCHAR ucMBSlaveID[MB_FUNC_OTHER_REP_SLAVEID_BUF]; +static UCHAR ucMBSlaveID[MB_FUNC_OTHER_REP_SLAVEID_BUF] = {0}; static USHORT usMBSlaveIDLen; /* ----------------------- Start implementation -----------------------------*/ @@ -92,9 +92,9 @@ eMBMasterFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen ) if( *usLen <= ( MB_FUNC_OTHER_REP_SLAVEID_BUF - 2 ) ) { - ucByteCount = ( UCHAR )( pucFrame[MB_PDU_FUNC_READ_BYTECNT_OFF] ); - ESP_LOGW("TEST", "Handle slave info command."); - eRegStatus = eMBMasterRegInputCB( &pucFrame[MB_PDU_FUNC_READ_VALUES_OFF], 0, (ucByteCount >> 1) ); + ucByteCount = ( UCHAR )( pucFrame[MB_PDU_BYTECNT_OFF] ); + ESP_LOGD("FHANDLER_SET_SLAVE_ID", "Master handler of slave info command %u bytes.", ucByteCount); + eRegStatus = eMBMasterRegInputCB( &pucFrame[MB_PDU_FUNC_DATA_OFF], 0, (ucByteCount >> 1) ); /* If an error occured convert it into a Modbus exception. */ if( eRegStatus != MB_ENOERR ) { @@ -129,6 +129,7 @@ eMBSetSlaveID( UCHAR ucSlaveID, BOOL xIsRunning, ( size_t )usAdditionalLen ); usMBSlaveIDLen += usAdditionalLen; } + ESP_LOG_BUFFER_HEX_LEVEL("FHANDLER_SET_SLAVE_ID", (void*)ucMBSlaveID, usMBSlaveIDLen, ESP_LOG_DEBUG); } else { @@ -137,11 +138,14 @@ eMBSetSlaveID( UCHAR ucSlaveID, BOOL xIsRunning, return eStatus; } +// pucFrame points to Modbus PDU eMBException eMBFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen ) { - memcpy( &pucFrame[MB_PDU_DATA_OFF], &ucMBSlaveID[0], ( size_t )usMBSlaveIDLen ); - *usLen = ( USHORT )( MB_PDU_DATA_OFF + usMBSlaveIDLen ); + memcpy( &pucFrame[MB_PDU_FUNC_DATA_OFF], &ucMBSlaveID[0], ( size_t )usMBSlaveIDLen ); + *usLen = ( USHORT )( MB_PDU_FUNC_DATA_OFF + usMBSlaveIDLen ); + pucFrame[MB_PDU_BYTECNT_OFF] = usMBSlaveIDLen; + ESP_LOG_BUFFER_HEX_LEVEL("REPORT_SLAVE_ID_FRAME", (void*)pucFrame, *usLen, ESP_LOG_DEBUG); return MB_EX_NONE; } diff --git a/freemodbus/serial_master/modbus_controller/mbc_serial_master.c b/freemodbus/serial_master/modbus_controller/mbc_serial_master.c index d3425e9..e079835 100644 --- a/freemodbus/serial_master/modbus_controller/mbc_serial_master.c +++ b/freemodbus/serial_master/modbus_controller/mbc_serial_master.c @@ -494,7 +494,7 @@ static esp_err_t mbc_serial_master_set_parameter(uint16_t cid, char* name, uint8 */ // Callback function for reading of MB Input Registers eMBErrorCode eMBRegInputCBSerialMaster(UCHAR * pucRegBuffer, USHORT usAddress, - USHORT usNRegs) + USHORT usNRegs) { MB_MASTER_CHECK((mbm_interface_ptr != NULL), MB_EILLSTATE, @@ -510,7 +510,7 @@ eMBErrorCode eMBRegInputCBSerialMaster(UCHAR * pucRegBuffer, USHORT usAddress, // If input or configuration parameters are incorrect then return an error to stack layer if ((pucInputBuffer != NULL) && (usNRegs >= 1) - && (usRegInputNregs == usRegs)) { + && ((usRegInputNregs == usRegs) || !usAddress)) { while (usRegs > 0) { _XFER_2_RD(pucInputBuffer, pucRegBuffer); usRegs -= 1; diff --git a/test/serial/mb_serial_master/main/master.c b/test/serial/mb_serial_master/main/master.c index 47fb317..c6f5c06 100644 --- a/test/serial/mb_serial_master/main/master.c +++ b/test/serial/mb_serial_master/main/master.c @@ -305,26 +305,22 @@ static void master_operation_func(void *arg) ESP_LOGI(TAG, "Start modbus test..."); - mb_param_request_t req = {0}; - - uint8_t info_buf[64] = {0}; - // Command - 17 (0x11) Report Slave ID (Serial Line only) - req.command = 0x11; // The command contains vendor specific data. // This version of command handler needs to define expected number of registers // that will be returned from concrete slave. // The returned slave info data will be stored in the `info_buf`. - req.reg_size = 16; - // This example will reques the slave infor from slave UID = 1. + // This example will request the slave info from slave UID = 1. // It can be modified accordingly for other slaves. - req.slave_addr = 0x01; + mb_param_request_t req = {.slave_addr = 1, .command = 0x11, .reg_start = 1, .reg_size = 16}; + + uint8_t info_buf[32] = {0}; err = mbc_master_send_request(&req, &info_buf[0]); if (err != ESP_OK) { ESP_LOGE("SLAVE_INFO", "Read slave info fail."); } else { - ESP_LOGI("SLAVE_INFO", "Slave ID array: %" PRIX32, *(uint32_t*)&info_buf[0]); + ESP_LOG_BUFFER_HEX_LEVEL("SLAVE_INFO", (void*)info_buf, sizeof(info_buf), ESP_LOG_WARN); } for(uint16_t retry = 0; retry <= MASTER_MAX_RETRY && (!alarm_state); retry++) { diff --git a/test/serial/mb_serial_slave/main/slave.c b/test/serial/mb_serial_slave/main/slave.c index 061fab0..3581e32 100644 --- a/test/serial/mb_serial_slave/main/slave.c +++ b/test/serial/mb_serial_slave/main/slave.c @@ -126,6 +126,10 @@ static void setup_reg_data(void) input_reg_params.input_data7 = 4.78; } +extern int +eMBSetSlaveID(uint8_t slave_id, bool is_running, + uint8_t const *pdata, uint16_t data_len); + // An example application of Modbus slave. It is based on freemodbus stack. // See deviceparams.h file for more information about assigned Modbus parameters. // These parameters can be accessed from main application and also can be changed @@ -226,6 +230,17 @@ void app_main(void) ESP_LOGI(TAG, "Modbus slave stack initialized."); ESP_LOGI(TAG, "Start modbus test..."); + //const uint32_t ext_data = 0x11223344; + uint8_t ext_data[] = {0x11, 0x22, 0x33, 0x44, 0x55}; + + int err = eMBSetSlaveID(comm_info.slave_addr, true, (uint8_t *)&ext_data, sizeof(ext_data)); + if (!err) { + //ESP_LOGI("SET_SLAVE_ID", "Set slave ID = %d, ext_data=0x%" PRIx32, comm_info.slave_addr, ext_data); + ESP_LOG_BUFFER_HEX_LEVEL("SET_SLAVE_ID", (void*)ext_data, sizeof(ext_data), ESP_LOG_WARN); + } else { + ESP_LOGE("SET_SLAVE_ID", "Set slave ID fail, err=%d.", err); + } + // The cycle below will be terminated when parameter holdingRegParams.dataChan0 // incremented each access cycle reaches the CHAN_DATA_MAX_VAL value. for(;holding_reg_params.holding_data0 < MB_CHAN_DATA_MAX_VAL;) {