Просмотр исходного кода

freemodbus: fix timer port to use esp_timer instead of group timer

aleks 4 лет назад
Родитель
Сommit
ee104f8de2

+ 5 - 35
components/freemodbus/Kconfig

@@ -193,44 +193,14 @@ menu "Modbus configuration"
                 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.
 
-    config FMB_TIMER_GROUP
-        int "Slave Timer group number"
-        range 0 1
-        default 0
-        help
-                Modbus slave Timer group number that is used for timeout measurement.
-
-    config FMB_TIMER_INDEX
-        int "Slave Timer index in the group"
-        range 0 1
-        default 0
-        help
-                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.
-
-    config FMB_TIMER_ISR_IN_IRAM
-        bool "Place timer interrupt handler into IRAM"
+    config FMB_TIMER_USE_ISR_DISPATCH_METHOD
+        bool "Modbus timer uses ISR dispatch method"
         default n
+        select ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
         select UART_ISR_IN_IRAM
         help
-                This option places Modbus timer IRQ handler into IRAM.
-                This allows to avoid delays related to processing of non-IRAM-safe interrupts
-                during a flash write operation (NVS updating a value, or some other
-                flash API which has to perform an read/write operation and disable CPU cache).
+                If this option is set the Modbus stack uses ISR dispatch method
+                to send timeout events from the callback function called from ISR.
                 This option has dependency with the UART_ISR_IN_IRAM option which places UART interrupt
                 handler into IRAM to prevent delays related to processing of UART events.
 

+ 8 - 0
components/freemodbus/port/port.h

@@ -40,6 +40,7 @@
 
 #include "freertos/FreeRTOS.h"
 #include "esp_log.h"                // for ESP_LOGE macro
+#include "esp_timer.h"
 #include "mbconfig.h"
 
 #define INLINE                      inline
@@ -87,6 +88,7 @@
 
 // Define number of timer reloads per 1 mS
 #define MB_TIMER_TICS_PER_MS            (20UL)
+#define MB_TIMER_TICK_TIME_US           (1000 / MB_TIMER_TICS_PER_MS) // 50uS = one discreet for timer
 
 #define MB_TCP_DEBUG                    (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) // Enable legacy debug output in TCP module.
 
@@ -142,6 +144,12 @@ typedef enum {
     MB_PORT_IPV6 = 1                      /*!< TCP IPV6 addressing */
 } eMBPortIpVer;
 
+typedef struct {
+    esp_timer_handle_t xTimerIntHandle;
+    USHORT usT35Ticks;
+    BOOL xTimerState;
+} xTimerContext_t;
+
 void vMBPortEnterCritical(void);
 void vMBPortExitCritical(void);
 

+ 5 - 0
components/freemodbus/port/portserial_m.c

@@ -85,9 +85,14 @@ static USHORT usMBMasterPortSerialRxPoll(size_t xEventSize)
             // Call the Modbus stack callback function and let it fill the stack buffers.
             xReadStatus = pxMBMasterFrameCBByteReceived(); // callback to receive FSM
         }
+
         // The buffer is transferred into Modbus stack and is not needed here any more
         uart_flush_input(ucUartNumber);
         ESP_LOGD(TAG, "Received data: %d(bytes in buffer)\n", (uint32_t)usCnt);
+#if !CONFIG_FMB_TIMER_PORT_ENABLED
+        vMBMasterSetCurTimerMode(MB_TMODE_T35);
+        pxMBMasterPortCBTimerExpired();
+#endif
     } else {
         ESP_LOGE(TAG, "%s: bRxState disabled but junk data (%d bytes) received. ", __func__, xEventSize);
     }

+ 49 - 69
components/freemodbus/port/porttimer.c

@@ -38,77 +38,54 @@
 #include "port.h"
 
 /* ----------------------- Modbus includes ----------------------------------*/
-#include "sdkconfig.h"
 #include "mb.h"
 #include "mbport.h"
-#include "driver/timer.h"
-#include "port_serial_slave.h"
 #include "sdkconfig.h"
 
 #if CONFIG_FMB_TIMER_PORT_ENABLED
 
