Merge branch 'bugfix/modbus_allow_master_slave_work_simultaneously_v40' into 'release/v4.0'

freemodbus: fix issues when modbus master and slave work simultaneously (backport v4.0)

See merge request espressif/esp-idf!14966
This commit is contained in:
Michael (XIAO Xufeng)
2021-09-09 17:58:16 +00:00
8 changed files with 49 additions and 47 deletions

View File

@@ -102,24 +102,39 @@ menu "Modbus configuration"
Modbus stack event processing time. Modbus stack event processing time.
config FMB_TIMER_PORT_ENABLED config FMB_TIMER_PORT_ENABLED
bool "Modbus slave stack use timer for 3.5T symbol time measurement" bool "Modbus stack use timer for 3.5T symbol time measurement"
default y default y
help help
If this option is set the Modbus stack uses timer for T3.5 time measurement. If this option is set the Modbus stack uses timer for T3.5 time measurement.
Else the internal UART TOUT timeout is used for 3.5T symbol time measurement. Else the internal UART TOUT timeout is used for 3.5T symbol time measurement.
config FMB_TIMER_GROUP config FMB_TIMER_GROUP
int "Modbus Timer group number" int "Slave Timer group number"
range 0 1 range 0 1
default 0 default 0
help help
Modbus Timer group number that is used for timeout measurement. Modbus slave Timer group number that is used for timeout measurement.
config FMB_TIMER_INDEX config FMB_TIMER_INDEX
int "Modbus Timer index in the group" int "Slave Timer index in the group"
range 0 1 range 0 1
default 0 default 0
help help
Modbus Timer Index in the group that is used for timeout measurement. Modbus slave Timer Index in the group that is used for timeout measurement.
config FMB_MASTER_TIMER_GROUP
int "Master Timer group number"
range 0 1
default FMB_TIMER_GROUP
help
Modbus master Timer group number that is used for timeout measurement.
config FMB_MASTER_TIMER_INDEX
int "Master Timer index"
range 0 1
default FMB_TIMER_INDEX
help
Modbus master Timer Index in the group that is used for timeout measurement.
Note: Modbus master and slave should have different timer index to be able to work simultaneously.
endmenu endmenu

View File

@@ -54,7 +54,7 @@
#endif #endif
#ifndef MB_PORT_HAS_CLOSE #ifndef MB_PORT_HAS_CLOSE
#define MB_PORT_HAS_CLOSE 0 #define MB_PORT_HAS_CLOSE 1
#endif #endif
/* ----------------------- Static variables ---------------------------------*/ /* ----------------------- Static variables ---------------------------------*/

View File

