ソースを参照

freemodbus: fix fragmented response frame causes next value fail

drop uart ll driver fix: soc: prevent speculative reads from FIFO at -O2 optimization
(new compiler fixes this issue)
Alex Lisitsyn 5 年 前
コミット
b28b62b194

+ 3 - 2
components/freemodbus/modbus/ascii/mbascii_m.c

@@ -320,13 +320,14 @@ xMBMasterASCIIReceiveFSM( void )
         {
             /* Disable character timeout timer because all characters are
              * received. */
-            vMBPortTimersDisable(  );
+            vMBMasterPortTimersDisable(  );
             /* Receiver is again in idle state. */
             eRcvState = STATE_M_RX_IDLE;
 
             /* Notify the caller of eMBMasterASCIIReceive that a new frame
              * was received. */
             (void)xMBMasterPortEventPost( EV_MASTER_FRAME_RECEIVED );
+            xNeedPoll = FALSE;
         }
         else if( ucByte == ':' )
         {
@@ -355,7 +356,7 @@ xMBMasterASCIITransmitFSM( void )
 {
     BOOL            xNeedPoll = TRUE;
     UCHAR           ucByte;
-    BOOL xFrameIsBroadcast = FALSE;
+    BOOL            xFrameIsBroadcast = FALSE;
 
     assert( eRcvState == STATE_M_RX_IDLE );
     

+ 1 - 1
components/freemodbus/modbus/mb.c

@@ -367,9 +367,9 @@ eMBPoll( void )
                 if( ( ucRcvAddress == ucMBAddress ) || ( ucRcvAddress == MB_ADDRESS_BROADCAST ) )
                 {
                     ( void )xMBPortEventPost( EV_EXECUTE );
+                    ESP_LOG_BUFFER_HEX_LEVEL(MB_PORT_TAG, &ucMBFrame[MB_PDU_FUNC_OFF], usLength, ESP_LOG_DEBUG);
                 }
             }
-            ESP_LOG_BUFFER_HEX_LEVEL(MB_PORT_TAG, &ucMBFrame[MB_PDU_FUNC_OFF], usLength, ESP_LOG_DEBUG);
             break;
 
         case EV_EXECUTE:

+ 5 - 3
components/freemodbus/modbus/mb_m.c

@@ -292,19 +292,19 @@ eMBMasterPoll( void )
             MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_READY );
         } else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_FRAME_RECEIVED ) ) {
             eStatus = peMBMasterFrameReceiveCur( &ucRcvAddress, &ucMBFrame, &usLength);
-            ESP_LOG_BUFFER_HEX_LEVEL("POLL RCV buffer:", (void*)ucMBFrame, (uint16_t)usLength, ESP_LOG_DEBUG);
             // Check if the frame is for us. If not ,send an error process event.
             if ( ( eStatus == MB_ENOERR ) && ( ucRcvAddress == ucMBMasterGetDestAddress() ) )
             {
-                ESP_LOGD(MB_PORT_TAG, "%s: Packet data received successfully (%u).", __func__, eStatus);
                 ( void ) xMBMasterPortEventPost( EV_MASTER_EXECUTE );
+                ESP_LOGD(MB_PORT_TAG, "%s: Packet data received successfully (%u).", __func__, eStatus);
+                ESP_LOG_BUFFER_HEX_LEVEL("POLL RCV buffer", (void*)ucMBFrame, (uint16_t)usLength, ESP_LOG_DEBUG);
             }
             else
             {
                 vMBMasterSetErrorType(EV_ERROR_RECEIVE_DATA);
+                ( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
                 ESP_LOGD( MB_PORT_TAG, "%s: Packet data receive failed (addr=%u)(%u).",
                                        __func__, ucRcvAddress, eStatus);
-                ( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
             }
             MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_FRAME_RECEIVED );
         } else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_EXECUTE ) ) {
@@ -371,6 +371,8 @@ eMBMasterPoll( void )
             if (eStatus != MB_ENOERR)
             {
                 ESP_LOGE( MB_PORT_TAG, "%s:Frame send error. %d", __func__, eStatus );
+            } else {
+                ESP_LOG_BUFFER_HEX_LEVEL("Sent buffer", (void*)ucMBFrame, usMBMasterGetPDUSndLength(), ESP_LOG_DEBUG);
             }
             MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_FRAME_TRANSMIT );
         } else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_FRAME_SENT ) ) {

+ 4 - 1
components/freemodbus/port/portevent.c

@@ -91,11 +91,14 @@ xMBPortEventPost( eMBEventType eEvent )
     if( (BOOL)xPortInIsrContext() == TRUE )
     {
         xStatus = xQueueSendFromISR(xQueueHdl, (const void*)&eEvent, &xHigherPriorityTaskWoken);
-        MB_PORT_CHECK((xStatus == pdTRUE), FALSE, "%s: Post message failure.", __func__);
         if ( xHigherPriorityTaskWoken )
         {
             portYIELD_FROM_ISR();
         }
+        if (xStatus != pdTRUE) {
+            ESP_EARLY_LOGV(MB_PORT_TAG, "%s: Post message failure = %d.", __func__, xStatus);
+            return FALSE;
+        }
     }
     else
     {

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

@@ -139,6 +139,8 @@ static void vUartTask(void* pvParameters)
                         // Read received data and send it to modbus stack
                         usResult = usMBMasterPortSerialRxPoll(xEvent.size);
                         ESP_LOGD(TAG,"Timeout occured, processed: %d bytes", usResult);
+                        // Block receiver task until data is not processed
+                        vTaskSuspend(NULL);
                     }
                     break;
                 //Event of HW FIFO overflow detected