-#define MB_US50_FREQ            (20000) // 20kHz 1/20000 = 50mks
-#define MB_DISCR_TIME_US        (50)    // 50uS = one discreet for timer
-
-#define MB_TIMER_PRESCALLER     ((TIMER_BASE_CLK / MB_US50_FREQ) - 1)
-#define MB_TIMER_SCALE          (TIMER_BASE_CLK / TIMER_DIVIDER)  // convert counter value to seconds
-#define MB_TIMER_DIVIDER        ((TIMER_BASE_CLK / 1000000UL) * MB_DISCR_TIME_US - 1) // divider for 50uS
-#define MB_TIMER_WITH_RELOAD    (1)
+static const char *TAG = "MBS_TIMER";
 
-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 timer_isr_handle_t xTimerIntHandle;                      // Timer interrupt handle
+static xTimerContext_t* pxTimerContext = NULL;
 
 /* ----------------------- Start implementation -----------------------------*/
-static void IRAM_ATTR vTimerGroupIsr(void *param)
+static void IRAM_ATTR vTimerAlarmCBHandler(void *param)
 {
-    assert((int)param == usTimerIndex);
-    // Retrieve the counter value from the timer that reported the interrupt
-    timer_group_clr_intr_status_in_isr(usTimerGroupIndex, usTimerIndex);
-    (void)pxMBPortCBTimerExpired(); // Timer callback function
-    // Enable alarm
-    timer_group_enable_alarm_in_isr(usTimerGroupIndex, usTimerIndex);
+    pxMBPortCBTimerExpired(); // Timer expired callback function
+    pxTimerContext->xTimerState = TRUE;
+    ESP_EARLY_LOGD(TAG, "Slave timeout triggered.");
 }
 #endif
 
-BOOL xMBPortTimersInit(USHORT usTim1Timerout50us)
+BOOL xMBPortTimersInit(USHORT usTimeOut50us)
 {
 #if CONFIG_FMB_TIMER_PORT_ENABLED
-    MB_PORT_CHECK((usTim1Timerout50us > 0), FALSE,
+    MB_PORT_CHECK((usTimeOut50us > 0), FALSE,
             "Modbus timeout discreet is incorrect.");
-    esp_err_t xErr;
-    timer_config_t config = {
-        .alarm_en = TIMER_ALARM_EN,
-        .auto_reload = MB_TIMER_WITH_RELOAD,
-        .counter_dir = TIMER_COUNT_UP,
-        .divider = MB_TIMER_PRESCALLER,
-        .intr_type = TIMER_INTR_LEVEL,
-        .counter_en = TIMER_PAUSE,
+    MB_PORT_CHECK(!pxTimerContext, FALSE,
+                "Modbus timer is already created.");
+    pxTimerContext = calloc(1, sizeof(xTimerContext_t));
+    if (!pxTimerContext) {
+        return FALSE;
+    }
+    pxTimerContext->xTimerIntHandle = NULL;
+    // Save timer reload value for Modbus T35 period
+    pxTimerContext->usT35Ticks = usTimeOut50us;
+    esp_timer_create_args_t xTimerConf = {
+        .callback = vTimerAlarmCBHandler,
+        .arg = NULL,
+#if CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD
+        .dispatch_method = ESP_TIMER_ISR,
+#else
+        .dispatch_method = ESP_TIMER_TASK,
+#endif
+        .name = "MBS_T35timer"
     };
-    // Configure timer
-    xErr = timer_init(usTimerGroupIndex, usTimerIndex, &config);
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-            "timer init failure, timer_init() returned (0x%x).", xErr);
-    // Stop timer counter
-    xErr = timer_pause(usTimerGroupIndex, usTimerIndex);
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                    "stop timer failure, timer_pause() returned (0x%x).", xErr);
-    // Reset counter value
-    xErr = timer_set_counter_value(usTimerGroupIndex, usTimerIndex, 0x00000000ULL);
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                    "timer set value failure, timer_set_counter_value() returned (0x%x).", xErr);
-    // wait3T5_us = 35 * 11 * 100000 / baud; // the 3.5T symbol time for baudrate
-    // Set alarm value for usTim1Timerout50us * 50uS
-    xErr = timer_set_alarm_value(usTimerGroupIndex, usTimerIndex, (uint32_t)(usTim1Timerout50us));
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                    "failure to set alarm failure, timer_set_alarm_value() returned (0x%x).",
-                    (uint32_t)xErr);
-    // Register ISR for timer
-    xErr = timer_isr_register(usTimerGroupIndex, usTimerIndex, vTimerGroupIsr,
-                                (void*)(uint32_t)usTimerIndex, MB_PORT_TIMER_ISR_FLAG, &xTimerIntHandle);
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                    "timer set value failure, timer_isr_register() returned (0x%x).",
-                    (uint32_t)xErr);
+    // Create Modbus timer
+    esp_err_t xErr = esp_timer_create(&xTimerConf, &(pxTimerContext->xTimerIntHandle));
+    if (xErr) {
+        return FALSE;
+    }
 #endif
     return TRUE;
 }
