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

freemodbus: fix event processing after merge

aleks 4 лет назад
Родитель
Сommit
d340fa68aa
2 измененных файлов с 122 добавлено и 120 удалено
  1. 4 3
      components/freemodbus/modbus/include/mbport.h
  2. 118 117
      components/freemodbus/modbus/mb_m.c

+ 4 - 3
components/freemodbus/modbus/include/mbport.h

@@ -74,14 +74,15 @@ typedef enum {
     EV_MASTER_PROCESS_SUCCESS = 0x0040,         /*!< Request process success. */
     EV_MASTER_ERROR_RESPOND_TIMEOUT = 0x0080,   /*!< Request respond timeout. */
     EV_MASTER_ERROR_RECEIVE_DATA = 0x0100,      /*!< Request receive data error. */
-    EV_MASTER_ERROR_EXECUTE_FUNCTION = 0x0200,  /*!< Request execute function error. */
+    EV_MASTER_ERROR_EXECUTE_FUNCTION = 0x0200   /*!< Request execute function error. */
 } eMBMasterEventType;
 
 typedef enum {
+    EV_ERROR_INIT,             /*!< No error, initial state. */
     EV_ERROR_RESPOND_TIMEOUT,  /*!< Slave respond timeout. */
-    EV_ERROR_RECEIVE_DATA,     /*!< Receive frame data erroe. */
+    EV_ERROR_RECEIVE_DATA,     /*!< Receive frame data error. */
     EV_ERROR_EXECUTE_FUNCTION, /*!< Execute function error. */
-    EV_ERROR_OK,               /*!< Data processed. */
+    EV_ERROR_OK                /*!< No error, processing completed. */
 } eMBMasterErrorEventType;
 #endif
 

+ 118 - 117
components/freemodbus/modbus/mb_m.c

