freemodbus函数调用关系
2020-08-07 10:02:54 26 举报
AI智能生成
freemodbus的函数调用
作者其他创作
大纲/内容
运行
eMBInit(eMBMode eMode, UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity )
MB_RTU
pvMBFrameStartCur = eMBRTUStart
pvMBFrameStopCur = eMBRTUStop
peMBFrameSendCur = eMBRTUSend
peMBFrameReceiveCur = eMBRTUReceive
pvMBFrameCloseCur = MB_PORT_HAS_CLOSE ? vMBPortClose : NULL;
pxMBFrameCBByteReceived = xMBRTUReceiveFSM;
pxMBFrameCBTransmitterEmpty = xMBRTUTransmitFSM;
pxMBPortCBTimerExpired = xMBRTUTimerT35Expired;
eMBRTUInit( ucMBAddress, ucPort, ulBaudRate, eParity ); //串口初始化
xMBPortEventInit( )
xEventInQueue = FALSE;
return TRUE;
eMBCurrentMode = eMode;
eMBState = STATE_DISABLED;
eMBEnable()
pvMBFrameStartCur( );
eMBRTUStart
eRcvState = STATE_RX_INIT;
vMBPortSerialEnable( TRUE, FALSE );
vMBPortTimersEnable( );
__HAL_TIM_CLEAR_IT(&htim4,TIM_IT_UPDATE);
__HAL_TIM_SetCounter(&htim4,0);//这里一定要清零计数器
HAL_TIM_Base_Start_IT(&htim4);
eMBState = STATE_ENABLED;
eMBPoll()
xMBPortEventGet( &eEvent )
xEventHappened = FALSE;
if( xEventInQueue )
*eEvent = eQueuedEvent;
xEventInQueue = FALSE;
xEventHappened = TRUE;
return xEventHappened;
if( xEventInQueue )
*eEvent = eQueuedEvent;
xEventInQueue = FALSE;
xEventHappened = TRUE;
return xEventHappened;
if(xMBPortEventGet== TRUE))
case EV_READY:
break;
case EV_FRAME_RECEIVED:
eStatus = peMBFrameReceiveCur()
eMBRTUReceive
BOOL xFrameReceived = FALSE;
eMBErrorCode eStatus = MB_ENOERR;
assert( usRcvBufferPos < MB_SER_PDU_SIZE_MAX );
if( ( usRcvBufferPos >= MB_SER_PDU_SIZE_MIN )
&& ( usMBCRC16( ( UCHAR * ) ucRTUBuf, usRcvBufferPos ) == 0 ) )
&& ( usMBCRC16( ( UCHAR * ) ucRTUBuf, usRcvBufferPos ) == 0 ) )
*pucRcvAddress = ucRTUBuf[MB_SER_PDU_ADDR_OFF];
*pusLength = ( USHORT )( usRcvBufferPos - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_CRC );
*pucFrame = ( UCHAR * ) & ucRTUBuf[MB_SER_PDU_PDU_OFF];
xFrameReceived = TRUE;
else
eStatus = MB_EIO;
return eStatus;
if( eStatus == MB_ENOERR )
( void )xMBPortEventPost( EV_EXECUTE );
case EV_EXECUTE:
ucFunctionCode = ucMBFrame[MB_PDU_FUNC_OFF];
eException = MB_EX_ILLEGAL_FUNCTION;
for( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ )
if( xFuncHandlers[i].ucFunctionCode == 0 )
break;
else if( xFuncHandlers[i].ucFunctionCode == ucFunctionCode )
eException = xFuncHandlers[i].pxHandler( ucMBFrame, &usLength );
break;
if( ucRcvAddress != MB_ADDRESS_BROADCAST )
if( eException != MB_EX_NONE )
eException != MB_EX_NONE
usLength = 0;
ucMBFrame[usLength++] = ( UCHAR )( ucFunctionCode | MB_FUNC_ERROR );
ucMBFrame[usLength++] = eException;
if( ( eMBCurrentMode == MB_ASCII ) && MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS )
vMBPortTimersDelay( MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS );
eStatus = peMBFrameSendCur( ucMBAddress, ucMBFrame, usLength );
eMBRTUSend
if( eRcvState == STATE_RX_IDLE )
/* Now copy the Modbus-PDU into the Modbus-Serial-Line-PDU. */
pucSndBufferCur[MB_SER_PDU_ADDR_OFF] = ucSlaveAddress;
usSndBufferCount += usLength;
/* Calculate CRC16 checksum for Modbus-Serial-Line-PDU. */
usCRC16 = usMBCRC16( ( UCHAR * ) pucSndBufferCur, usSndBufferCount );
ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF );
ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 );
pucSndBufferCur[MB_SER_PDU_ADDR_OFF] = ucSlaveAddress;
usSndBufferCount += usLength;
/* Calculate CRC16 checksum for Modbus-Serial-Line-PDU. */
usCRC16 = usMBCRC16( ( UCHAR * ) pucSndBufferCur, usSndBufferCount );
ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF );
ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 );
/* Activate the transmitter. */
eSndState = STATE_TX_XMIT;
eSndState = STATE_TX_XMIT;
vMBPortSerialEnable( FALSE, TRUE );
else
eStatus = MB_EIO;
break;
case EV_FRAME_SENT:
break;
return MB_ENOERR;
定时器中断处理
HAL_TIM_PeriodElapsedCallback
prvvTIMERExpiredISR();
pxMBPortCBTimerExpired
xMBRTUTimerT35Expired;
BOOL xNeedPoll = FALSE;
switch ( eRcvState )
case STATE_RX_INIT:
xNeedPoll = xMBPortEventPost( EV_READY );
case STATE_RX_RCV:
xNeedPoll = xMBPortEventPost( EV_FRAME_RECEIVED );
case STATE_RX_ERROR:
default:
assert( ( eRcvState == STATE_RX_INIT ) ||
( eRcvState == STATE_RX_RCV ) || ( eRcvState == STATE_RX_ERROR ) );
( eRcvState == STATE_RX_RCV ) || ( eRcvState == STATE_RX_ERROR ) );
vMBPortTimersDisable( );
eRcvState = STATE_RX_IDLE;
return xNeedPoll;
串口中断处理
HAL_UART_RxCpltCallback
prvvUARTRxISR();
pxMBFrameCBByteReceived( );
xMBRTUReceiveFSM;
BOOL xTaskNeedSwitch = FALSE;
UCHAR ucByte;
assert( eSndState == STATE_TX_IDLE );
( void )xMBPortSerialGetByte( ( CHAR * ) & ucByte );
switch ( eRcvState )
case STATE_RX_INIT:
vMBPortTimersEnable( );
case STATE_RX_ERROR:
vMBPortTimersEnable( );
case STATE_RX_IDLE:
usRcvBufferPos = 0;
ucRTUBuf[usRcvBufferPos++] = ucByte;
eRcvState = STATE_RX_RCV;
vMBPortTimersEnable( );
case STATE_RX_RCV:
if( usRcvBufferPos < MB_SER_PDU_SIZE_MAX )
ucRTUBuf[usRcvBufferPos++] = ucByte;
else
eRcvState = STATE_RX_ERROR;
vMBPortTimersEnable( );
return xTaskNeedSwitch;
HAL_UART_TxCpltCallback
prvvUARTTxReadyISR();
pxMBFrameCBTransmitterEmpty();
xMBRTUTransmitFSM;
BOOL xNeedPoll = FALSE;
assert( eRcvState == STATE_RX_IDLE );
switch ( eSndState )
case STATE_TX_IDLE:
vMBPortSerialEnable( TRUE, FALSE );
case STATE_TX_XMIT:
if( usSndBufferCount != 0 )
xMBPortSerialPutByte( ( CHAR )*pucSndBufferCur );
pucSndBufferCur++; /* next byte in sendbuffer. */
usSndBufferCount--;
else
xNeedPoll = xMBPortEventPost( EV_FRAME_SENT );
vMBPortSerialEnable( TRUE, FALSE );
eSndState = STATE_TX_IDLE;
return xNeedPoll;
0 条评论
下一页