此篇博客将按照Freemodbus的运行流程,对各个函数进行解析(无主机RTU模式),
我将尽我所能解释的尽量清楚,如有错误或者语义模糊处还请在评论区指出,谢谢。
文章目录
1、eMBInit(…)
首先我们来看mb.h里的说明注释
eMBErrorCode
eMBInit( eMBMode eMode, UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity );
/* ----------------------- 函数原型------------------------------*/
-
\简要说明:初始化modbus协议栈
-
该函数初始化ASCII或RTU模块,
-
并调用porting layer的init函数来配置硬件部分。
-
请注意,直到eMBEnable()被调用之前,
-
Receiver一直是禁用的,没有Modbus帧被处理。
-
\参数1:eMode 选择 ASCII or RTU 模式.
-
\参数2:ucSlaveAddress 从机地址
-
\参数3:ucPort 端口。例如windows上的COM1。这个值跟平台有关系,一些端口干脆忽略它。(我也忽略了,直接填0)
-
\参数4:ulBaudRate 波特率
-
\参数5:eParity 校验方式
-
\返回值:没错返回 MB_ENOERR.
-
没错然后,该协议处于禁用状态,并准备通过调用eMBEnable()激活。
-
Otherwise one of the following error codes
-
is returned:
-
- eMBErrorCode::MB_EINVAL 从机地址无效,有效的地址范围1 - 247
-
- eMBErrorCode::MB_EPORTERR porting layer返回错误
小结:从上面可以看出eMBInit(…)函数就是做一些初始化的
eMBErrorCode点击跳转定义
eMBInit( eMBMode eMode, UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity )
{
eMBErrorCode eStatus = MB_ENOERR;
if( ( ucSlaveAddress = = MB_ADDRESS_BROADCAST ) ||
( ucSlaveAddress < MB_ADDRESS_MIN ) || ( ucSlaveAddress > MB_ADDRESS_MAX ) )
{
eStatus = MB_EINVAL;
}
else
{
ucMBAddress = ucSlaveAddress;首先判断从机地址对不对
switch ( eMode )
{ 这里给函数指针赋值 ,根据不同的帧格式来执行不同的操作
#if MB_RTU_ENABLED > 0
case MB_RTU:点击跳转函数指针定义
pvMBFrameStartCur = eMBRTUStart;
pvMBFrameStopCur = eMBRTUStop;
peMBFrameSendCur = eMBRTUSend;
peMBFrameReceiveCur = eMBRTUReceive;
pvMBFrameCloseCur = MB_PORT_HAS_CLOSE ? vMBPortClose : NULL;
pxMBFrameCBByteReceived = xMBRTUReceiveFSM;
pxMBFrameCBTransmitterEmpty = xMBRTUTransmitFSM;
pxMBPortCBTimerExpired = xMBRTUTimerT35Expired;
eStatus = eMBRTUInit( ucMBAddress, ucPort, ulBaudRate, eParity );
break;点击跳转eMBRTUInit函数
#endif
#if MB_ASCII_ENABLED > 0
case MB_ASCII:
pvMBFrameStartCur = eMBASCIIStart;
pvMBFrameStopCur = eMBASCIIStop;
peMBFrameSendCur = eMBASCIISend;
peMBFrameReceiveCur = eMBASCIIReceive;
pvMBFrameCloseCur = MB_PORT_HAS_CLOSE ? vMBPortClose : NULL;
pxMBFrameCBByteReceived = xMBASCIIReceiveFSM;
pxMBFrameCBTransmitterEmpty = xMBASCIITransmitFSM;
pxMBPortCBTimerExpired = xMBASCIITimerT1SExpired;
eStatus = eMBASCIIInit( ucMBAddress, ucPort, ulBaudRate, eParity );
break;
#endif
default:
eStatus = MB_EINVAL;
}
/* port dependent event module initalization failed. */
if( eStatus == MB_ENOERR ) 如果前面的初始化没错,进行接下来的任务
{
if( !xMBPortEventInit( ) ) 注意,这里是!点击跳转xMBPortEventInit函数
{
eStatus = MB_EPORTERR; 端口事件模块初始化失败。
}
else
{
eMBCurrentMode = eMode;
eMBState = STATE_DISABLED;一切正常就会来到这里
}
}
}
return eStatus;
}