@@ -285,135 +285,136 @@ eMBMasterPoll( void )
      * Otherwise we will handle the event. */
     if ( xMBMasterPortEventGet( &eEvent ) == TRUE )
     {
-        // In some cases it is possible that more than one event set
-        // together (even from one subset mask) than process them consistently
-        if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_READY ) ) {
-            ESP_LOGD(MB_PORT_TAG, "%s:EV_MASTER_READY", __func__);
-            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 );
-            }
-            else
-            {
-                vMBMasterSetErrorType(EV_ERROR_RECEIVE_DATA);
-                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 ) ) {
-            if ( !ucMBFrame )
-            {
-                return MB_EILLSTATE;
-            }
-            ESP_LOGD(MB_PORT_TAG, "%s:EV_MASTER_EXECUTE", __func__);
-            ucFunctionCode = ucMBFrame[MB_PDU_FUNC_OFF];
-            eException = MB_EX_ILLEGAL_FUNCTION;
-            /* If receive frame has exception. The receive function code highest bit is 1.*/
-            if (ucFunctionCode & MB_FUNC_ERROR)
-            {
-                eException = (eMBException)ucMBFrame[MB_PDU_DATA_OFF];
-            } else {
-                for ( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ )
+        while( eEvent ) {
+            // In some cases it is possible that more than one event set
+            // together (even from one subset mask) than process them consistently
+            if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_READY ) ) {
+                ESP_LOGD(MB_PORT_TAG, "%s:EV_MASTER_READY", __func__);
+                MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_READY );
+            } else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_FRAME_TRANSMIT ) ) {
+                ESP_LOGD(MB_PORT_TAG, "%s:EV_MASTER_FRAME_TRANSMIT", __func__);
+                /* Master is busy now. */
+                vMBMasterGetPDUSndBuf( &ucMBFrame );
+                ESP_LOG_BUFFER_HEX_LEVEL("POLL transmit buffer", (void*)ucMBFrame, usMBMasterGetPDUSndLength(), ESP_LOG_DEBUG);
+                eStatus = peMBMasterFrameSendCur( ucMBMasterGetDestAddress(), ucMBFrame, usMBMasterGetPDUSndLength() );
+                if (eStatus != MB_ENOERR)
                 {
-                    /* No more function handlers registered. Abort. */
-                    if (xMasterFuncHandlers[i].ucFunctionCode == 0)
-                    {
-                        break;
-                    }
-                    if (xMasterFuncHandlers[i].ucFunctionCode == ucFunctionCode)
+                    ESP_LOGE( MB_PORT_TAG, "%s:Frame send error. %d", __func__, eStatus );
+                }
+                MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_FRAME_TRANSMIT );
+            } else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_FRAME_SENT ) ) {
+                ESP_LOGD( MB_PORT_TAG, "%s:EV_MASTER_FRAME_SENT", __func__ );
+                ESP_LOG_BUFFER_HEX_LEVEL("POLL sent buffer", (void*)ucMBFrame, usMBMasterGetPDUSndLength(), ESP_LOG_DEBUG);
+                MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_FRAME_SENT );
+            } else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_FRAME_RECEIVED ) ) {
+                eStatus = peMBMasterFrameReceiveCur( &ucRcvAddress, &ucMBFrame, &usLength);
+
+                // Check if the frame is for us. If not ,send an error process event.
+                if ( ( eStatus == MB_ENOERR ) && ( ucRcvAddress == ucMBMasterGetDestAddress() ) )
+                {
+                    ( void ) xMBMasterPortEventPost( EV_MASTER_EXECUTE );
+                    ESP_LOGD(MB_PORT_TAG, "%s: Packet data received successfully (%u).", __func__, eStatus);
+                    ESP_LOG_BUFFER_HEX_LEVEL("POLL receive 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);
+                }
+                MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_FRAME_RECEIVED );
+            } else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_EXECUTE ) ) {
+                if ( !ucMBFrame )
+                {
+                    return MB_EILLSTATE;
+                }
+                ESP_LOGD(MB_PORT_TAG, "%s:EV_MASTER_EXECUTE", __func__);
+                ucFunctionCode = ucMBFrame[MB_PDU_FUNC_OFF];
+                eException = MB_EX_ILLEGAL_FUNCTION;
+                /* If receive frame has exception. The receive function code highest bit is 1.*/
+                if (ucFunctionCode & MB_FUNC_ERROR)
+                {
+                    eException = (eMBException)ucMBFrame[MB_PDU_DATA_OFF];
+                } else {
+                    for ( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ )
                     {
-                        vMBMasterSetCBRunInMasterMode(TRUE);
-                        /* If master request is broadcast,
-                         * the master need execute function for all slave.
-                         */
-                        if ( xMBMasterRequestIsBroadcast() )
+                        /* No more function handlers registered. Abort. */
+                        if (xMasterFuncHandlers[i].ucFunctionCode == 0)
                         {
-                            usLength = usMBMasterGetPDUSndLength();
-                            for(j = 1; j <= MB_MASTER_TOTAL_SLAVE_NUM; j++)
-                            {
-                                vMBMasterSetDestAddress(j);
-                                eException = xMasterFuncHandlers[i].pxHandler(ucMBFrame, &usLength);
-                            }
+                            break;
                         }
-                        else
+                        if (xMasterFuncHandlers[i].ucFunctionCode == ucFunctionCode)
                         {
-                            eException = xMasterFuncHandlers[i].pxHandler( ucMBFrame, &usLength );
+                            vMBMasterSetCBRunInMasterMode(TRUE);
+                            /* If master request is broadcast,
+                             * the master need execute function for all slave.
+                             */
+                            if ( xMBMasterRequestIsBroadcast() )
+                            {
+                                usLength = usMBMasterGetPDUSndLength();
+                                for(j = 1; j <= MB_MASTER_TOTAL_SLAVE_NUM; j++)
+                                {
+                                    vMBMasterSetDestAddress(j);
+                                    eException = xMasterFuncHandlers[i].pxHandler(ucMBFrame, &usLength);
+                                }
+                            }
+                            else
+                            {
+                                eException = xMasterFuncHandlers[i].pxHandler( ucMBFrame, &usLength );
+                            }
+                            vMBMasterSetCBRunInMasterMode( FALSE );
+                            break;
                         }
-                        vMBMasterSetCBRunInMasterMode( FALSE );
-                        break;
                     }
                 }
+                /* If master has exception, will send error process event. Otherwise the master is idle.*/
+                if ( eException != MB_EX_NONE )
+                {
+                    vMBMasterSetErrorType( EV_ERROR_EXECUTE_FUNCTION );
+                    ( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
+                }
+                else
+                {
+                    if ( eMBMasterGetErrorType( ) == EV_ERROR_INIT ) {
+                        vMBMasterSetErrorType(EV_ERROR_OK);
+                        ESP_LOGD( MB_PORT_TAG, "%s: set event EV_ERROR_OK", __func__ );
+                        ( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
+                    }
+                }
+                MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_EXECUTE );
+            } else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_ERROR_PROCESS ) ) {
+                ESP_LOGD( MB_PORT_TAG, "%s:EV_MASTER_ERROR_PROCESS", __func__ );
+                /* Execute specified error process callback function. */
+                errorType = eMBMasterGetErrorType( );
+                vMBMasterGetPDUSndBuf( &ucMBFrame );
+                switch ( errorType )
+                {
+                    case EV_ERROR_RESPOND_TIMEOUT:
+                        vMBMasterErrorCBRespondTimeout( ucMBMasterGetDestAddress( ),
+                                ucMBFrame, usMBMasterGetPDUSndLength( ) );
+                        break;
+                    case EV_ERROR_RECEIVE_DATA:
+                        vMBMasterErrorCBReceiveData( ucMBMasterGetDestAddress( ),
+                                ucMBFrame, usMBMasterGetPDUSndLength( ) );
+                        break;
+                    case EV_ERROR_EXECUTE_FUNCTION:
+                        vMBMasterErrorCBExecuteFunction( ucMBMasterGetDestAddress( ),
+                                ucMBFrame, usMBMasterGetPDUSndLength( ) );
+                        break;
+                    case EV_ERROR_OK:
+                        vMBMasterCBRequestSuccess( );
+                        break;
+                    default:
+                        ESP_LOGE( MB_PORT_TAG, "%s: incorrect error type = %d.", __func__, errorType);
+                        break;
+                }
+                vMBMasterSetErrorType( EV_ERROR_INIT );
+                MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_ERROR_PROCESS );
+                vMBMasterRunResRelease( );
             }