@@ -116,10 +93,12 @@ BOOL xMBPortTimersInit(USHORT usTim1Timerout50us)
 void vMBPortTimersEnable(void)
 {
 #if CONFIG_FMB_TIMER_PORT_ENABLED
-    ESP_ERROR_CHECK(timer_pause(usTimerGroupIndex, usTimerIndex));
-    ESP_ERROR_CHECK(timer_set_counter_value(usTimerGroupIndex, usTimerIndex, 0ULL));
-    ESP_ERROR_CHECK(timer_enable_intr(usTimerGroupIndex, usTimerIndex));
-    ESP_ERROR_CHECK(timer_start(usTimerGroupIndex, usTimerIndex));
+    MB_PORT_CHECK((pxTimerContext && pxTimerContext->xTimerIntHandle), ; ,
+                                "timer is not initialized.");
+    uint64_t xToutUs = (pxTimerContext->usT35Ticks * MB_TIMER_TICK_TIME_US);
+    esp_timer_stop(pxTimerContext->xTimerIntHandle);
+    esp_timer_start_once(pxTimerContext->xTimerIntHandle, xToutUs);
+    pxTimerContext->xTimerState = FALSE;
 #endif
 }
 
@@ -127,21 +106,22 @@ void MB_PORT_ISR_ATTR
 vMBPortTimersDisable(void)
 {
 #if CONFIG_FMB_TIMER_PORT_ENABLED
-    if( (BOOL)xPortInIsrContext() ) {
-        timer_group_set_counter_enable_in_isr(usTimerGroupIndex, usTimerIndex, TIMER_PAUSE);
-    } else {
-        ESP_ERROR_CHECK(timer_pause(usTimerGroupIndex, usTimerIndex));
-        ESP_ERROR_CHECK(timer_set_counter_value(usTimerGroupIndex, usTimerIndex, 0ULL));
-        // Disable timer interrupt
-        ESP_ERROR_CHECK(timer_disable_intr(usTimerGroupIndex, usTimerIndex));
-    }
+    // Disable timer alarm
+    esp_timer_stop(pxTimerContext->xTimerIntHandle);
 #endif
 }
 
 void vMBPortTimerClose(void)
 {
-#ifdef CONFIG_FMB_TIMER_PORT_ENABLED
-    ESP_ERROR_CHECK(timer_deinit(usTimerGroupIndex, usTimerIndex));
-    ESP_ERROR_CHECK(esp_intr_free(xTimerIntHandle));
+#if CONFIG_FMB_TIMER_PORT_ENABLED
+    // Delete active timer
+    if (pxTimerContext) {
+        if (pxTimerContext->xTimerIntHandle) {
+            esp_timer_stop(pxTimerContext->xTimerIntHandle);
+            esp_timer_delete(pxTimerContext->xTimerIntHandle);
+        }
+        free(pxTimerContext);
+        pxTimerContext = NULL;
+    }
 #endif
 }

+ 58 - 103
components/freemodbus/port/porttimer_m.c

@@ -32,158 +32,113 @@
 /* ----------------------- Modbus includes ----------------------------------*/
 #include "mb_m.h"
 #include "mbport.h"
-#include "port_serial_master.h"
 #include "sdkconfig.h"
 