@@ -28,6 +28,8 @@
#define MB_PORT_TAG "MB_PORT_COMMON" #define MB_PORT_TAG "MB_PORT_COMMON"
#define MB_PORT_HAS_CLOSE (1) // Define to explicitly close port on destroy
#define MB_PORT_CHECK(a, ret_val, str, ...) \ #define MB_PORT_CHECK(a, ret_val, str, ...) \
if (!(a)) { \ if (!(a)) { \
ESP_LOGE(MB_PORT_TAG, "%s(%u): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ ESP_LOGE(MB_PORT_TAG, "%s(%u): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \

View File

@@ -55,25 +55,9 @@
/* ----------------------- Modbus includes ----------------------------------*/ /* ----------------------- Modbus includes ----------------------------------*/
/* ----------------------- Variables ----------------------------------------*/ /* ----------------------- Variables ----------------------------------------*/
static UCHAR ucPortMode = 0;
/* ----------------------- Start implementation -----------------------------*/ /* ----------------------- Start implementation -----------------------------*/
UCHAR
ucMBPortGetMode( void )
{
return ucPortMode;
}
void
vMBPortSetMode( UCHAR ucMode )
{
ENTER_CRITICAL_SECTION();
ucPortMode = ucMode;
EXIT_CRITICAL_SECTION();
}
void void
vMBMasterPortClose( void ) vMBMasterPortClose( void )
{ {
@@ -84,4 +68,3 @@ vMBMasterPortClose( void )
vMBMasterPortTimerClose( ); vMBMasterPortTimerClose( );
vMBMasterPortEventClose( ); vMBMasterPortEventClose( );
} }

View File

@@ -51,7 +51,7 @@
#include "sdkconfig.h" #include "sdkconfig.h"
#include "port_serial_slave.h" #include "port_serial_slave.h"
#ifdef CONFIG_FMB_TIMER_PORT_ENABLED #if CONFIG_FMB_TIMER_PORT_ENABLED
#define MB_US50_FREQ (20000) // 20kHz 1/20000 = 50mks #define MB_US50_FREQ (20000) // 20kHz 1/20000 = 50mks
#define MB_DISCR_TIME_US (50) // 50uS = one discreet for timer #define MB_DISCR_TIME_US (50) // 50uS = one discreet for timer
@@ -63,6 +63,7 @@
static const USHORT usTimerIndex = CONFIG_FMB_TIMER_INDEX; // Modbus Timer index used by stack static const USHORT usTimerIndex = CONFIG_FMB_TIMER_INDEX; // Modbus Timer index used by stack
static const USHORT usTimerGroupIndex = CONFIG_FMB_TIMER_GROUP; // Modbus Timer group index used by stack static const USHORT usTimerGroupIndex = CONFIG_FMB_TIMER_GROUP; // Modbus Timer group index used by stack
static timer_isr_handle_t xTimerIntHandle; // Timer interrupt handle
static timg_dev_t *MB_TG[2] = {&TIMERG0, &TIMERG1}; static timg_dev_t *MB_TG[2] = {&TIMERG0, &TIMERG1};
@@ -82,7 +83,7 @@ static void IRAM_ATTR vTimerGroupIsr(void *param)
BOOL xMBPortTimersInit(USHORT usTim1Timerout50us) BOOL xMBPortTimersInit(USHORT usTim1Timerout50us)
{ {
#ifdef CONFIG_FMB_TIMER_PORT_ENABLED #if CONFIG_FMB_TIMER_PORT_ENABLED
MB_PORT_CHECK((usTim1Timerout50us > 0), FALSE, MB_PORT_CHECK((usTim1Timerout50us > 0), FALSE,
"Modbus timeout discreet is incorrect."); "Modbus timeout discreet is incorrect.");
esp_err_t xErr; esp_err_t xErr;
@@ -113,7 +114,7 @@ BOOL xMBPortTimersInit(USHORT usTim1Timerout50us)
"failure to set alarm failure, timer_set_alarm_value() returned (0x%x).", "failure to set alarm failure, timer_set_alarm_value() returned (0x%x).",
(uint32_t)xErr); (uint32_t)xErr);
// Register ISR for timer // Register ISR for timer
xErr = timer_isr_register(usTimerGroupIndex, usTimerIndex, vTimerGroupIsr, NULL, ESP_INTR_FLAG_IRAM, NULL); xErr = timer_isr_register(usTimerGroupIndex, usTimerIndex, vTimerGroupIsr, NULL, ESP_INTR_FLAG_LOWMED, &xTimerIntHandle);
MB_PORT_CHECK((xErr == ESP_OK), FALSE, MB_PORT_CHECK((xErr == ESP_OK), FALSE,
"timer set value failure, timer_isr_register() returned (0x%x).", "timer set value failure, timer_isr_register() returned (0x%x).",
(uint32_t)xErr); (uint32_t)xErr);
@@ -123,7 +124,7 @@ BOOL xMBPortTimersInit(USHORT usTim1Timerout50us)
void vMBPortTimersEnable() void vMBPortTimersEnable()
{ {
#ifdef CONFIG_FMB_TIMER_PORT_ENABLED #if CONFIG_FMB_TIMER_PORT_ENABLED
ESP_ERROR_CHECK(timer_pause(usTimerGroupIndex, usTimerIndex)); ESP_ERROR_CHECK(timer_pause(usTimerGroupIndex, usTimerIndex));
ESP_ERROR_CHECK(timer_set_counter_value(usTimerGroupIndex, usTimerIndex, 0ULL)); ESP_ERROR_CHECK(timer_set_counter_value(usTimerGroupIndex, usTimerIndex, 0ULL));
ESP_ERROR_CHECK(timer_enable_intr(usTimerGroupIndex, usTimerIndex)); ESP_ERROR_CHECK(timer_enable_intr(usTimerGroupIndex, usTimerIndex));
@@ -133,7 +134,7 @@ void vMBPortTimersEnable()
void vMBPortTimersDisable() void vMBPortTimersDisable()
{ {
#ifdef CONFIG_FMB_TIMER_PORT_ENABLED #if CONFIG_FMB_TIMER_PORT_ENABLED
ESP_ERROR_CHECK(timer_pause(usTimerGroupIndex, usTimerIndex)); ESP_ERROR_CHECK(timer_pause(usTimerGroupIndex, usTimerIndex));
ESP_ERROR_CHECK(timer_set_counter_value(usTimerGroupIndex, usTimerIndex, 0ULL)); ESP_ERROR_CHECK(timer_set_counter_value(usTimerGroupIndex, usTimerIndex, 0ULL));
// Disable timer interrupt // Disable timer interrupt
@@ -143,9 +144,10 @@ void vMBPortTimersDisable()
void vMBPortTimerClose() void vMBPortTimerClose()
{ {
#ifdef CONFIG_FMB_TIMER_PORT_ENABLED #if CONFIG_FMB_TIMER_PORT_ENABLED
ESP_ERROR_CHECK(timer_pause(usTimerGroupIndex, usTimerIndex)); ESP_ERROR_CHECK(timer_pause(usTimerGroupIndex, usTimerIndex));
ESP_ERROR_CHECK(timer_disable_intr(usTimerGroupIndex, usTimerIndex)); ESP_ERROR_CHECK(timer_disable_intr(usTimerGroupIndex, usTimerIndex));
ESP_ERROR_CHECK(esp_intr_free(xTimerIntHandle));
#endif #endif
} }

View File

@@ -49,17 +49,15 @@
#define MB_TIMER_DIVIDER ((TIMER_BASE_CLK / 1000000UL) * MB_TICK_TIME_US - 1) // divider for 50uS #define MB_TIMER_DIVIDER ((TIMER_BASE_CLK / 1000000UL) * MB_TICK_TIME_US - 1) // divider for 50uS
#define MB_TIMER_WITH_RELOAD (1) #define MB_TIMER_WITH_RELOAD (1)
// Timer group and timer number to measure time (configurable in KConfig)
#define MB_TIMER_INDEX CONFIG_FMB_TIMER_INDEX
#define MB_TIMER_GROUP CONFIG_FMB_TIMER_GROUP
#define MB_TIMER_IO_LED 0 #define MB_TIMER_IO_LED 0
/* ----------------------- Variables ----------------------------------------*/ /* ----------------------- Variables ----------------------------------------*/
static USHORT usT35TimeOut50us; static USHORT usT35TimeOut50us;
static const USHORT usTimerIndex = MB_TIMER_INDEX; // Initialize Modbus Timer index used by stack, // Initialize Modbus Timer group and index used by stack
static const USHORT usTimerGroupIndex = MB_TIMER_GROUP; // Timer group index used by stack static const USHORT usTimerIndex = CONFIG_FMB_MASTER_TIMER_INDEX;
static const USHORT usTimerGroupIndex = CONFIG_FMB_MASTER_TIMER_GROUP;
static timer_isr_handle_t xTimerIntHandle; // Timer interrupt handle
static timg_dev_t *MB_TG[2] = { &TIMERG0, &TIMERG1 }; static timg_dev_t *MB_TG[2] = { &TIMERG0, &TIMERG1 };
@@ -115,7 +113,7 @@ BOOL xMBMasterPortTimersInit(USHORT usTimeOut50us)
(uint32_t)xErr); (uint32_t)xErr);
// Register ISR for timer // Register ISR for timer
xErr = timer_isr_register(usTimerGroupIndex, usTimerIndex, xErr = timer_isr_register(usTimerGroupIndex, usTimerIndex,
vTimerGroupIsr, NULL, ESP_INTR_FLAG_IRAM, NULL); vTimerGroupIsr, NULL, ESP_INTR_FLAG_LOWMED, &xTimerIntHandle);
MB_PORT_CHECK((xErr == ESP_OK), FALSE, MB_PORT_CHECK((xErr == ESP_OK), FALSE,
"timer set value failure, timer_isr_register() returned (0x%x).", "timer set value failure, timer_isr_register() returned (0x%x).",
(uint32_t)xErr); (uint32_t)xErr);
@@ -151,7 +149,7 @@ static BOOL xMBMasterPortTimersEnable(USHORT usTimerTics50us)
MB_PORT_CHECK((xErr == ESP_OK), FALSE, MB_PORT_CHECK((xErr == ESP_OK), FALSE,
"timer start failure, timer_start() returned (0x%x).", "timer start failure, timer_start() returned (0x%x).",
(uint32_t)xErr); (uint32_t)xErr);
//ESP_LOGD(MB_PORT_TAG,"%s Init timer.", __func__);
return TRUE; return TRUE;
} }
@@ -198,4 +196,5 @@ void vMBMasterPortTimerClose()
{ {
ESP_ERROR_CHECK(timer_pause(usTimerGroupIndex, usTimerIndex)); ESP_ERROR_CHECK(timer_pause(usTimerGroupIndex, usTimerIndex));
ESP_ERROR_CHECK(timer_disable_intr(usTimerGroupIndex, usTimerIndex)); ESP_ERROR_CHECK(timer_disable_intr(usTimerGroupIndex, usTimerIndex));
ESP_ERROR_CHECK(esp_intr_free(xTimerIntHandle));
} }

View File

@@ -141,6 +141,7 @@ static esp_err_t mbc_serial_master_destroy(void)
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).", (uint32_t)mb_error); "mb stack close failure returned (0x%x).", (uint32_t)mb_error);
free(mbm_interface_ptr); // free the memory allocated for options free(mbm_interface_ptr); // free the memory allocated for options
mbm_interface_ptr = NULL;
return ESP_OK; return ESP_OK;
} }

View File

@@ -28,7 +28,7 @@
#include "port_serial_slave.h" #include "port_serial_slave.h"
// Shared pointer to interface structure // Shared pointer to interface structure
static mb_slave_interface_t* mbs_interface_ptr = NULL; // &default_interface_inst; static mb_slave_interface_t* mbs_interface_ptr = NULL;
// Modbus task function // Modbus task function
static void modbus_slave_task(void *pvParameters) static void modbus_slave_task(void *pvParameters)
@@ -129,7 +129,7 @@ static esp_err_t mbc_serial_slave_destroy(void)
MB_SLAVE_CHECK((mb_error == MB_ENOERR), ESP_ERR_INVALID_STATE, MB_SLAVE_CHECK((mb_error == MB_ENOERR), ESP_ERR_INVALID_STATE,
"mb stack close failure returned (0x%x).", (uint32_t)mb_error); "mb stack close failure returned (0x%x).", (uint32_t)mb_error);
free(mbs_interface_ptr); free(mbs_interface_ptr);
mbs_interface_ptr = NULL;
return ESP_OK; return ESP_OK;
} }