From 0fa0d73b2062af78db775d22fc0890ed7fcffa5c Mon Sep 17 00:00:00 2001 From: aleks Date: Sun, 13 Oct 2024 20:54:28 +0200 Subject: [PATCH] add the 0x11 command - get slave info --- freemodbus/modbus/functions/mbfuncother.c | 51 +++++++++++++++++++ freemodbus/modbus/include/mb_m.h | 2 + freemodbus/modbus/mb_m.c | 2 +- .../modbus_controller/mbc_serial_master.c | 4 +- test/serial/mb_serial_master/main/master.c | 22 ++++++++ 5 files changed, 79 insertions(+), 2 deletions(-) diff --git a/freemodbus/modbus/functions/mbfuncother.c b/freemodbus/modbus/functions/mbfuncother.c index 59d6bda..91c8d1f 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_FUNC_READ_BYTECNT_OFF ( MB_PDU_DATA_OFF + 0 ) +#define MB_PDU_FUNC_READ_VALUES_OFF ( MB_PDU_DATA_OFF + 1 ) + /* ----------------------- Static variables ---------------------------------*/ static UCHAR ucMBSlaveID[MB_FUNC_OTHER_REP_SLAVEID_BUF]; 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_FUNC_READ_BYTECNT_OFF] ); + ESP_LOGW("TEST", "Handle slave info command."); + eRegStatus = eMBMasterRegInputCB( &pucFrame[MB_PDU_FUNC_READ_VALUES_OFF], 0, (ucByteCount >> 1) ); + /* 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, diff --git a/freemodbus/modbus/include/mb_m.h b/freemodbus/modbus/include/mb_m.h index 33421ef..3a0b15c 100644 --- a/freemodbus/modbus/include/mb_m.h +++ b/freemodbus/modbus/include/mb_m.h @@ -365,6 +365,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/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..d3425e9 100644 --- a/freemodbus/serial_master/modbus_controller/mbc_serial_master.c +++ b/freemodbus/serial_master/modbus_controller/mbc_serial_master.c @@ -192,6 +192,9 @@ static esp_err_t mbc_serial_master_send_request(mb_param_request_t* request, voi // 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, diff --git a/test/serial/mb_serial_master/main/master.c b/test/serial/mb_serial_master/main/master.c index 2559525..47fb317 100644 --- a/test/serial/mb_serial_master/main/master.c +++ b/test/serial/mb_serial_master/main/master.c @@ -305,6 +305,28 @@ 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. + // It can be modified accordingly for other slaves. + req.slave_addr = 0x01; + + 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]); + } + 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++) {