From 3689bc6259b5e5f9702351f6fc72e6b7367689b7 Mon Sep 17 00:00:00 2001 From: Alex Lisitsyn Date: Mon, 23 Sep 2024 18:59:08 +0800 Subject: [PATCH] modbus master - slave tcp port fix close connections on destroy --- freemodbus/tcp_master/port/port_tcp_master.c | 15 +++++++++------ freemodbus/tcp_slave/port/port_tcp_slave.c | 20 +++++++++++--------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/freemodbus/tcp_master/port/port_tcp_master.c b/freemodbus/tcp_master/port/port_tcp_master.c index ff8930d..a1ca304 100644 --- a/freemodbus/tcp_master/port/port_tcp_master.c +++ b/freemodbus/tcp_master/port/port_tcp_master.c @@ -235,8 +235,6 @@ static BOOL xMBTCPPortMasterCloseConnection(MbSlaveInfo_t *pxInfo) static void xMBTCPPortMasterShutdown(void) { - xSemaphoreGive(xShutdownSema); - for (USHORT ucCnt = 0; ucCnt < MB_TCP_PORT_MAX_CONN; ucCnt++) { MbSlaveInfo_t* pxInfo = xMbPortConfig.pxMbSlaveInfo[ucCnt]; if (pxInfo) { @@ -245,12 +243,15 @@ static void xMBTCPPortMasterShutdown(void) free(pxInfo->pucRcvBuf); } free(pxInfo); + ESP_LOGD(TAG,"Close slave instance: %p", xMbPortConfig.pxMbSlaveInfo[ucCnt]); xMbPortConfig.pxMbSlaveInfo[ucCnt] = NULL; } } free(xMbPortConfig.pxMbSlaveInfo); - vTaskDelete(NULL); - xMbPortConfig.xMbTcpTaskHandle = NULL; + xMbPortConfig.pxMbSlaveInfo = NULL; + xSemaphoreGive(xShutdownSema); + ESP_LOGD(TAG,"Shutdown the port task."); + vTaskSuspend(NULL); } void vMBTCPPortMasterSetNetOpt(void *pvNetIf, eMBPortIpVer xIpVersion, eMBPortProto xProto) @@ -918,14 +919,16 @@ void vMBMasterTCPPortDisable(void) // that were allocated on the stack of the task we're going to delete xShutdownSema = xSemaphoreCreateBinary(); // if no semaphore (alloc issues) or couldn't acquire it, just delete the task - if (xShutdownSema == NULL || xSemaphoreTake(xShutdownSema, pdMS_TO_TICKS(MB_SHDN_WAIT_TOUT_MS)) != pdTRUE) { + if (!xShutdownSema || xSemaphoreTake(xShutdownSema, pdMS_TO_TICKS(MB_SHDN_WAIT_TOUT_MS)) != pdTRUE) { ESP_LOGW(TAG, "Modbus port task couldn't exit gracefully within timeout -> abruptly deleting the task."); - vTaskDelete(xMbPortConfig.xMbTcpTaskHandle); } + vTaskDelete(xMbPortConfig.xMbTcpTaskHandle); + xMbPortConfig.xMbTcpTaskHandle = NULL; if (xShutdownSema) { vSemaphoreDelete(xShutdownSema); xShutdownSema = NULL; } + ESP_LOGD(TAG,"Master port is closed."); } void vMBMasterTCPPortClose(void) diff --git a/freemodbus/tcp_slave/port/port_tcp_slave.c b/freemodbus/tcp_slave/port/port_tcp_slave.c index 7e641b4..616d0f2 100644 --- a/freemodbus/tcp_slave/port/port_tcp_slave.c +++ b/freemodbus/tcp_slave/port/port_tcp_slave.c @@ -261,19 +261,21 @@ static void vMBTCPPortFreeClientInfo(MbClientInfo_t *pxClientInfo) static void vMBTCPPortShutdown(void) { - xSemaphoreGive(xShutdownSema); - vTaskDelete(NULL); - xConfig.xMbTcpTaskHandle = NULL; - for (int i = 0; i < MB_TCP_PORT_MAX_CONN; i++) { MbClientInfo_t *pxClientInfo = xConfig.pxMbClientInfo[i]; - if ((pxClientInfo != NULL) && (pxClientInfo->xSockId > 0)) { - xMBTCPPortCloseConnection(pxClientInfo); + if (pxClientInfo != NULL) { + if (pxClientInfo->xSockId > 0) { + xMBTCPPortCloseConnection(pxClientInfo); + } + ESP_LOGD(TAG,"Close port instance: %p.", pxClientInfo); vMBTCPPortFreeClientInfo(pxClientInfo); xConfig.pxMbClientInfo[i] = NULL; } } + ESP_LOGD(TAG,"Shutdown port task."); free(xConfig.pxMbClientInfo); + xSemaphoreGive(xShutdownSema); + vTaskSuspend(NULL); } static int xMBTCPPortRxPoll(MbClientInfo_t *pxClientInfo, ULONG xTimeoutMs) @@ -669,19 +671,19 @@ vMBTCPPortClose( ) if (xShutdownSema == NULL || // if no semaphore (alloc issues) or couldn't acquire it, just delete the task xSemaphoreTake(xShutdownSema, 2 * pdMS_TO_TICKS(CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND)) != pdTRUE) { ESP_LOGE(TAG, "Task couldn't exit gracefully within timeout -> abruptly deleting the task"); - vTaskDelete(xConfig.xMbTcpTaskHandle); } - + vTaskDelete(xConfig.xMbTcpTaskHandle); + xConfig.xMbTcpTaskHandle = NULL; close(xListenSock); xListenSock = -1; vMBTCPPortRespQueueDelete(xConfig.xRespQueueHandle); - if (xShutdownSema) { vSemaphoreDelete(xShutdownSema); xShutdownSema = NULL; } vMBPortEventClose(); + ESP_LOGD(TAG,"Port is closed."); } void vMBTCPPortEnable( void )