mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-03 20:54:32 +02:00
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:
@@ -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
|
||||||
|
@@ -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 ---------------------------------*/
|
||||||
|
@@ -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__); \
|
||||||
|
@@ -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( );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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));
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user