fix api lock sequence

This commit is contained in:
aleks
2024-10-23 21:46:34 +02:00
parent 50ba25f55c
commit 0d66d9631b
7 changed files with 48 additions and 23 deletions

View File

@ -171,6 +171,15 @@ menu "Modbus configuration"
Most significant byte of ID is used as short device ID and Most significant byte of ID is used as short device ID and
other three bytes used as long ID. other three bytes used as long ID.
config FMB_CONTROLLER_SLAVE_ID_MAX_SIZE
int "Modbus Slave ID maximum buffer size (bytes)"
range 0 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 <Report Slave ID> command.
config FMB_CONTROLLER_NOTIFY_TIMEOUT config FMB_CONTROLLER_NOTIFY_TIMEOUT
int "Modbus controller notification timeout (ms)" int "Modbus controller notification timeout (ms)"
range 0 200 range 0 200

View File

@ -11,6 +11,7 @@
#include "freertos/FreeRTOS.h" // for task creation and queue access #include "freertos/FreeRTOS.h" // for task creation and queue access
#include "freertos/task.h" // for task api access #include "freertos/task.h" // for task api access
#include "freertos/event_groups.h" // for event groups #include "freertos/event_groups.h" // for event groups
#include "freertos/semphr.h" // for semaphore
#include "driver/uart.h" // for UART types #include "driver/uart.h" // for UART types
#include "errno.h" // for errno #include "errno.h" // for errno
#include "esp_log.h" // for log write #include "esp_log.h" // for log write
@ -64,6 +65,7 @@ typedef struct {
uint16_t mbm_reg_buffer_size; /*!< Modbus data buffer size */ uint16_t mbm_reg_buffer_size; /*!< Modbus data buffer size */
TaskHandle_t mbm_task_handle; /*!< Modbus task handle */ TaskHandle_t mbm_task_handle; /*!< Modbus task handle */
EventGroupHandle_t mbm_event_group; /*!< Modbus controller event group */ 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 */ 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*/ size_t mbm_param_descriptor_size; /*!< Modbus controller parameter description table size*/
#if MB_MASTER_TCP_ENABLED #if MB_MASTER_TCP_ENABLED

View File

@ -53,8 +53,8 @@
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED #if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
#define MB_PDU_BYTECNT_OFF ( MB_PDU_DATA_OFF + 0 ) #define MB_PDU_BYTECNT_OFF ( MB_PDU_DATA_OFF + 0 )
#define MB_PDU_FUNC_DATA_OFF ( MB_PDU_DATA_OFF + 1 ) #define MB_PDU_FUNC_DATA_OFF ( MB_PDU_DATA_OFF + 1 )
/* ----------------------- Static variables ---------------------------------*/ /* ----------------------- Static variables ---------------------------------*/
static UCHAR ucMBSlaveID[MB_FUNC_OTHER_REP_SLAVEID_BUF] = {0}; static UCHAR ucMBSlaveID[MB_FUNC_OTHER_REP_SLAVEID_BUF] = {0};
@ -93,7 +93,7 @@ eMBMasterFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen )
if( *usLen <= ( MB_FUNC_OTHER_REP_SLAVEID_BUF - 2 ) ) if( *usLen <= ( MB_FUNC_OTHER_REP_SLAVEID_BUF - 2 ) )
{ {
ucByteCount = ( UCHAR )( pucFrame[MB_PDU_BYTECNT_OFF] ); ucByteCount = ( UCHAR )( pucFrame[MB_PDU_BYTECNT_OFF] );
ESP_LOGD("FHANDLER_SET_SLAVE_ID", "Master handler of slave info command %u bytes.", ucByteCount); ESP_LOGD("MB_FHANDLER", "Master handler of slave info data, %u bytes.", ucByteCount);
eRegStatus = eMBMasterRegInputCB( &pucFrame[MB_PDU_FUNC_DATA_OFF], 0, (ucByteCount >> 1) ); eRegStatus = eMBMasterRegInputCB( &pucFrame[MB_PDU_FUNC_DATA_OFF], 0, (ucByteCount >> 1) );
/* If an error occured convert it into a Modbus exception. */ /* If an error occured convert it into a Modbus exception. */
if( eRegStatus != MB_ENOERR ) if( eRegStatus != MB_ENOERR )
@ -129,7 +129,7 @@ eMBSetSlaveID( UCHAR ucSlaveID, BOOL xIsRunning,
( size_t )usAdditionalLen ); ( size_t )usAdditionalLen );
usMBSlaveIDLen += usAdditionalLen; usMBSlaveIDLen += usAdditionalLen;
} }
ESP_LOG_BUFFER_HEX_LEVEL("FHANDLER_SET_SLAVE_ID", (void*)ucMBSlaveID, usMBSlaveIDLen, ESP_LOG_DEBUG); ESP_LOG_BUFFER_HEX_LEVEL("MB_FHANDLER", (void*)ucMBSlaveID, usMBSlaveIDLen, ESP_LOG_DEBUG);
} }
else else
{ {
@ -145,7 +145,7 @@ eMBFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen )
memcpy( &pucFrame[MB_PDU_FUNC_DATA_OFF], &ucMBSlaveID[0], ( size_t )usMBSlaveIDLen ); memcpy( &pucFrame[MB_PDU_FUNC_DATA_OFF], &ucMBSlaveID[0], ( size_t )usMBSlaveIDLen );
*usLen = ( USHORT )( MB_PDU_FUNC_DATA_OFF + usMBSlaveIDLen ); *usLen = ( USHORT )( MB_PDU_FUNC_DATA_OFF + usMBSlaveIDLen );
pucFrame[MB_PDU_BYTECNT_OFF] = usMBSlaveIDLen; pucFrame[MB_PDU_BYTECNT_OFF] = usMBSlaveIDLen;
ESP_LOG_BUFFER_HEX_LEVEL("REPORT_SLAVE_ID_FRAME", (void*)pucFrame, *usLen, ESP_LOG_DEBUG); ESP_LOG_BUFFER_HEX_LEVEL("MB_FHANDLER", (void*)pucFrame, *usLen, ESP_LOG_DEBUG);
return MB_EX_NONE; return MB_EX_NONE;
} }