-            /* If master has exception ,Master will send error process.Otherwise the Master is idle.*/
-            if (eException != MB_EX_NONE)
-            {
-                vMBMasterSetErrorType(EV_ERROR_EXECUTE_FUNCTION);
-                ( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
-            }
-            else
-            {
-                vMBMasterSetErrorType(EV_ERROR_OK);
-                ( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
-            }
-            MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_EXECUTE );
-        } else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_FRAME_TRANSMIT ) ) {
-            ESP_LOGD(MB_PORT_TAG, "%s:EV_MASTER_FRAME_TRANSMIT", __func__);
-            /* Master is busy now. */
-            vMBMasterGetPDUSndBuf( &ucMBFrame );
-            eStatus = peMBMasterFrameSendCur( ucMBMasterGetDestAddress(), ucMBFrame, usMBMasterGetPDUSndLength() );
-            if (eStatus != MB_ENOERR)
-            {
-                ESP_LOGE( MB_PORT_TAG, "%s:Frame send error. %d", __func__, eStatus );
-            }
-            MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_FRAME_TRANSMIT );
-        } else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_FRAME_SENT ) ) {
-            ESP_LOGD( MB_PORT_TAG, "%s:EV_MASTER_FRAME_SENT", __func__ );
-            MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_FRAME_SENT );
-        } else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_ERROR_PROCESS ) ) {
-            ESP_LOGD( MB_PORT_TAG, "%s:EV_MASTER_ERROR_PROCESS", __func__ );
-            /* Execute specified error process callback function. */
-            errorType = eMBMasterGetErrorType( );
-            vMBMasterGetPDUSndBuf( &ucMBFrame );
-            switch ( errorType )
-            {
-                case EV_ERROR_RESPOND_TIMEOUT:
-                    vMBMasterErrorCBRespondTimeout( ucMBMasterGetDestAddress( ),
-                            ucMBFrame, usMBMasterGetPDUSndLength( ) );
-                    break;
-                case EV_ERROR_RECEIVE_DATA:
-                    vMBMasterErrorCBReceiveData( ucMBMasterGetDestAddress( ),
-                            ucMBFrame, usMBMasterGetPDUSndLength( ) );
-                    break;
-                case EV_ERROR_EXECUTE_FUNCTION:
-                    vMBMasterErrorCBExecuteFunction( ucMBMasterGetDestAddress( ),
-                            ucMBFrame, usMBMasterGetPDUSndLength( ) );
-                    break;
-                case EV_ERROR_OK:
-                    vMBMasterCBRequestSuccess( );
-                    break;
-                default:
-                    ESP_LOGE( MB_PORT_TAG, "%s: incorrect error type = %d.", __func__, errorType);
-                    break;
-            }
-            vMBMasterRunResRelease( );
-            MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_ERROR_PROCESS );
-        }
-        if ( eEvent ) {
-            // Event processing is done, but some poll events still set then
-            // postpone its processing for next poll cycle (rare case).
-            ESP_LOGW( MB_PORT_TAG, "%s: Unprocessed event %d.", __func__, eEvent );
-            ( void ) xMBMasterPortEventPost( eEvent );
         }
     } else {
         // Something went wrong and task unblocked but there are no any correct events set
-        ESP_LOGE( MB_PORT_TAG, "%s: Unexpected event triggered %d.", __func__, eEvent );
+        ESP_LOGE( MB_PORT_TAG, "%s: Unexpected event triggered 0x%02x.", __func__, eEvent );
         eStatus = MB_EILLSTATE;
     }
     return eStatus;