-#define MB_US50_FREQ            (20000) // 20kHz 1/20000 = 50mks
-#define MB_TICK_TIME_US         (50)    // 50uS = one tick for timer
-
-#define MB_TIMER_PRESCALLER     ((TIMER_BASE_CLK / MB_US50_FREQ) - 1)
-#define MB_TIMER_SCALE          (TIMER_BASE_CLK / TIMER_DIVIDER)
-#define MB_TIMER_DIVIDER        ((TIMER_BASE_CLK / 1000000UL) * MB_TICK_TIME_US - 1) // divider for 50uS
-#define MB_TIMER_WITH_RELOAD    (1)
+static const char *TAG = "MBM_TIMER";
 
 /* ----------------------- Variables ----------------------------------------*/
-static USHORT usT35TimeOut50us;
-
-// Initialize Modbus Timer group and 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 xTimerContext_t* pxTimerContext = NULL;
 
-/* ----------------------- static functions ---------------------------------*/
-static void IRAM_ATTR vTimerGroupIsr(void *param)
+/* ----------------------- Start implementation -----------------------------*/
+static void IRAM_ATTR vTimerAlarmCBHandler(void *param)
 {
-    assert((int)param == usTimerIndex);
-    // Retrieve the the counter value from the timer that reported the interrupt
-    timer_group_clr_intr_status_in_isr(usTimerGroupIndex, usTimerIndex);
-    (void)pxMBMasterPortCBTimerExpired(); // Timer expired callback function
-    // Enable alarm
-    timer_group_enable_alarm_in_isr(usTimerGroupIndex, usTimerIndex);
+    pxMBMasterPortCBTimerExpired(); // Timer expired callback function
+    pxTimerContext->xTimerState = TRUE;
+    ESP_EARLY_LOGD(TAG, "Timer mode: (%d) triggered", xMBMasterGetCurTimerMode());
 }
 
-/* ----------------------- Start implementation -----------------------------*/
 BOOL xMBMasterPortTimersInit(USHORT usTimeOut50us)
 {
     MB_PORT_CHECK((usTimeOut50us > 0), FALSE,
             "Modbus timeout discreet is incorrect.");
+    MB_PORT_CHECK(!pxTimerContext, FALSE,
+                "Modbus timer is already created.");
+    pxTimerContext = calloc(1, sizeof(xTimerContext_t));
+    if (!pxTimerContext) {
+        return FALSE;
+    }
+    pxTimerContext->xTimerIntHandle = NULL;
     // Save timer reload value for Modbus T35 period
-    usT35TimeOut50us = usTimeOut50us;
-    esp_err_t xErr;
-    timer_config_t config = {
-        .alarm_en = TIMER_ALARM_EN,
-        .auto_reload = MB_TIMER_WITH_RELOAD,
-        .counter_dir = TIMER_COUNT_UP,
-        .divider = MB_TIMER_PRESCALLER,
-        .intr_type = TIMER_INTR_LEVEL,
-        .counter_en = TIMER_PAUSE,
+    pxTimerContext->usT35Ticks = usTimeOut50us;
+    esp_timer_create_args_t xTimerConf = {
+        .callback = vTimerAlarmCBHandler,
+        .arg = NULL,
+#if CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD
+        .dispatch_method = ESP_TIMER_ISR,
+#else
+        .dispatch_method = ESP_TIMER_TASK,
+#endif
+        .name = "MBM_T35timer"
     };
-    // Configure timer
-    xErr = timer_init(usTimerGroupIndex, usTimerIndex, &config);
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-            "timer init failure, timer_init() returned (0x%x).", (uint32_t)xErr);
-    // Stop timer counter
-    xErr = timer_pause(usTimerGroupIndex, usTimerIndex);
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                    "stop timer failure, timer_pause() returned (0x%x).", (uint32_t)xErr);
-    // Reset counter value
-    xErr = timer_set_counter_value(usTimerGroupIndex, usTimerIndex, 0x00000000ULL);
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                    "timer set value failure, timer_set_counter_value() returned (0x%x).",
-                    (uint32_t)xErr);
-    // wait3T5_us = 35 * 11 * 100000 / baud; // the 3.5T symbol time for baudrate
-    // Set alarm value for usTimeOut50us * 50uS
-    xErr = timer_set_alarm_value(usTimerGroupIndex, usTimerIndex, (uint32_t)(usTimeOut50us));
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                    "failure to set alarm failure, timer_set_alarm_value() returned (0x%x).",
-                    (uint32_t)xErr);
-    // Register ISR for timer
-    xErr = timer_isr_register(usTimerGroupIndex, usTimerIndex,
-                                vTimerGroupIsr, (void*)(uint32_t)usTimerIndex, MB_PORT_TIMER_ISR_FLAG, &xTimerIntHandle);
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                    "timer set value failure, timer_isr_register() returned (0x%x).",
-                    (uint32_t)xErr);
+    // Create Modbus timer
+    esp_err_t xErr = esp_timer_create(&xTimerConf, &(pxTimerContext->xTimerIntHandle));
+    if (xErr) {
+        return FALSE;
+    }
     return TRUE;
 }
 
