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
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
int "Modbus controller notification timeout (ms)"
range 0 200

View File

@ -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

View File

@ -53,8 +53,8 @@
#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 )
#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] = {0};
@ -93,7 +93,7 @@ eMBMasterFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen )
if( *usLen <= ( MB_FUNC_OTHER_REP_SLAVEID_BUF - 2 ) )
{
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) );
/* If an error occured convert it into a Modbus exception. */
if( eRegStatus != MB_ENOERR )
@ -129,7 +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);
ESP_LOG_BUFFER_HEX_LEVEL("MB_FHANDLER", (void*)ucMBSlaveID, usMBSlaveIDLen, ESP_LOG_DEBUG);
}
else
{
@ -145,7 +145,7 @@ eMBFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen )
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);
ESP_LOG_BUFFER_HEX_LEVEL("MB_FHANDLER", (void*)pucFrame, *usLen, ESP_LOG_DEBUG);
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
* 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. */
#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/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
@ -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,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;
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)
{
@ -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;
break;
}
} else {
ESP_LOGD(TAG, "%s:MBC semaphore take fail.", __func__);
}
// 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;
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;
}
@ -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
eMBErrorCode eMBRegInputCBSerialMaster(UCHAR * pucRegBuffer, USHORT usAddress,
USHORT usNRegs)
USHORT usNRegs)
{
MB_MASTER_CHECK((mbm_interface_ptr != NULL),
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 ((pucInputBuffer != NULL)
&& (usNRegs >= 1)
&& ((usRegInputNregs == usRegs) || !usAddress)) {
&& ((usRegInputNregs == usRegs) || (!usAddress))) {
while (usRegs > 0) {
_XFER_2_RD(pucInputBuffer, pucRegBuffer);
usRegs -= 1;
@ -700,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",

View File

@ -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
@ -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.");
(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 +264,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 +323,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 +352,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 +747,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",

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));
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);