freemodbus: change critical sections to semaphore mutex

revert changes made in mbrtu.c, mbascii.c
change critical section type to semaphore mutex instead of spin lock

Closes: https://github.com/espressif/esp-idf/issues/3009
This commit is contained in:
aleks 2019-03-07 09:51:25 +01:00
parent 1ef7d093e1
commit aaa1cb6eec
5 changed files with 23 additions and 10 deletions

View file

@ -110,6 +110,7 @@ eMBASCIIInit( UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eP
eMBErrorCode eStatus = MB_ENOERR; eMBErrorCode eStatus = MB_ENOERR;
( void )ucSlaveAddress; ( void )ucSlaveAddress;
ENTER_CRITICAL_SECTION( );
ucMBLFCharacter = MB_ASCII_DEFAULT_LF; ucMBLFCharacter = MB_ASCII_DEFAULT_LF;
if( xMBPortSerialInit( ucPort, ulBaudRate, 7, eParity ) != TRUE ) if( xMBPortSerialInit( ucPort, ulBaudRate, 7, eParity ) != TRUE )
@ -121,6 +122,7 @@ eMBASCIIInit( UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eP
eStatus = MB_EPORTERR; eStatus = MB_EPORTERR;
} }
EXIT_CRITICAL_SECTION( );
return eStatus; return eStatus;
} }
@ -128,8 +130,10 @@ eMBASCIIInit( UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eP
void void
eMBASCIIStart( void ) eMBASCIIStart( void )
{ {
ENTER_CRITICAL_SECTION( );
vMBPortSerialEnable( TRUE, FALSE ); vMBPortSerialEnable( TRUE, FALSE );
eRcvState = STATE_RX_IDLE; eRcvState = STATE_RX_IDLE;
EXIT_CRITICAL_SECTION( );
/* No special startup required for ASCII. */ /* No special startup required for ASCII. */
( void )xMBPortEventPost( EV_READY ); ( void )xMBPortEventPost( EV_READY );
@ -138,8 +142,10 @@ eMBASCIIStart( void )
void void
eMBASCIIStop( void ) eMBASCIIStop( void )
{ {
ENTER_CRITICAL_SECTION( );
vMBPortSerialEnable( FALSE, FALSE ); vMBPortSerialEnable( FALSE, FALSE );
vMBPortTimersDisable( ); vMBPortTimersDisable( );
EXIT_CRITICAL_SECTION( );
} }
eMBErrorCode eMBErrorCode

View file

@ -84,6 +84,7 @@ eMBRTUInit( UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity ePar
ULONG usTimerT35_50us; ULONG usTimerT35_50us;
( void )ucSlaveAddress; ( void )ucSlaveAddress;
ENTER_CRITICAL_SECTION( );
/* Modbus RTU uses 8 Databits. */ /* Modbus RTU uses 8 Databits. */
if( xMBPortSerialInit( ucPort, ulBaudRate, 8, eParity ) != TRUE ) if( xMBPortSerialInit( ucPort, ulBaudRate, 8, eParity ) != TRUE )
@ -116,6 +117,7 @@ eMBRTUInit( UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity ePar
eStatus = MB_EPORTERR; eStatus = MB_EPORTERR;
} }
} }
EXIT_CRITICAL_SECTION( );
return eStatus; return eStatus;
} }
@ -123,6 +125,7 @@ eMBRTUInit( UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity ePar
void void
eMBRTUStart( void ) eMBRTUStart( void )
{ {
ENTER_CRITICAL_SECTION( );
/* Initially the receiver is in the state STATE_RX_INIT. we start /* Initially the receiver is in the state STATE_RX_INIT. we start
* the timer and if no character is received within t3.5 we change * the timer and if no character is received within t3.5 we change
* to STATE_RX_IDLE. This makes sure that we delay startup of the * to STATE_RX_IDLE. This makes sure that we delay startup of the
@ -132,13 +135,16 @@ eMBRTUStart( void )
vMBPortSerialEnable( TRUE, FALSE ); vMBPortSerialEnable( TRUE, FALSE );
vMBPortTimersEnable( ); vMBPortTimersEnable( );
EXIT_CRITICAL_SECTION( );
} }
void void
eMBRTUStop( void ) eMBRTUStop( void )
{ {
ENTER_CRITICAL_SECTION( );
vMBPortSerialEnable( FALSE, FALSE ); vMBPortSerialEnable( FALSE, FALSE );
vMBPortTimersDisable( ); vMBPortTimersDisable( );
EXIT_CRITICAL_SECTION( );
} }
// The lines below are required to suppress GCC warnings about unused but set variable 'xFrameReceived' // The lines below are required to suppress GCC warnings about unused but set variable 'xFrameReceived'

View file

@ -60,8 +60,11 @@
#define MB_ENTER_CRITICAL(mux) portENTER_CRITICAL(mux) #define MB_ENTER_CRITICAL(mux) portENTER_CRITICAL(mux)
#define MB_EXIT_CRITICAL(mux) portEXIT_CRITICAL(mux) #define MB_EXIT_CRITICAL(mux) portEXIT_CRITICAL(mux)
#define ENTER_CRITICAL_SECTION( ) ( vMBPortEnterCritical() ) #define ENTER_CRITICAL_SECTION( ) { ESP_LOGD(MB_PORT_TAG,"%s: Port enter critical.", __func__); \
#define EXIT_CRITICAL_SECTION( ) ( vMBPortExitCritical() ) vMBPortEnterCritical(); }
#define EXIT_CRITICAL_SECTION( ) { vMBPortExitCritical(); \
ESP_LOGD(MB_PORT_TAG,"%s: Port exit critical", __func__); }
typedef char BOOL; typedef char BOOL;

View file

@ -32,16 +32,16 @@
#include <stdlib.h> #include <stdlib.h>
#include <freertos/FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include <freertos/task.h> #include <freertos/task.h>
#include <freertos/semphr.h>
/* ----------------------- Modbus includes ----------------------------------*/ /* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h" #include "mb.h"
#include "mbport.h" #include "mbport.h"
#include "sys/lock.h"
/* ----------------------- Modbus includes ----------------------------------*/ /* ----------------------- Modbus includes ----------------------------------*/
/* ----------------------- Variables ----------------------------------------*/ /* ----------------------- Variables ----------------------------------------*/
static portMUX_TYPE mb_mutex = portMUX_INITIALIZER_UNLOCKED; static _lock_t s_port_lock;
/* ----------------------- Start implementation -----------------------------*/ /* ----------------------- Start implementation -----------------------------*/
@ -52,16 +52,16 @@ bMBPortIsWithinException( void )
return bIsWithinException; return bIsWithinException;
} }
void inline void
vMBPortEnterCritical( void ) vMBPortEnterCritical( void )
{ {
portENTER_CRITICAL(&mb_mutex); _lock_acquire(&s_port_lock);
} }
void inline void
vMBPortExitCritical( void ) vMBPortExitCritical( void )
{ {
portEXIT_CRITICAL(&mb_mutex); _lock_release(&s_port_lock);
} }
void void

View file

@ -74,7 +74,6 @@ static USHORT uiRxBufferPos = 0; // position in the receiver buffer
void vMBPortSerialEnable(BOOL bRxEnable, BOOL bTxEnable) void vMBPortSerialEnable(BOOL bRxEnable, BOOL bTxEnable)
{ {
// This function can be called from xMBRTUTransmitFSM() of different task // This function can be called from xMBRTUTransmitFSM() of different task
ENTER_CRITICAL_SECTION();
if (bRxEnable) { if (bRxEnable) {
//uart_enable_rx_intr(ucUartNumber); //uart_enable_rx_intr(ucUartNumber);
bRxStateEnabled = TRUE; bRxStateEnabled = TRUE;
@ -88,7 +87,6 @@ void vMBPortSerialEnable(BOOL bRxEnable, BOOL bTxEnable)
} else { } else {
bTxStateEnabled = FALSE; bTxStateEnabled = FALSE;
} }
EXIT_CRITICAL_SECTION();
} }
static void vMBPortSerialRxPoll(size_t xEventSize) static void vMBPortSerialRxPoll(size_t xEventSize)