1、【优化】FreeModbus主机及从机协议栈事件机制,完全采用操作系统自带事件实现,比之前方式性能提升10倍。

Signed-off-by: armink <armink.ztl@gmail.com>
This commit is contained in:
armink 2014-04-03 16:01:16 +08:00
parent b717ccd2e6
commit 0a2e9c8d6f
4 changed files with 80 additions and 57 deletions

View File

@ -42,19 +42,23 @@ PR_BEGIN_EXTERN_C
typedef enum typedef enum
{ {
EV_READY, /*!< Startup finished. */ EV_READY = 1<<0, /*!< Startup finished. */
EV_FRAME_RECEIVED, /*!< Frame received. */ EV_FRAME_RECEIVED = 1<<1, /*!< Frame received. */
EV_EXECUTE, /*!< Execute function. */ EV_EXECUTE = 1<<2, /*!< Execute function. */
EV_FRAME_SENT /*!< Frame sent. */ EV_FRAME_SENT = 1<<3 /*!< Frame sent. */
} eMBEventType; } eMBEventType;
typedef enum typedef enum
{ {
EV_MASTER_READY, /*!< Startup finished. */ EV_MASTER_READY = 1<<0, /*!< Startup finished. */
EV_MASTER_FRAME_RECEIVED, /*!< Frame received. */ EV_MASTER_FRAME_RECEIVED = 1<<1, /*!< Frame received. */
EV_MASTER_EXECUTE, /*!< Execute function. */ EV_MASTER_EXECUTE = 1<<2, /*!< Execute function. */
EV_MASTER_FRAME_SENT, /*!< Frame sent. */ EV_MASTER_FRAME_SENT = 1<<3, /*!< Frame sent. */
EV_MASTER_ERROR_PROCESS /*!< Frame error process*/ EV_MASTER_ERROR_PROCESS = 1<<4, /*!< Frame error process. */
EV_MASTER_PROCESS_SUCESS = 1<<5, /*!< Request process success. */
EV_MASTER_ERROR_RESPOND_TIMEOUT = 1<<6, /*!< Request respond timeout. */
EV_MASTER_ERROR_RECEIVE_DATA = 1<<7, /*!< Request receive data error. */
EV_MASTER_ERROR_EXECUTE_FUNCTION = 1<<8, /*!< Request execute function error. */
} eMBMasterEventType; } eMBMasterEventType;
typedef enum typedef enum

View File

@ -24,35 +24,45 @@
#include "mbport.h" #include "mbport.h"
/* ----------------------- Variables ----------------------------------------*/ /* ----------------------- Variables ----------------------------------------*/
static eMBEventType eQueuedEvent; static struct rt_event xSlaveOsEvent;
static BOOL xEventInQueue;
/* ----------------------- Start implementation -----------------------------*/ /* ----------------------- Start implementation -----------------------------*/
BOOL BOOL
xMBPortEventInit( void ) xMBPortEventInit( void )
{ {
xEventInQueue = FALSE; rt_event_init(&xSlaveOsEvent,"slave event",RT_IPC_FLAG_PRIO);
return TRUE; return TRUE;
} }
BOOL BOOL
xMBPortEventPost( eMBEventType eEvent ) xMBPortEventPost( eMBEventType eEvent )
{ {
xEventInQueue = TRUE; rt_event_send(&xSlaveOsEvent, eEvent);
eQueuedEvent = eEvent;
return TRUE; return TRUE;
} }
BOOL BOOL
xMBPortEventGet( eMBEventType * eEvent ) xMBPortEventGet( eMBEventType * eEvent )
{ {
BOOL xEventHappened = FALSE; rt_uint32_t recvedEvent;
/* waiting forever OS event */
if( xEventInQueue ) rt_event_recv(&xSlaveOsEvent,
{ EV_READY | EV_FRAME_RECEIVED | EV_EXECUTE | EV_FRAME_SENT,
*eEvent = eQueuedEvent; RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER,
xEventInQueue = FALSE; &recvedEvent);
xEventHappened = TRUE; switch (recvedEvent)
} {
return xEventHappened; case EV_READY:
*eEvent = EV_READY;
break;
case EV_FRAME_RECEIVED:
*eEvent = EV_FRAME_RECEIVED;
break;
case EV_EXECUTE:
*eEvent = EV_EXECUTE;
break;
case EV_FRAME_SENT:
*eEvent = EV_FRAME_SENT;
break;
}
return TRUE;
} }

