diff --git a/Kconfig b/Kconfig index 3b2a2e2..340971e 100644 --- a/Kconfig +++ b/Kconfig @@ -58,7 +58,7 @@ menu "Modbus configuration" config FMB_MASTER_TIMEOUT_MS_RESPOND int "Slave respond timeout (Milliseconds)" default 3000 - range 150 15000 + range 300 15000 help If master sends a frame which is not broadcast, it has to wait sometime for slave response. if slave is not respond in this time, the master will process timeout error. @@ -171,6 +171,15 @@ menu "Modbus configuration" Most significant byte of ID is used as short device ID and other three bytes used as long ID. + config FMB_CONTROLLER_SLAVE_ID_MAX_SIZE + int "Modbus Slave ID maximum buffer size (bytes)" + range 4 255 + default 32 + depends on FMB_CONTROLLER_SLAVE_ID_SUPPORT + help + Modbus slave ID buffer size used to store vendor specific ID information + for the command. + config FMB_CONTROLLER_NOTIFY_TIMEOUT int "Modbus controller notification timeout (ms)" range 0 200 diff --git a/freemodbus/common/esp_modbus_master.c b/freemodbus/common/esp_modbus_master.c index a0af76c..599342c 100644 --- a/freemodbus/common/esp_modbus_master.c +++ b/freemodbus/common/esp_modbus_master.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include "esp_err.h" // for esp_err_t #include "mbc_master.h" // for master interface define #include "esp_modbus_master.h" // for public interface defines @@ -237,6 +238,29 @@ eMBErrorCode eMBMasterRegInputCB(UCHAR * pucRegBuffer, USHORT usAddress, return error; } +eMBErrorCode eMBMasterRegCommonCB(UCHAR * pucData, USHORT usAddress, + USHORT usBytes) +{ + MB_MASTER_CHECK((master_interface_ptr != NULL), + MB_EILLSTATE, + "Master interface is not correctly initialized."); + MB_MASTER_CHECK((master_interface_ptr != NULL), + MB_EILLSTATE, + "Master interface uninitialized."); + MB_MASTER_CHECK(pucData, MB_EINVAL, + "Master stack processing error."); + mb_master_options_t* popts = &master_interface_ptr->opts; + USHORT usRegLen = (USHORT)popts->mbm_reg_buffer_size; + UCHAR* pucParBuffer = (UCHAR*)popts->mbm_reg_buffer_ptr; // Get instance address + eMBErrorCode eStatus = MB_ENOERR; + if (pucParBuffer && !usAddress && (usBytes >= 1) && (((usRegLen << 1) >= usBytes))){ + memmove(pucParBuffer, pucData, MIN((usRegLen << 1), usBytes)); + } else { + eStatus = MB_ENOREG; + } + return eStatus; +} + /** * Helper function to get current transaction info */ diff --git a/freemodbus/common/mbc_master.h b/freemodbus/common/mbc_master.h index a736fab..d078264 100644 --- a/freemodbus/common/mbc_master.h +++ b/freemodbus/common/mbc_master.h @@ -11,6 +11,7 @@ #include "freertos/FreeRTOS.h" // for task creation and queue access #include "freertos/task.h" // for task api access #include "freertos/event_groups.h" // for event groups +#include "freertos/semphr.h" // for semaphore #include "driver/uart.h" // for UART types #include "errno.h" // for errno #include "esp_log.h" // for log write @@ -64,6 +65,7 @@ typedef struct { uint16_t mbm_reg_buffer_size; /*!< Modbus data buffer size */ TaskHandle_t mbm_task_handle; /*!< Modbus task handle */ EventGroupHandle_t mbm_event_group; /*!< Modbus controller event group */ + SemaphoreHandle_t mbm_sema; /*!< Modbus controller semaphore */ const mb_parameter_descriptor_t* mbm_param_descriptor_table; /*!< Modbus controller parameter description table */ size_t mbm_param_descriptor_size; /*!< Modbus controller parameter description table size*/ #if MB_MASTER_TCP_ENABLED diff --git a/freemodbus/modbus/functions/mbfuncother.c b/freemodbus/modbus/functions/mbfuncother.c index 59d6bda..2e32827 100644 --- a/freemodbus/modbus/functions/mbfuncother.c +++ b/freemodbus/modbus/functions/mbfuncother.c @@ -44,6 +44,7 @@ /* ----------------------- Modbus includes ----------------------------------*/ #include "mb.h" +#include "mb_m.h" #include "mbframe.h" #include "mbproto.h" #include "mbconfig.h" @@ -52,11 +53,61 @@ #if MB_FUNC_OTHER_REP_SLAVEID_ENABLED +#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 -----------------------------*/ +eMBException prveMBError2Exception( eMBErrorCode eErrorCode ); + +eMBMasterReqErrCode +eMBMasterReqReportSlaveID( UCHAR ucSndAddr, LONG lTimeOut ) +{ + UCHAR *ucMBFrame; + eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR; + + if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG; + else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY; + else + { + vMBMasterGetPDUSndBuf(&ucMBFrame); + vMBMasterSetDestAddress(ucSndAddr); + ucMBFrame[MB_PDU_FUNC_OFF] = MB_FUNC_OTHER_REPORT_SLAVEID; + vMBMasterSetPDUSndLength( 1 ); + ( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT | EV_MASTER_TRANS_START ); + eErrStatus = eMBMasterWaitRequestFinish( ); + } + return eErrStatus; +} + +eMBException +eMBMasterFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen ) +{ + UCHAR ucByteCount = 0; + eMBException eStatus = MB_EX_NONE; + eMBErrorCode eRegStatus; + + if( *usLen <= ( MB_FUNC_OTHER_REP_SLAVEID_BUF - 2 ) ) + { + ucByteCount = ( UCHAR )( pucFrame[MB_PDU_BYTECNT_OFF] ); + // Transfer data from command buffer. + eRegStatus = eMBMasterRegCommonCB( &pucFrame[MB_PDU_FUNC_DATA_OFF], 0, ucByteCount); + /* If an error occured convert it into a Modbus exception. */ + if( eRegStatus != MB_ENOERR ) + { + eStatus = prveMBError2Exception( eRegStatus ); + } + } + else + { + /* Can't be a valid request because the length is incorrect. */ + eStatus = MB_EX_ILLEGAL_DATA_VALUE; + } + return eStatus; +} eMBErrorCode eMBSetSlaveID( UCHAR ucSlaveID, BOOL xIsRunning, @@ -86,11 +137,13 @@ 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; return MB_EX_NONE; } diff --git a/freemodbus/modbus/include/mb_m.h b/freemodbus/modbus/include/mb_m.h index 33421ef..2935008 100644 --- a/freemodbus/modbus/include/mb_m.h +++ b/freemodbus/modbus/include/mb_m.h @@ -258,6 +258,24 @@ eMBErrorCode eMBMasterRegisterCB( UCHAR ucFunctionCode, * to update the application register values. */ +/*! \ingroup modbus_registers + * \brief The common callback function used to transfer common data as bytes + * from command buffer in little endian format. + * + * \param pucData A pointer to data in command buffer to be transferred. + * \param usAddress Unused for this function == 0. + * \param usBytes Number of bytes the callback function must supply. + * + * \return The function must return one of the following error codes: + * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal + * Modbus response is sent. + * - eMBErrorCode::MB_ENOREG if can not map the data of the registers + * - eMBErrorCode::MB_EILLSTATE if can not procceed with data transfer due to critical error + * - eMBErrorCode::MB_EINVAL if value data can not be transferred + */ +eMBErrorCode eMBMasterRegCommonCB( UCHAR * pucData, USHORT usAddress, + USHORT usBytes ); + /*! \ingroup modbus_registers * \brief Callback function used if the value of a Input Register * is required by the protocol stack. The starting register address is given @@ -273,9 +291,9 @@ eMBErrorCode eMBMasterRegisterCB( UCHAR ucFunctionCode, * \return The function must return one of the following error codes: * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal * Modbus response is sent. - * - eMBErrorCode::MB_ENOREG If the application does not map an coils - * within the requested address range. In this case a - * ILLEGAL DATA ADDRESS is sent as a response. + * - eMBErrorCode::MB_ENOREG if can not map the data of the registers + * - eMBErrorCode::MB_EILLSTATE if can not procceed with data transfer due to critical error + * - eMBErrorCode::MB_EINVAL if value data can not be transferred */ eMBErrorCode eMBMasterRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs ); @@ -365,6 +383,8 @@ eMBErrorCode eMBMasterRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, *\brief These Modbus functions are called for user when Modbus run in Master Mode. */ eMBMasterReqErrCode +eMBMasterReqReportSlaveID( UCHAR ucSndAddr, LONG lTimeOut ); +eMBMasterReqErrCode eMBMasterReqReadInputRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs, LONG lTimeOut ); eMBMasterReqErrCode eMBMasterReqWriteHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usRegData, LONG lTimeOut ); diff --git a/freemodbus/modbus/include/mbconfig.h b/freemodbus/modbus/include/mbconfig.h index 171208a..8b547a0 100644 --- a/freemodbus/modbus/include/mbconfig.h +++ b/freemodbus/modbus/include/mbconfig.h @@ -144,7 +144,7 @@ PR_BEGIN_EXTERN_C * how to set this value. It is only used if MB_FUNC_OTHER_REP_SLAVEID_ENABLED * is set to 1. */ -#define MB_FUNC_OTHER_REP_SLAVEID_BUF ( 32 ) +#define MB_FUNC_OTHER_REP_SLAVEID_BUF ( CONFIG_FMB_CONTROLLER_SLAVE_ID_MAX_SIZE ) /*! \brief If the Report Slave ID function should be enabled. */ #define MB_FUNC_OTHER_REP_SLAVEID_ENABLED ( CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT ) diff --git a/freemodbus/modbus/mb_m.c b/freemodbus/modbus/mb_m.c index 573dfd7..7e9cfff 100644 --- a/freemodbus/modbus/mb_m.c +++ b/freemodbus/modbus/mb_m.c @@ -129,7 +129,7 @@ BOOL( *pxMBMasterFrameCBTransmitFSMCur ) ( void ); */ static xMBFunctionHandler xMasterFuncHandlers[MB_FUNC_HANDLERS_MAX] = { #if MB_FUNC_OTHER_REP_SLAVEID_ENABLED > 0 - {MB_FUNC_OTHER_REPORT_SLAVEID, eMBFuncReportSlaveID}, + {MB_FUNC_OTHER_REPORT_SLAVEID, eMBMasterFuncReportSlaveID}, #endif #if MB_FUNC_READ_INPUT_ENABLED > 0 {MB_FUNC_READ_INPUT_REGISTER, eMBMasterFuncReadInputRegister}, diff --git a/freemodbus/serial_master/modbus_controller/mbc_serial_master.c b/freemodbus/serial_master/modbus_controller/mbc_serial_master.c index 307dca2..3de4cc3 100644 --- a/freemodbus/serial_master/modbus_controller/mbc_serial_master.c +++ b/freemodbus/serial_master/modbus_controller/mbc_serial_master.c @@ -14,6 +14,7 @@ #include "freertos/task.h" // for task api access #include "freertos/event_groups.h" // for event groups #include "freertos/queue.h" // for queue api access +#include "freertos/semphr.h" // for semaphore #include "mb_m.h" // for modbus stack master types definition #include "port.h" // for port callback functions #include "mbutils.h" // for mbutils functions definition for stack callback @@ -28,7 +29,7 @@ extern BOOL xMBMasterPortSerialTxPoll(void); /*-----------------------Master mode use these variables----------------------*/ // Actual wait time depends on the response timer -#define MB_SERIAL_API_RESP_TICS (pdMS_TO_TICKS(MB_MAX_RESPONSE_TIME_MS)) +#define MB_SERIAL_API_RESP_TICS (pdMS_TO_TICKS(MB_MAX_RESPONSE_TIME_MS)) static mb_master_interface_t* mbm_interface_ptr = NULL; static const char *TAG = "MB_CONTROLLER_MASTER"; @@ -127,6 +128,8 @@ static esp_err_t mbc_serial_master_destroy(void) MB_MASTER_CHECK((mb_error == MB_ENOERR), ESP_ERR_INVALID_STATE, "mb stack disable failure."); (void)vTaskDelete(mbm_opts->mbm_task_handle); (void)vEventGroupDelete(mbm_opts->mbm_event_group); + vSemaphoreDelete(mbm_opts->mbm_sema); + mbm_opts->mbm_sema = NULL; mb_error = eMBMasterClose(); MB_MASTER_CHECK((mb_error == MB_ENOERR), ESP_ERR_INVALID_STATE, "mb stack close failure returned (0x%x).", (int)mb_error); @@ -176,22 +179,22 @@ static esp_err_t mbc_serial_master_send_request(mb_param_request_t* request, voi eMBMasterReqErrCode mb_error = MB_MRE_MASTER_BUSY; esp_err_t error = ESP_FAIL; - if (xMBMasterRunResTake(MB_SERIAL_API_RESP_TICS)) { - + if (xSemaphoreTake(mbm_opts->mbm_sema, MB_SERIAL_API_RESP_TICS) == pdTRUE) { uint8_t mb_slave_addr = request->slave_addr; uint8_t mb_command = request->command; uint16_t mb_offset = request->reg_start; uint16_t mb_size = request->reg_size; - + // Set the buffer for callback function processing of received data mbm_opts->mbm_reg_buffer_ptr = (uint8_t*)data_ptr; mbm_opts->mbm_reg_buffer_size = mb_size; - vMBMasterRunResRelease(); - // Calls appropriate request function to send request and waits response switch(mb_command) { + case MB_FUNC_OTHER_REPORT_SLAVEID: + mb_error = eMBMasterReqReportSlaveID((UCHAR)mb_slave_addr, (LONG)MB_SERIAL_API_RESP_TICS ); + break; case MB_FUNC_READ_COILS: mb_error = eMBMasterReqReadCoils((UCHAR)mb_slave_addr, (USHORT)mb_offset, (USHORT)mb_size , (LONG)MB_SERIAL_API_RESP_TICS ); @@ -216,7 +219,6 @@ static esp_err_t mbc_serial_master_send_request(mb_param_request_t* request, voi mb_error = eMBMasterReqWriteHoldingRegister( (UCHAR)mb_slave_addr, (USHORT)mb_offset, *(USHORT*)data_ptr, (LONG)MB_SERIAL_API_RESP_TICS ); break; - case MB_FUNC_WRITE_MULTIPLE_REGISTERS: mb_error = eMBMasterReqWriteMultipleHoldingRegister( (UCHAR)mb_slave_addr, (USHORT)mb_offset, (USHORT)mb_size, @@ -237,6 +239,8 @@ static esp_err_t mbc_serial_master_send_request(mb_param_request_t* request, voi mb_error = MB_MRE_NO_REG; break; } + } else { + ESP_LOGD(TAG, "%s:MBC semaphore take fail.", __func__); } // Propagate the Modbus errors to higher level @@ -264,11 +268,13 @@ static esp_err_t mbc_serial_master_send_request(mb_param_request_t* request, voi break; default: - ESP_LOGE(TAG, "%s: Incorrect return code (%x) ", __FUNCTION__, (int)mb_error); + ESP_LOGE(TAG, "%s: Incorrect return code (0x%x) ", __FUNCTION__, (int)mb_error); error = ESP_FAIL; break; } + (void)xSemaphoreGive( mbm_opts->mbm_sema ); + return error; } @@ -508,7 +514,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; @@ -698,6 +704,10 @@ esp_err_t mbc_serial_master_create(void** handler) mbm_opts->mbm_event_group = xEventGroupCreate(); MB_MASTER_CHECK((mbm_opts->mbm_event_group != NULL), ESP_ERR_NO_MEM, "mb event group error."); + mbm_opts->mbm_sema = xSemaphoreCreateBinary(); + MB_MASTER_CHECK((mbm_opts->mbm_sema != NULL), ESP_ERR_NO_MEM, "%s: mbm resource create error.", __func__); + (void)xSemaphoreGive( mbm_opts->mbm_sema ); + // Create modbus controller task status = xTaskCreatePinnedToCore((void*)&modbus_master_task, "modbus_matask", diff --git a/freemodbus/tcp_master/modbus_controller/mbc_tcp_master.c b/freemodbus/tcp_master/modbus_controller/mbc_tcp_master.c index ce385e1..ad06126 100644 --- a/freemodbus/tcp_master/modbus_controller/mbc_tcp_master.c +++ b/freemodbus/tcp_master/modbus_controller/mbc_tcp_master.c @@ -15,6 +15,7 @@ #include "freertos/task.h" // for task api access #include "freertos/event_groups.h" // for event groups #include "freertos/queue.h" // for queue api access +#include "freertos/semphr.h" // for semaphore #include "mb_m.h" // for modbus stack master types definition #include "port.h" // for port callback functions and defines #include "mbutils.h" // for mbutils functions definition for stack callback @@ -28,7 +29,6 @@ #if MB_MASTER_TCP_ENABLED /*-----------------------Master mode use these variables----------------------*/ - #define MB_TCP_CONNECTION_TOUT (pdMS_TO_TICKS(CONFIG_FMB_TCP_CONNECTION_TOUT_SEC * 1000)) // Actual wait time depends on the response timer @@ -197,7 +197,9 @@ static esp_err_t mbc_tcp_master_destroy(void) MB_MASTER_CHECK((mb_error == MB_ENOERR), ESP_ERR_INVALID_STATE, "mb stack disable failure."); (void)vTaskDelete(mbm_opts->mbm_task_handle); - mbm_opts->mbm_task_handle = NULL; + mbm_opts->mbm_task_handle = NULL; + vSemaphoreDelete(mbm_opts->mbm_sema); + mbm_opts->mbm_sema = NULL; mb_error = eMBMasterClose(); MB_MASTER_CHECK((mb_error == MB_ENOERR), ESP_ERR_INVALID_STATE, @@ -261,19 +263,16 @@ static esp_err_t mbc_tcp_master_send_request(mb_param_request_t* request, void* eMBMasterReqErrCode mb_error = MB_MRE_MASTER_BUSY; esp_err_t error = ESP_FAIL; - if (xMBMasterRunResTake(MB_TCP_API_RESP_TICS)) { - + if (xSemaphoreTake(mbm_opts->mbm_sema, MB_TCP_API_RESP_TICS) == pdTRUE) { uint8_t mb_slave_addr = request->slave_addr; uint8_t mb_command = request->command; uint16_t mb_offset = request->reg_start; uint16_t mb_size = request->reg_size; - + // Set the buffer for callback function processing of received data mbm_opts->mbm_reg_buffer_ptr = (uint8_t*)data_ptr; mbm_opts->mbm_reg_buffer_size = mb_size; - vMBMasterRunResRelease(); - // Calls appropriate request function to send request and waits response switch(mb_command) { @@ -323,7 +322,9 @@ static esp_err_t mbc_tcp_master_send_request(mb_param_request_t* request, void* mb_error = MB_MRE_NO_REG; break; } - } + } else { + ESP_LOGD(TAG, "%s:MBC semaphore take fail.", __func__); + } // Propagate the Modbus errors to higher level switch(mb_error) @@ -350,10 +351,11 @@ static esp_err_t mbc_tcp_master_send_request(mb_param_request_t* request, void* break; default: - ESP_LOGE(TAG, "%s: Incorrect return code (0x%x) ", __FUNCTION__, (unsigned)mb_error); + ESP_LOGE(TAG, "%s: Incorrect return code (0x%x) ", __FUNCTION__, (int)mb_error); error = ESP_FAIL; break; } + xSemaphoreGive( mbm_opts->mbm_sema ); return error; } @@ -744,6 +746,10 @@ esp_err_t mbc_tcp_master_create(void** handler) // Parameter change notification queue mbm_opts->mbm_event_group = xEventGroupCreate(); MB_MASTER_CHECK((mbm_opts->mbm_event_group != NULL), ESP_ERR_NO_MEM, "mb event group error."); + mbm_opts->mbm_sema = xSemaphoreCreateBinary(); + MB_MASTER_CHECK((mbm_opts->mbm_sema), ESP_ERR_NO_MEM, "%s: mbm resource create error.", __func__); + (void)xSemaphoreGive( mbm_opts->mbm_sema ); + // Create modbus controller task status = xTaskCreate((void*)&modbus_tcp_master_task, "modbus_tcp_master_task", diff --git a/idf_component.yml b/idf_component.yml index 9a6ec47..5ebee56 100644 --- a/idf_component.yml +++ b/idf_component.yml @@ -1,4 +1,4 @@ -version: "1.0.16" +version: "1.0.17" description: ESP-MODBUS is the official Modbus library for Espressif SoCs. url: https://github.com/espressif/esp-modbus dependencies: diff --git a/test/serial/mb_serial_master/main/master.c b/test/serial/mb_serial_master/main/master.c index 2559525..375bf60 100644 --- a/test/serial/mb_serial_master/main/master.c +++ b/test/serial/mb_serial_master/main/master.c @@ -305,6 +305,26 @@ static void master_operation_func(void *arg) ESP_LOGI(TAG, "Start modbus test..."); + // Command - 17 (0x11) Report Slave ID (Serial Line only) + // The command contains vendor specific data and should be interpreted accordingly. + // This version of command handler needs to define the maximum number + // of registers that can be returned from concrete slave (buffer size). + // The returned slave info data will be stored into the `info_buf`. + // Request fields: slave_addr - the UID of slave, reg_start - not used, + // reg_size = max size of buffer (registers). + mb_param_request_t req = {.slave_addr = 1, .command = 0x11, + .reg_start = 0, .reg_size = (CONFIG_FMB_CONTROLLER_SLAVE_ID_MAX_SIZE >> 1)}; + + uint8_t info_buf[CONFIG_FMB_CONTROLLER_SLAVE_ID_MAX_SIZE] = {0}; + + // This is the way to retrieve slave ID information from slave (vendor specific command = 0x11). + err = mbc_master_send_request(&req, &info_buf[0]); + if (err != ESP_OK) { + ESP_LOGE("SLAVE_INFO", "Read slave info fail."); + } else { + 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++) { // Read all found characteristics from slave(s) for (uint16_t cid = 0; (err != ESP_ERR_NOT_FOUND) && cid < MASTER_MAX_CIDS; cid++) { diff --git a/test/serial/mb_serial_slave/main/slave.c b/test/serial/mb_serial_slave/main/slave.c index fa10e40..7a45dfd 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; } +// This is the way to expose the funcion to set slave ID . +// The related function is vendor specific and stack by default hides this functionality from user. +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,15 @@ void app_main(void) ESP_LOGI(TAG, "Modbus slave stack initialized."); ESP_LOGI(TAG, "Start modbus test..."); + uint8_t ext_data[] = {0x11, 0x22, 0x33, 0x44, 0x55}; + // This is the way to set Slave ID fields to retrieve it by master using report slave ID command. + int err = eMBSetSlaveID(comm_info.slave_addr, true, (uint8_t *)&ext_data, sizeof(ext_data)); + if (!err) { + 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;) {