From d9d5cae9bbf67af52d7ef053909eced8390e8fba Mon Sep 17 00:00:00 2001 From: armink Date: Wed, 26 Feb 2014 11:27:55 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E3=80=90=E5=A2=9E=E5=8A=A0=E3=80=91F?= =?UTF-8?q?reeModbus=E4=B8=BB=E6=9C=BA=E8=AF=B7=E6=B1=82=E7=BB=93=E6=9E=9C?= =?UTF-8?q?=EF=BC=8C=E5=8C=85=E6=8B=AC=E8=AF=B7=E6=B1=82=E5=A4=84=E7=90=86?= =?UTF-8?q?=E6=88=90=E5=8A=9F=E3=80=81=E8=AF=B7=E6=B1=82=E5=93=8D=E5=BA=94?= =?UTF-8?q?=E8=B6=85=E6=97=B6=E3=80=81=E6=8E=A5=E6=94=B6=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=87=BA=E9=94=99=E5=8F=8A=E5=8A=9F=E8=83=BD=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=E9=94=99=E8=AF=AF=EF=BC=9B=202=E3=80=81?= =?UTF-8?q?=E3=80=90=E5=A2=9E=E5=8A=A0=E3=80=91FreeModbus=E4=B8=BB?= =?UTF-8?q?=E6=9C=BA=E8=AF=B7=E6=B1=82=E5=A4=84=E7=90=86=E6=88=90=E5=8A=9F?= =?UTF-8?q?=E7=9A=84=E5=9B=9E=E8=B0=83=E6=8E=A5=E5=8F=A3=EF=BC=8C=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E5=8F=AF=E4=BB=A5=E5=9C=A8=E9=87=8C=E9=9D=A2=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E8=87=AA=E5=B7=B1=E7=9A=84=E4=BB=A3=E7=A0=81=EF=BC=8C?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E6=88=90=E5=8A=9F=E7=8E=87=E7=AD=89=E7=AD=89?= =?UTF-8?q?=EF=BC=9B=202=E3=80=81=E3=80=90=E4=BF=AE=E6=94=B9=E3=80=91FreeM?= =?UTF-8?q?odbus=E4=B8=BB=E6=9C=BA=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86?= =?UTF-8?q?=E5=9B=9E=E8=B0=83=E6=96=B9=E6=B3=95=E5=AD=98=E6=94=BE=E7=9A=84?= =?UTF-8?q?=E4=BD=8D=E7=BD=AE=EF=BC=8C=E7=A7=BB=E5=8A=A8=E8=87=B3/port/por?= =?UTF-8?q?tevent=5Fm.c=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: armink --- APP/inc/rtconfig.h | 2 +- APP/src/app_task.c | 18 ++-- FreeModbus/modbus/include/mb_m.h | 8 +- FreeModbus/modbus/include/mbport.h | 12 +-- FreeModbus/modbus/mb_m.c | 9 +- FreeModbus/modbus/rtu/mbrtu_m.c | 5 +- FreeModbus/port/port.c | 24 ----- FreeModbus/port/portevent_m.c | 144 +++++++++++++++++++++++++++-- 8 files changed, 164 insertions(+), 58 deletions(-) diff --git a/APP/inc/rtconfig.h b/APP/inc/rtconfig.h index 7c5cf5c..58fca81 100644 --- a/APP/inc/rtconfig.h +++ b/APP/inc/rtconfig.h @@ -38,7 +38,7 @@ #define RT_USING_MUTEX /* Using Event */ -//#define RT_USING_EVENT +#define RT_USING_EVENT /* Using MailBox */ //#define RT_USING_MAILBOX diff --git a/APP/src/app_task.c b/APP/src/app_task.c index 9ccf346..62bfd80 100644 --- a/APP/src/app_task.c +++ b/APP/src/app_task.c @@ -49,15 +49,15 @@ void thread_entry_SysMonitor(void* parameter) usModbusUserData[0] = (USHORT)(rt_tick_get()/10); usModbusUserData[1] = (USHORT)(rt_tick_get()%10); ucModbusUserData[0] = 0x1F; - eMBMasterReqReadDiscreteInputs(1,3,8,MB_WAITING_FOREVER); -// eMBMasterReqWriteMultipleCoils(1,3,5,ucModbusUserData,MB_WAITING_FOREVER); -// eMBMasterReqWriteCoil(1,8,0xFF00,MB_WAITING_FOREVER); -// eMBMasterReqReadCoils(1,3,8,MB_WAITING_FOREVER); -// eMBMasterReqReadInputRegister(1,3,2,MB_WAITING_FOREVER); -// eMBMasterReqWriteHoldingRegister(1,3,usModbusUserData[0],MB_WAITING_FOREVER); -// eMBMasterReqWriteMultipleHoldingRegister(1,3,2,usModbusUserData,MB_WAITING_FOREVER); -// eMBMasterReqReadHoldingRegister(1,3,2,MB_WAITING_FOREVER); -// eMBMasterReqReadWriteMultipleHoldingRegister(1,3,2,usModbusUserData,5,2,MB_WAITING_FOREVER); + eMBMasterReqReadDiscreteInputs(1,3,8,RT_WAITING_FOREVER); +// eMBMasterReqWriteMultipleCoils(1,3,5,ucModbusUserData,RT_WAITING_FOREVER); +// eMBMasterReqWriteCoil(1,8,0xFF00,RT_WAITING_FOREVER); +// eMBMasterReqReadCoils(1,3,8,RT_WAITING_FOREVER); +// eMBMasterReqReadInputRegister(1,3,2,RT_WAITING_FOREVER); +// eMBMasterReqWriteHoldingRegister(1,3,usModbusUserData[0],RT_WAITING_FOREVER); +// eMBMasterReqWriteMultipleHoldingRegister(1,3,2,usModbusUserData,RT_WAITING_FOREVER); +// eMBMasterReqReadHoldingRegister(1,3,2,RT_WAITING_FOREVER); +// eMBMasterReqReadWriteMultipleHoldingRegister(1,3,2,usModbusUserData,5,2,RT_WAITING_FOREVER); } } diff --git a/FreeModbus/modbus/include/mb_m.h b/FreeModbus/modbus/include/mb_m.h index 0dadb45..abe4889 100644 --- a/FreeModbus/modbus/include/mb_m.h +++ b/FreeModbus/modbus/include/mb_m.h @@ -77,13 +77,10 @@ typedef enum MB_MRE_NO_ERR, /*!< no error. */ MB_MRE_NO_REG, /*!< illegal register address. */ MB_MRE_ILL_ARG, /*!< illegal argument. */ - MB_MRE_PORT_ERR, /*!< porting layer error. */ - MB_MRE_NO_RES, /*!< insufficient resources. */ - MB_MRE_IO, /*!< I/O error. */ - MB_MRE_ILL_STATE, /*!< protocol stack in illegal state. */ + MB_MRE_REV_DATA, /*!< receive data error. */ MB_MRE_TIMEDOUT, /*!< timeout error occurred. */ MB_MRE_MASTER_BUSY, /*!< master is busy now. */ - MB_MRE_SLAVE_EXCE /*!< slave has exception. */ + MB_MRE_EXE_FUN /*!< execute function error. */ } eMBMasterReqErrCode; /*! \ingroup modbus * \brief TimerMode is Master 3 kind of Timer modes. @@ -394,6 +391,7 @@ void vMBMasterSetPDUSndLength( USHORT SendPDULength ); void vMBMasterSetCurTimerMode( eMBMasterTimerMode eMBTimerMode ); eMBMasterErrorEventType eMBMasterGetErrorType( void ); void vMBMasterSetErrorType( eMBMasterErrorEventType errorType ); +eMBMasterReqErrCode vMBMasterWaitRequestFinish( void ); /* ----------------------- Callback -----------------------------------------*/ diff --git a/FreeModbus/modbus/include/mbport.h b/FreeModbus/modbus/include/mbport.h index b465a94..b06d40f 100644 --- a/FreeModbus/modbus/include/mbport.h +++ b/FreeModbus/modbus/include/mbport.h @@ -38,14 +38,6 @@ PR_BEGIN_EXTERN_C /* ----------------------- Defines ------------------------------------------*/ -/*! \ingroup modbus - * \brief used for master mode. - * - * the xMBMasterRunResTake() parameter definitions - */ -#define MB_WAITING_FOREVER -1 /*!< Block forever until get resource. */ -#define MB_WAITING_NO 0 /*!< Non-block. */ - /* ----------------------- Type definitions ---------------------------------*/ typedef enum @@ -99,7 +91,7 @@ BOOL xMBMasterPortEventPost( eMBMasterEventType eEvent ); BOOL xMBMasterPortEventGet( /*@out@ */ eMBMasterEventType * eEvent ); -void vMBMasterRunResInit( void ); +void vMBMasterOsResInit( void ); BOOL xMBMasterRunResTake( int32_t time ); @@ -164,6 +156,8 @@ void vMBMasterErrorCBReceiveData( UCHAR ucDestAddress, const UCHAR* p void vMBMasterErrorCBExecuteFunction( UCHAR ucDestAddress, const UCHAR* pucPDUData, USHORT ucPDULength ); +void vMBMasterCBRequestScuuess( void ); + /* ----------------------- Callback for the protocol stack ------------------*/ /*! diff --git a/FreeModbus/modbus/mb_m.c b/FreeModbus/modbus/mb_m.c index e0859a6..962bb13 100644 --- a/FreeModbus/modbus/mb_m.c +++ b/FreeModbus/modbus/mb_m.c @@ -185,8 +185,8 @@ eMBMasterInit( eMBMode eMode, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity { eMBState = STATE_DISABLED; } - /* initialize the Mobus Master running resource. */ - vMBMasterRunResInit(); + /* initialize the OS resource for modbus master. */ + vMBMasterOsResInit(); } return eStatus; } @@ -325,7 +325,10 @@ eMBMasterPoll( void ) vMBMasterSetErrorType(EV_ERROR_EXECUTE_FUNCTION); ( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS ); } - else vMBMasterRunResRelease(); + else { + vMBMasterCBRequestScuuess( ); + vMBMasterRunResRelease( ); + } break; case EV_MASTER_FRAME_SENT: diff --git a/FreeModbus/modbus/rtu/mbrtu_m.c b/FreeModbus/modbus/rtu/mbrtu_m.c index 740e686..55ff739 100644 --- a/FreeModbus/modbus/rtu/mbrtu_m.c +++ b/FreeModbus/modbus/rtu/mbrtu_m.c @@ -396,7 +396,10 @@ xMBMasterRTUTimerExpired(void) vMBMasterPortTimersDisable( ); /* If timer mode is convert delay ,then Master is idel now. */ - if (eMasterCurTimerMode == MB_TMODE_CONVERT_DELAY) vMBMasterRunResRelease(); + if (eMasterCurTimerMode == MB_TMODE_CONVERT_DELAY) { + vMBMasterCBRequestScuuess( ); + vMBMasterRunResRelease( ); + } return xNeedPoll; } diff --git a/FreeModbus/port/port.c b/FreeModbus/port/port.c index 952999a..cbab104 100644 --- a/FreeModbus/port/port.c +++ b/FreeModbus/port/port.c @@ -42,27 +42,3 @@ void vMBDelay(ULONG nCount) { for(; nCount > 0;nCount--); } - -#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0 -/** - * - * Just use it for modbus master. - * @note There functions will block modbus master poll while execute OS waiting. - * So,for real-time of system.Do not execute too much waiting process. - * - */ -void vMBMasterErrorCBRespondTimeout(UCHAR ucDestAddress, const UCHAR* pucPDUData, - USHORT ucPDULength) { - -} - -void vMBMasterErrorCBReceiveData(UCHAR ucDestAddress, const UCHAR* pucPDUData, - USHORT ucPDULength) { - -} - -void vMBMasterErrorCBExecuteFunction(UCHAR ucDestAddress, const UCHAR* pucPDUData, - USHORT ucPDULength) { - -} -#endif diff --git a/FreeModbus/port/portevent_m.c b/FreeModbus/port/portevent_m.c index 289e09a..685ecad 100644 --- a/FreeModbus/port/portevent_m.c +++ b/FreeModbus/port/portevent_m.c @@ -21,15 +21,21 @@ /* ----------------------- Modbus includes ----------------------------------*/ #include "mb.h" +#include "mb_m.h" #include "mbport.h" #include "port.h" #if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0 +/* ----------------------- Defines ------------------------------------------*/ +#define EVENT_MASTER_PROCESS_SUCESS 1<<0 //master request process success event +#define EVENT_MASTER_ERROR_RESPOND_TIMEOUT 1<<1 //master request respond timeout event +#define EVENT_MASTER_ERROR_RECEIVE_DATA 1<<2 //master request receive data error event +#define EVENT_MASTER_ERROR_EXECUTE_FUNCTION 1<<3 //master request execute function error event /* ----------------------- Variables ----------------------------------------*/ static eMBMasterEventType eMasterQueuedEvent; static BOOL xMasterEventInQueue; static struct rt_semaphore xMasterRunRes; - +static struct rt_event xMasterOsEvent; /* ----------------------- Start implementation -----------------------------*/ BOOL xMBMasterPortEventInit( void ) @@ -61,18 +67,19 @@ xMBMasterPortEventGet( eMBMasterEventType * eEvent ) } /** - * This function is initialize the Mobus Master running resource . - * Note:The resource is define by Operating System.If you not use Opearting System this function can be empty. + * This function is initialize the OS resource for modbus master. + * Note:The resource is define by OS.If you not use OS this function can be empty. * */ -void vMBMasterRunResInit( void ) +void vMBMasterOsResInit( void ) { + rt_event_init(&xMasterOsEvent,"master event",RT_IPC_FLAG_PRIO); rt_sem_init(&xMasterRunRes, "master res", 0x01 , RT_IPC_FLAG_PRIO); } /** * This function is take Mobus Master running resource. - * Note:The resource is define by Operating System.If you not use Opearting System this function can be just return TRUE. + * Note:The resource is define by Operating System.If you not use OS this function can be just return TRUE. * * @param lTimeOut the waiting time. * @@ -86,7 +93,7 @@ BOOL xMBMasterRunResTake( LONG lTimeOut ) /** * This function is release Mobus Master running resource. - * Note:The resource is define by Operating System.If you not use Opearting System this function can be empty. + * Note:The resource is define by Operating System.If you not use OS this function can be empty. * */ void vMBMasterRunResRelease( void ) @@ -95,4 +102,129 @@ void vMBMasterRunResRelease( void ) rt_sem_release(&xMasterRunRes); } +/** + * This is modbus master respond timeout error process callback function. + * @note There functions will block modbus master poll while execute OS waiting. + * So,for real-time of system.Do not execute too much waiting process. + * + * @param ucDestAddress destination salve address + * @param pucPDUData PDU buffer data + * @param ucPDULength PDU buffer length + * + */ +void vMBMasterErrorCBRespondTimeout(UCHAR ucDestAddress, const UCHAR* pucPDUData, + USHORT ucPDULength) { + /** + * @note This code is use OS's event mechanism for modbus master protocol stack. + * If you don't use OS, you can change it. + */ + rt_event_send(&xMasterOsEvent, EVENT_MASTER_ERROR_RESPOND_TIMEOUT); + + /* You can add your code under here. */ + +} + +/** + * This is modbus master receive data error process callback function. + * @note There functions will block modbus master poll while execute OS waiting. + * So,for real-time of system.Do not execute too much waiting process. + * + * @param ucDestAddress destination salve address + * @param pucPDUData PDU buffer data + * @param ucPDULength PDU buffer length + * + */ +void vMBMasterErrorCBReceiveData(UCHAR ucDestAddress, const UCHAR* pucPDUData, + USHORT ucPDULength) { + /** + * @note This code is use OS's event mechanism for modbus master protocol stack. + * If you don't use OS, you can change it. + */ + rt_event_send(&xMasterOsEvent, EVENT_MASTER_ERROR_RECEIVE_DATA); + + /* You can add your code under here. */ + +} + +/** + * This is modbus master execute function error process callback function. + * @note There functions will block modbus master poll while execute OS waiting. + * So,for real-time of system.Do not execute too much waiting process. + * + * @param ucDestAddress destination salve address + * @param pucPDUData PDU buffer data + * @param ucPDULength PDU buffer length + * + */ +void vMBMasterErrorCBExecuteFunction(UCHAR ucDestAddress, const UCHAR* pucPDUData, + USHORT ucPDULength) { + /** + * @note This code is use OS's event mechanism for modbus master protocol stack. + * If you don't use OS, you can change it. + */ + rt_event_send(&xMasterOsEvent, EVENT_MASTER_ERROR_EXECUTE_FUNCTION); + + /* You can add your code under here. */ + +} + +/** + * This is modbus master request process success callback function. + * @note There functions will block modbus master poll while execute OS waiting. + * So,for real-time of system.Do not execute too much waiting process. + * + */ +void vMBMasterCBRequestScuuess( void ) { + /** + * @note This code is use OS's event mechanism for modbus master protocol stack. + * If you don't use OS, you can change it. + */ + rt_event_send(&xMasterOsEvent, EVENT_MASTER_PROCESS_SUCESS); + + /* You can add your code under here. */ + +} + +/** + * This function is wait for modbus master request finish and return result. + * Waiting result include request process success, request respond timeout, + * receive data error and execute function error.You can use the above callback function. + * @note If you are use OS, you can use OS's event mechanism. Otherwise you have to run + * much user custom delay for waiting. + * + * @return request error code + */ +eMBMasterReqErrCode vMBMasterWaitRequestFinish( void ) { + eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR; + rt_uint32_t recvedEvent; + /* waiting for OS event */ + rt_event_recv(&xMasterOsEvent, + EVENT_MASTER_PROCESS_SUCESS | EVENT_MASTER_ERROR_RESPOND_TIMEOUT + | EVENT_MASTER_ERROR_RECEIVE_DATA + | EVENT_MASTER_ERROR_EXECUTE_FUNCTION, + RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, + &recvedEvent); + switch (recvedEvent) + { + case EVENT_MASTER_PROCESS_SUCESS: + break; + case EVENT_MASTER_ERROR_RESPOND_TIMEOUT: + { + eErrStatus = MB_MRE_TIMEDOUT; + break; + } + case EVENT_MASTER_ERROR_RECEIVE_DATA: + { + eErrStatus = MB_MRE_REV_DATA; + break; + } + case EVENT_MASTER_ERROR_EXECUTE_FUNCTION: + { + eErrStatus = MB_MRE_EXE_FUN; + break; + } + } + return eErrStatus; +} + #endif