View File

@ -27,45 +27,55 @@
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0 #if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
/* ----------------------- Defines ------------------------------------------*/ /* ----------------------- 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 ----------------------------------------*/ /* ----------------------- Variables ----------------------------------------*/
static eMBMasterEventType eMasterQueuedEvent;
static BOOL xMasterEventInQueue;
static struct rt_semaphore xMasterRunRes; static struct rt_semaphore xMasterRunRes;
static struct rt_event xMasterOsEvent; static struct rt_event xMasterOsEvent;
/* ----------------------- Start implementation -----------------------------*/ /* ----------------------- Start implementation -----------------------------*/
BOOL BOOL
xMBMasterPortEventInit( void ) xMBMasterPortEventInit( void )
{ {
xMasterEventInQueue = FALSE; rt_event_init(&xMasterOsEvent,"master event",RT_IPC_FLAG_PRIO);
return TRUE; return TRUE;
} }
BOOL BOOL
xMBMasterPortEventPost( eMBMasterEventType eEvent ) xMBMasterPortEventPost( eMBMasterEventType eEvent )
{ {
xMasterEventInQueue = TRUE; rt_event_send(&xMasterOsEvent, eEvent);
eMasterQueuedEvent = eEvent;
return TRUE; return TRUE;
} }
BOOL BOOL
xMBMasterPortEventGet( eMBMasterEventType * eEvent ) xMBMasterPortEventGet( eMBMasterEventType * eEvent )
{ {
BOOL xEventHappened = FALSE; rt_uint32_t recvedEvent;
/* waiting forever OS event */
if( xMasterEventInQueue ) rt_event_recv(&xMasterOsEvent,
{ EV_MASTER_READY | EV_MASTER_FRAME_RECEIVED | EV_MASTER_EXECUTE |
*eEvent = eMasterQueuedEvent; EV_MASTER_FRAME_SENT | EV_MASTER_ERROR_PROCESS,
xMasterEventInQueue = FALSE; RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER,
xEventHappened = TRUE; &recvedEvent);
} /* the enum type couldn't convert to int type */
return xEventHappened; switch (recvedEvent)
{
case EV_MASTER_READY:
*eEvent = EV_MASTER_READY;
break;
case EV_MASTER_FRAME_RECEIVED:
*eEvent = EV_MASTER_FRAME_RECEIVED;
break;
case EV_MASTER_EXECUTE:
*eEvent = EV_MASTER_EXECUTE;
break;
case EV_MASTER_FRAME_SENT:
*eEvent = EV_MASTER_FRAME_SENT;
break;
case EV_MASTER_ERROR_PROCESS:
*eEvent = EV_MASTER_ERROR_PROCESS;
break;
}
return TRUE;
} }
/** /**
* This function is initialize the OS resource for modbus master. * 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. * Note:The resource is define by OS.If you not use OS this function can be empty.
@ -73,7 +83,6 @@ xMBMasterPortEventGet( eMBMasterEventType * eEvent )
*/ */
void vMBMasterOsResInit( 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); rt_sem_init(&xMasterRunRes, "master res", 0x01 , RT_IPC_FLAG_PRIO);
} }
@ -118,7 +127,7 @@ void vMBMasterErrorCBRespondTimeout(UCHAR ucDestAddress, const UCHAR* pucPDUData
* @note This code is use OS's event mechanism for modbus master protocol stack. * @note This code is use OS's event mechanism for modbus master protocol stack.
* If you don't use OS, you can change it. * If you don't use OS, you can change it.
*/ */
rt_event_send(&xMasterOsEvent, EVENT_MASTER_ERROR_RESPOND_TIMEOUT); rt_event_send(&xMasterOsEvent, EV_MASTER_ERROR_RESPOND_TIMEOUT);
/* You can add your code under here. */ /* You can add your code under here. */
@ -140,7 +149,7 @@ void vMBMasterErrorCBReceiveData(UCHAR ucDestAddress, const UCHAR* pucPDUData,
* @note This code is use OS's event mechanism for modbus master protocol stack. * @note This code is use OS's event mechanism for modbus master protocol stack.
* If you don't use OS, you can change it. * If you don't use OS, you can change it.
*/ */
rt_event_send(&xMasterOsEvent, EVENT_MASTER_ERROR_RECEIVE_DATA); rt_event_send(&xMasterOsEvent, EV_MASTER_ERROR_RECEIVE_DATA);
/* You can add your code under here. */ /* You can add your code under here. */
@ -162,7 +171,7 @@ void vMBMasterErrorCBExecuteFunction(UCHAR ucDestAddress, const UCHAR* pucPDUDat
* @note This code is use OS's event mechanism for modbus master protocol stack. * @note This code is use OS's event mechanism for modbus master protocol stack.
* If you don't use OS, you can change it. * If you don't use OS, you can change it.
*/ */
rt_event_send(&xMasterOsEvent, EVENT_MASTER_ERROR_EXECUTE_FUNCTION); rt_event_send(&xMasterOsEvent, EV_MASTER_ERROR_EXECUTE_FUNCTION);
/* You can add your code under here. */ /* You can add your code under here. */
@ -179,7 +188,7 @@ void vMBMasterCBRequestScuuess( void ) {
* @note This code is use OS's event mechanism for modbus master protocol stack. * @note This code is use OS's event mechanism for modbus master protocol stack.
* If you don't use OS, you can change it. * If you don't use OS, you can change it.
*/ */
rt_event_send(&xMasterOsEvent, EVENT_MASTER_PROCESS_SUCESS); rt_event_send(&xMasterOsEvent, EV_MASTER_PROCESS_SUCESS);
/* You can add your code under here. */ /* You can add your code under here. */
@ -199,26 +208,26 @@ eMBMasterReqErrCode eMBMasterWaitRequestFinish( void ) {
rt_uint32_t recvedEvent; rt_uint32_t recvedEvent;
/* waiting for OS event */ /* waiting for OS event */
rt_event_recv(&xMasterOsEvent, rt_event_recv(&xMasterOsEvent,
EVENT_MASTER_PROCESS_SUCESS | EVENT_MASTER_ERROR_RESPOND_TIMEOUT EV_MASTER_PROCESS_SUCESS | EV_MASTER_ERROR_RESPOND_TIMEOUT
| EVENT_MASTER_ERROR_RECEIVE_DATA | EV_MASTER_ERROR_RECEIVE_DATA
| EVENT_MASTER_ERROR_EXECUTE_FUNCTION, | EV_MASTER_ERROR_EXECUTE_FUNCTION,
RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER,
&recvedEvent); &recvedEvent);
switch (recvedEvent) switch (recvedEvent)
{ {
case EVENT_MASTER_PROCESS_SUCESS: case EV_MASTER_PROCESS_SUCESS:
break; break;
case EVENT_MASTER_ERROR_RESPOND_TIMEOUT: case EV_MASTER_ERROR_RESPOND_TIMEOUT:
{ {
eErrStatus = MB_MRE_TIMEDOUT; eErrStatus = MB_MRE_TIMEDOUT;
break; break;
} }
case EVENT_MASTER_ERROR_RECEIVE_DATA: case EV_MASTER_ERROR_RECEIVE_DATA:
{ {
eErrStatus = MB_MRE_REV_DATA; eErrStatus = MB_MRE_REV_DATA;
break; break;
} }
case EVENT_MASTER_ERROR_EXECUTE_FUNCTION: case EV_MASTER_ERROR_EXECUTE_FUNCTION:
{ {
eErrStatus = MB_MRE_EXE_FUN; eErrStatus = MB_MRE_EXE_FUN;
break; break;

View File

@ -87,6 +87,8 @@ GraphEnabled=0
ShowTimeLog=1 ShowTimeLog=1
ShowTimeSum=1 ShowTimeSum=1
SumSortOrder=0 SumSortOrder=0
[Breakpoints2]
Count=0
[Trace2] [Trace2]
Enabled=0 Enabled=0
ShowSource=0 ShowSource=0
@ -111,5 +113,3 @@ Mode=3
Graph=0 Graph=0
Symbiont=0 Symbiont=0
Exclusions= Exclusions=
[Breakpoints2]
Count=0