View File

@ -144,7 +144,7 @@ PR_BEGIN_EXTERN_C
* how to set this value. It is only used if MB_FUNC_OTHER_REP_SLAVEID_ENABLED * how to set this value. It is only used if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
* is set to <code>1</code>. * is set to <code>1</code>.
*/ */
#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 <em>Report Slave ID</em> function should be enabled. */ /*! \brief If the <em>Report Slave ID</em> function should be enabled. */
#define MB_FUNC_OTHER_REP_SLAVEID_ENABLED ( CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT ) #define MB_FUNC_OTHER_REP_SLAVEID_ENABLED ( CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT )

View File

@ -14,6 +14,7 @@
#include "freertos/task.h" // for task api access #include "freertos/task.h" // for task api access
#include "freertos/event_groups.h" // for event groups #include "freertos/event_groups.h" // for event groups
#include "freertos/queue.h" // for queue api access #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 "mb_m.h" // for modbus stack master types definition
#include "port.h" // for port callback functions #include "port.h" // for port callback functions
#include "mbutils.h" // for mbutils functions definition for stack callback #include "mbutils.h" // for mbutils functions definition for stack callback
@ -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."); MB_MASTER_CHECK((mb_error == MB_ENOERR), ESP_ERR_INVALID_STATE, "mb stack disable failure.");
(void)vTaskDelete(mbm_opts->mbm_task_handle); (void)vTaskDelete(mbm_opts->mbm_task_handle);
(void)vEventGroupDelete(mbm_opts->mbm_event_group); (void)vEventGroupDelete(mbm_opts->mbm_event_group);
vSemaphoreDelete(mbm_opts->mbm_sema);
mbm_opts->mbm_sema = NULL;
mb_error = eMBMasterClose(); mb_error = eMBMasterClose();
MB_MASTER_CHECK((mb_error == MB_ENOERR), ESP_ERR_INVALID_STATE, MB_MASTER_CHECK((mb_error == MB_ENOERR), ESP_ERR_INVALID_STATE,
"mb stack close failure returned (0x%x).", (int)mb_error); "mb stack close failure returned (0x%x).", (int)mb_error);
@ -176,19 +179,16 @@ static esp_err_t mbc_serial_master_send_request(mb_param_request_t* request, voi
eMBMasterReqErrCode mb_error = MB_MRE_MASTER_BUSY; eMBMasterReqErrCode mb_error = MB_MRE_MASTER_BUSY;
esp_err_t error = ESP_FAIL; 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_slave_addr = request->slave_addr;
uint8_t mb_command = request->command; uint8_t mb_command = request->command;
uint16_t mb_offset = request->reg_start; uint16_t mb_offset = request->reg_start;
uint16_t mb_size = request->reg_size; uint16_t mb_size = request->reg_size;
// Set the buffer for callback function processing of received data // 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_ptr = (uint8_t*)data_ptr;
mbm_opts->mbm_reg_buffer_size = mb_size; mbm_opts->mbm_reg_buffer_size = mb_size;
vMBMasterRunResRelease();
// Calls appropriate request function to send request and waits response // Calls appropriate request function to send request and waits response
switch(mb_command) switch(mb_command)
{ {
@ -239,6 +239,8 @@ static esp_err_t mbc_serial_master_send_request(mb_param_request_t* request, voi
mb_error = MB_MRE_NO_REG; mb_error = MB_MRE_NO_REG;
break; break;
} }
} else {
ESP_LOGD(TAG, "%s:MBC semaphore take fail.", __func__);
} }
// Propagate the Modbus errors to higher level // Propagate the Modbus errors to higher level
@ -266,11 +268,13 @@ static esp_err_t mbc_serial_master_send_request(mb_param_request_t* request, voi
break; break;
default: 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; error = ESP_FAIL;
break; break;
} }
(void)xSemaphoreGive( mbm_opts->mbm_sema );
return error; return error;
} }
@ -494,7 +498,7 @@ static esp_err_t mbc_serial_master_set_parameter(uint16_t cid, char* name, uint8
*/ */
// Callback function for reading of MB Input Registers // Callback function for reading of MB Input Registers
eMBErrorCode eMBRegInputCBSerialMaster(UCHAR * pucRegBuffer, USHORT usAddress, eMBErrorCode eMBRegInputCBSerialMaster(UCHAR * pucRegBuffer, USHORT usAddress,
USHORT usNRegs) USHORT usNRegs)
{ {
MB_MASTER_CHECK((mbm_interface_ptr != NULL), MB_MASTER_CHECK((mbm_interface_ptr != NULL),
MB_EILLSTATE, MB_EILLSTATE,
@ -510,7 +514,7 @@ eMBErrorCode eMBRegInputCBSerialMaster(UCHAR * pucRegBuffer, USHORT usAddress,
// If input or configuration parameters are incorrect then return an error to stack layer // If input or configuration parameters are incorrect then return an error to stack layer
if ((pucInputBuffer != NULL) if ((pucInputBuffer != NULL)
&& (usNRegs >= 1) && (usNRegs >= 1)
&& ((usRegInputNregs == usRegs) || !usAddress)) { && ((usRegInputNregs == usRegs) || (!usAddress))) {
while (usRegs > 0) { while (usRegs > 0) {
_XFER_2_RD(pucInputBuffer, pucRegBuffer); _XFER_2_RD(pucInputBuffer, pucRegBuffer);
usRegs -= 1; usRegs -= 1;
@ -700,6 +704,10 @@ esp_err_t mbc_serial_master_create(void** handler)
mbm_opts->mbm_event_group = xEventGroupCreate(); mbm_opts->mbm_event_group = xEventGroupCreate();
MB_MASTER_CHECK((mbm_opts->mbm_event_group != NULL), MB_MASTER_CHECK((mbm_opts->mbm_event_group != NULL),
ESP_ERR_NO_MEM, "mb event group error."); 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 // Create modbus controller task
status = xTaskCreatePinnedToCore((void*)&modbus_master_task, status = xTaskCreatePinnedToCore((void*)&modbus_master_task,
"modbus_matask", "modbus_matask",

View File

@ -15,6 +15,7 @@
#include "freertos/task.h" // for task api access #include "freertos/task.h" // for task api access
#include "freertos/event_groups.h" // for event groups #include "freertos/event_groups.h" // for event groups
#include "freertos/queue.h" // for queue api access #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 "mb_m.h" // for modbus stack master types definition
#include "port.h" // for port callback functions and defines #include "port.h" // for port callback functions and defines
#include "mbutils.h" // for mbutils functions definition for stack callback #include "mbutils.h" // for mbutils functions definition for stack callback
@ -197,7 +198,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."); MB_MASTER_CHECK((mb_error == MB_ENOERR), ESP_ERR_INVALID_STATE, "mb stack disable failure.");
(void)vTaskDelete(mbm_opts->mbm_task_handle); (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_error = eMBMasterClose();
MB_MASTER_CHECK((mb_error == MB_ENOERR), ESP_ERR_INVALID_STATE, MB_MASTER_CHECK((mb_error == MB_ENOERR), ESP_ERR_INVALID_STATE,
@ -261,19 +264,16 @@ static esp_err_t mbc_tcp_master_send_request(mb_param_request_t* request, void*
eMBMasterReqErrCode mb_error = MB_MRE_MASTER_BUSY; eMBMasterReqErrCode mb_error = MB_MRE_MASTER_BUSY;
esp_err_t error = ESP_FAIL; 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_slave_addr = request->slave_addr;
uint8_t mb_command = request->command; uint8_t mb_command = request->command;
uint16_t mb_offset = request->reg_start; uint16_t mb_offset = request->reg_start;
uint16_t mb_size = request->reg_size; uint16_t mb_size = request->reg_size;
// Set the buffer for callback function processing of received data // 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_ptr = (uint8_t*)data_ptr;
mbm_opts->mbm_reg_buffer_size = mb_size; mbm_opts->mbm_reg_buffer_size = mb_size;
vMBMasterRunResRelease();
// Calls appropriate request function to send request and waits response // Calls appropriate request function to send request and waits response
switch(mb_command) switch(mb_command)
{ {
@ -323,7 +323,9 @@ static esp_err_t mbc_tcp_master_send_request(mb_param_request_t* request, void*
mb_error = MB_MRE_NO_REG; mb_error = MB_MRE_NO_REG;
break; break;
} }
} } else {
ESP_LOGD(TAG, "%s:MBC semaphore take fail.", __func__);
}
// Propagate the Modbus errors to higher level // Propagate the Modbus errors to higher level
switch(mb_error) switch(mb_error)
@ -350,10 +352,11 @@ static esp_err_t mbc_tcp_master_send_request(mb_param_request_t* request, void*
break; break;
default: 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; error = ESP_FAIL;
break; break;
} }
xSemaphoreGive( mbm_opts->mbm_sema );
return error; return error;
} }
@ -744,6 +747,10 @@ esp_err_t mbc_tcp_master_create(void** handler)
// Parameter change notification queue // Parameter change notification queue
mbm_opts->mbm_event_group = xEventGroupCreate(); mbm_opts->mbm_event_group = xEventGroupCreate();
MB_MASTER_CHECK((mbm_opts->mbm_event_group != NULL), ESP_ERR_NO_MEM, "mb event group error."); 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 // Create modbus controller task
status = xTaskCreate((void*)&modbus_tcp_master_task, status = xTaskCreate((void*)&modbus_tcp_master_task,
"modbus_tcp_master_task", "modbus_tcp_master_task",

View File

@ -235,7 +235,6 @@ void app_main(void)
int err = eMBSetSlaveID(comm_info.slave_addr, true, (uint8_t *)&ext_data, sizeof(ext_data)); int err = eMBSetSlaveID(comm_info.slave_addr, true, (uint8_t *)&ext_data, sizeof(ext_data));
if (!err) { 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); ESP_LOG_BUFFER_HEX_LEVEL("SET_SLAVE_ID", (void*)ext_data, sizeof(ext_data), ESP_LOG_WARN);
} else { } else {
ESP_LOGE("SET_SLAVE_ID", "Set slave ID fail, err=%d.", err); ESP_LOGE("SET_SLAVE_ID", "Set slave ID fail, err=%d.", err);