eMbPoll()的作用是FreeMod协议通信过程中不断查询事件对列有无完速数据桢,并进行地址和CRD验证,最后运行和回复主机。

为了减小代码尺寸对eMbPoll进行改进:

原版:

   1:  
   2: eMBErrorCode
void )
   4: {
static UCHAR   *ucMBFrame;
static UCHAR    ucRcvAddress;
static UCHAR    ucFunctionCode;
static USHORT   usLength;
static eMBException eException;
  10:  
int             i;
  12:     eMBErrorCode    eStatus = MB_ENOERR;
  13:     eMBEventType    eEvent;
  14:  
/* Check if the protocol stack is ready. */
if( eMBState != STATE_ENABLED )
  17:     {
return MB_EILLSTATE;
  19:     }
  20:  
/* Check if there is a event available. If not return control to caller.
     * Otherwise we will handle the event. */
TRUE )
  24:     {
switch ( eEvent )
  26:         {
case EV_READY:
break;
  29:  
case EV_FRAME_RECEIVED:
  31:             eStatus = peMBFrameReceiveCur( &ucRcvAddress, &ucMBFrame, &usLength );
if( eStatus == MB_ENOERR )
  33:             {
/* Check if the frame is for us. If not ignore the frame. */
if( ( ucRcvAddress == ucMBAddress ) || ( ucRcvAddress == MB_ADDRESS_BROADCAST ) )
  36:                 {
void )xMBPortEventPost( EV_EXECUTE );
  38:                 }
  39:             }
break;
  41:  
case EV_EXECUTE:
  43:             ucFunctionCode = ucMBFrame[MB_PDU_FUNC_OFF];
  44:             eException = MB_EX_ILLEGAL_FUNCTION;
for( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ )
  46:             {
/* No more function handlers registered. Abort. */
if( xFuncHandlers[i].ucFunctionCode == 0 )
  49:                 {
break;
  51:                 }
if( xFuncHandlers[i].ucFunctionCode == ucFunctionCode )
  53:                 {
  54:                     eException = xFuncHandlers[i].pxHandler( ucMBFrame, &usLength );
break;
  56:                 }
  57:             }
  58:  
/* If the request was not sent to the broadcast address we
             * return a reply. */
if( ucRcvAddress != MB_ADDRESS_BROADCAST )
  62:             {
if( eException != MB_EX_NONE )
  64:                 {
/* An exception occured. Build an error frame. */
  66:                     usLength = 0;
  67:                     ucMBFrame[usLength++] = ( UCHAR )( ucFunctionCode | MB_FUNC_ERROR );
  68:                     ucMBFrame[usLength++] = eException;
  69:                 }
if( ( eMBCurrentMode == MB_ASCII ) && MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS )
  71:                 {
  72:                     vMBPortTimersDelay( MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS );
  73:                 }                
  74:                 eStatus = peMBFrameSendCur( ucMBAddress, ucMBFrame, usLength );
  75:             }
break;
  77:  
case EV_FRAME_SENT:
break;
  80:         }
  81:     }
return MB_ENOERR;
  83: }

 

改进后的eMbPoll():

   1:  
void ){
   3:   
static UCHAR   *ucMBFrame;
static UCHAR    ucFunctionCode;
static USHORT   usLength;
static eMBException eException;
   8:   eMBEventType    eEvent;
   9:   UCHAR i;
  10:   USHORT usCRC16;
//桢事件判断
if(eEvent == EV_FRAME_RECEIVED){    
//最小桢判断
return;
//CRC判断
return;
//地址    
  18:         ucMBFrame = (UCHAR *) &ucRTUBuf[MB_SER_PDU_PDU_OFF];    
  19:         usLength = (USHORT)( usRcvBufferPos - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_CRC);
  20:         ucFunctionCode = ucMBFrame[MB_PDU_FUNC_OFF];
  21:         eException = MB_EX_ILLEGAL_FUNCTION;
//执行功能码
if( xFuncHandlers[i].ucFunctionCode == 0 ){
return;
  25:           }
if( xFuncHandlers[i].ucFunctionCode == ucFunctionCode ){
  27:             eException = xFuncHandlers[i].pxHandler( ucMBFrame, &usLength );
break;                               
  29:           }
  30:       }
//回复主机
//错误码         
  33:           usLength = 0;
  34:           ucMBFrame[usLength++] = ( UCHAR )( ucFunctionCode | MB_FUNC_ERROR );
  35:           ucMBFrame[usLength++] = eException;
  36:         } 
//发送
  38:           pucSndBufferCur = ( UCHAR * ) ucMBFrame - 1;
  39:           pucSndBufferCur[MB_SER_PDU_ADDR_OFF] = ucMBAddress;
  40:           usSndBufferCount = usLength + 1;      
  41:           usCRC16 = usMBCRC16( ( UCHAR * ) pucSndBufferCur, usSndBufferCount );
  42:           ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF );
  43:           ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 );    
  44:           eSndState = STATE_TX_XMIT;
TRUE );
//发送结束
//回复结束
//地址判断
//桢事件判断
  50:   }
  51: }

 

改进说明:

1、eMbPoll()调用一次即可运行功能码和回复主机;

2、省去独立的接收函数peMBFrameReceiveCur( &ucRcvAddress, &ucMBFrame, &usLength ); 而直接操作,(其实里面对算出数据桢的启始位置、和长度);

3、省去发送函数peMBFrameSendCur( ucMBAddress, ucMBFrame, usLength ); 而直接操作;

4、省去返回值,因为调用处没有使用;

5、对功能的遍历i改成unsigned char类型,省去ucRcvAddress和eMBErrorCode    eStatus = MB_ENOERR; 变量,

6、功能兼容原版本。

 

eMbPoll的经典之处在于功能的运行,——》函数指针,这部分在其它笔记中记录。

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-07-29
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-11-21
相关资源
相似解决方案