-// Set alarm value for usTimerTimeOut50us * 50uS
-static BOOL xMBMasterPortTimersEnable(USHORT usTimerTics50us)
+// Set timer alarm value
+static BOOL xMBMasterPortTimersEnable(uint64_t xToutUs)
 {
-    MB_PORT_CHECK((usTimerTics50us > 0), FALSE,
-                            "incorrect tick value for timer = (0x%x).",
-                            (uint32_t)usTimerTics50us);
-    esp_err_t xErr;
-    xErr = timer_pause(usTimerGroupIndex, usTimerIndex); // stop timer
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                        "timer pause failure, timer_pause() returned (0x%x).",
-                        (uint32_t)xErr);
-    xErr = timer_set_counter_value(usTimerGroupIndex, usTimerIndex, 0ULL); // reset timer
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                        "timer set counter failure, timer_set_counter_value() returned (0x%x).",
-                        (uint32_t)xErr);
-    // Set alarm value to number of 50uS ticks
-    xErr = timer_set_alarm_value(usTimerGroupIndex, usTimerIndex,
-                                            (uint32_t)(usTimerTics50us));
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                    "timer set alarm failure, timer_set_alarm_value() returned (0x%x).",
-                    (uint32_t)xErr);
-    xErr = timer_enable_intr(usTimerGroupIndex, usTimerIndex);
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                            "timer enable interrupt failure, timer_enable_intr() returned (0x%x).",
-                            (uint32_t)xErr);
-    xErr = timer_start(usTimerGroupIndex, usTimerIndex); // start timer
-    MB_PORT_CHECK((xErr == ESP_OK), FALSE,
-                            "timer start failure, timer_start() returned (0x%x).",
-                            (uint32_t)xErr);
+    MB_PORT_CHECK(pxTimerContext && (pxTimerContext->xTimerIntHandle), FALSE,
+                                "timer is not initialized.");
+    MB_PORT_CHECK((xToutUs > 0), FALSE,
+                            "incorrect tick value for timer = (0x%llu).", xToutUs);
+    esp_timer_stop(pxTimerContext->xTimerIntHandle);
+    esp_timer_start_once(pxTimerContext->xTimerIntHandle, xToutUs);
+    pxTimerContext->xTimerState = FALSE;
     return TRUE;
 }
 
 void vMBMasterPortTimersT35Enable(void)
 {
-    USHORT usTimerTicks = usT35TimeOut50us;
+#if CONFIG_FMB_TIMER_PORT_ENABLED
+    uint64_t xToutUs = (pxTimerContext->usT35Ticks * MB_TIMER_TICK_TIME_US);
 
     // Set current timer mode, don't change it.
     vMBMasterSetCurTimerMode(MB_TMODE_T35);
-    // Set timer period
-    (void)xMBMasterPortTimersEnable(usTimerTicks);
+    // Set timer alarm
+    (void)xMBMasterPortTimersEnable(xToutUs);
+#endif
 }
 
 void vMBMasterPortTimersConvertDelayEnable(void)
 {
     // Covert time in milliseconds into ticks
-    USHORT usTimerTicks = ((MB_MASTER_DELAY_MS_CONVERT * 1000) / MB_TICK_TIME_US);
+    uint64_t xToutUs = (MB_MASTER_DELAY_MS_CONVERT * 1000);
 
     // Set current timer mode
     vMBMasterSetCurTimerMode(MB_TMODE_CONVERT_DELAY);
     ESP_LOGD(MB_PORT_TAG,"%s Convert delay enable.", __func__);
-    (void)xMBMasterPortTimersEnable(usTimerTicks);
+    (void)xMBMasterPortTimersEnable(xToutUs);
 }
 
 void vMBMasterPortTimersRespondTimeoutEnable(void)
 {
-    USHORT usTimerTicks = (MB_MASTER_TIMEOUT_MS_RESPOND * 1000 / MB_TICK_TIME_US);
+    uint64_t xToutUs = (MB_MASTER_TIMEOUT_MS_RESPOND * 1000);
 
     vMBMasterSetCurTimerMode(MB_TMODE_RESPOND_TIMEOUT);
     ESP_LOGD(MB_PORT_TAG,"%s Respond enable timeout.", __func__);
-    (void)xMBMasterPortTimersEnable(usTimerTicks);
+    (void)xMBMasterPortTimersEnable(xToutUs);
 }
 
 void MB_PORT_ISR_ATTR
 vMBMasterPortTimersDisable()
 {
-    if( (BOOL)xPortInIsrContext() ) {
-        timer_group_set_counter_enable_in_isr(usTimerGroupIndex, usTimerIndex, TIMER_PAUSE);
-    } else {
-        // Stop timer and then reload timer counter value
-        ESP_ERROR_CHECK(timer_pause(usTimerGroupIndex, usTimerIndex));
-        ESP_ERROR_CHECK(timer_set_counter_value(usTimerGroupIndex, usTimerIndex, 0ULL));
-        // Disable timer interrupt
-        ESP_ERROR_CHECK(timer_disable_intr(usTimerGroupIndex, usTimerIndex));
-    }
+    // Disable timer alarm
+    esp_timer_stop(pxTimerContext->xTimerIntHandle);
 }
 
 void vMBMasterPortTimerClose(void)
 {
-    ESP_ERROR_CHECK(timer_deinit(usTimerGroupIndex, usTimerIndex));
-    ESP_ERROR_CHECK(esp_intr_free(xTimerIntHandle));
+    // Delete active timer
+    if (pxTimerContext) {
+        if (pxTimerContext->xTimerIntHandle) {
+            esp_timer_stop(pxTimerContext->xTimerIntHandle);
+            esp_timer_delete(pxTimerContext->xTimerIntHandle);
+        }
+        free(pxTimerContext);
+        pxTimerContext = NULL;
+    }
 }

+ 1 - 0
examples/protocols/modbus/serial/mb_master/sdkconfig.defaults

@@ -9,3 +9,4 @@ CONFIG_FMB_TIMER_INDEX=0
 CONFIG_FMB_TIMER_ISR_IN_IRAM=y
 CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200
 CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150
+CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y

+ 1 - 0
examples/protocols/modbus/serial/mb_slave/sdkconfig.defaults

@@ -8,3 +8,4 @@ CONFIG_FMB_TIMER_PORT_ENABLED=y
 CONFIG_FMB_TIMER_GROUP=0
 CONFIG_FMB_TIMER_INDEX=0
 CONFIG_FMB_TIMER_ISR_IN_IRAM=y
+CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y

+ 1 - 0
examples/protocols/modbus/tcp/mb_tcp_master/sdkconfig.defaults

@@ -17,3 +17,4 @@ CONFIG_FMB_TIMER_ISR_IN_IRAM=y
 CONFIG_MB_MDNS_IP_RESOLVER=n
 CONFIG_MB_SLAVE_IP_FROM_STDIN=y
 CONFIG_EXAMPLE_CONNECT_IPV6=n
+CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y

+ 1 - 0
examples/protocols/modbus/tcp/mb_tcp_slave/sdkconfig.defaults

@@ -19,3 +19,4 @@ CONFIG_MB_SLAVE_IP_FROM_STDIN=y
 CONFIG_MB_SLAVE_ADDR=1
 CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y
 CONFIG_EXAMPLE_CONNECT_IPV6=n
+CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y