- 23
- 0
- 约 13页
- 2020-03-13 发布于江西
- 举报
1. FreeModbus 协议分析
协议必须首先调用初始化功能 eMBinit()函数。后调用 eMBEnable(),最后,在循环体或者 单独一个任务中调用 eMBPoll()函数。
2. 应用层协议
2.1.
系统的启动
2.1.1. eMBInit()函数的源码分析
以 RTU 方式为例,首先,检查调用的地址是否合法。如不合法,返回错误。如果合法则 继续执行,
首先,针对 RTU 方式还是 ASCII 方式,选择不同的编译模块。
对需要调用的函数指针进行复制。如果移植需要改变其他用途,则要修改相应的指针,包 括如下赋值:
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);具体初始化 通讯端口。
2.1.2. eMBRTUInit
eMBRTUInit 这个函数主要干两件事:
第一, 初始化串口:
if( xMBPortSerialInit(ucPort, ulBaudRate, 8, eParity ) != TRUE )
{
eStatus = MB_EPORTERR;
}
这个函数在 portserial.c 中,需要用户在移植的时候根据自己的处理器编写。
第二, 初始化计时器:首先要根据波特率计算一下是 3.5~5.0 个字节周期的时间,然后再 调用 xMBPortTimersInit( ( USHORT ) usTimerT35_50us),初始化计时器。这个函数在 porttimer.c 中,需要用户在移植的时候根据自己的处理器编写。
2.1.3. eMBEnable 源码分析
首先,看看 Modbus 功能是否是被关闭的,如果不是被关闭(可能是没有被初始化或者已 经打开),就返回错误。
如果是 disable 状态,就干下面两件事:
l 调用 pvMBFrameStartCur()。由于这是个函数指针,在模块 eMBInit 中,指向了 eMBRTUStart 函数
n 在源代码中有这样一段注释:,意思是,首先设置成 STATE_RX_INIT,然后打开计时 器,等待 t3.5 以后,进入 STATE_RX_IDLE 状态。
n 看源代码中,首先有设置 Receiver 的状态,后调用 vMBPortSerialEnable,设置接收状 态,然后打开定时器。
n 当定时器中断后,自动调用中断服务程序,在中断服务程序中,只调用了 pxMBPortCBTimerExpired,而这是一个函数指针,在 RTU 方式初始化时,被指向了 xMBRTUTimerT35Expired()函数。
n xMBRTUTimerT35Expired 函数在 mbrtu.c 中,在这里,我们只看第一种方式,就是进 入初始化状态,在 t35 时间以后,只调用了一个 xNeedPoll = xMBPortEventPost( EV_READY );
n xMBPortEventPost 函数就是在事件队列里加了一个 EV_RDY 事件。
l 然后,将 eMB 状态改为使能状态,
l 初始化结束。
2.2.
总线侦听 eMBPoll()
首先,判断系统是否被使能,如果没有,则返回错误值。
然后,检查是否有事件发生,如果有,则根据不同类型的事件响应:
l 如果是 EV_RDY,表示系统刚刚进入侦听状态,则什么都不做;
l 如果状态为 EV_FRAME_RECEIVED,也就是接收到完整的帧,做下面两件事情:
n 调用 eStatus=peMBFrameReceiveCur( ucRcvAddress,ucMBFrame, usLength)。 这是一个函数指针,在 eMBInit 中,被初始化指向 eMBRTUReceive。
n eMBRTUReceive 这个函数首先校验帧的长度和 CRC,然后从协议中解析出地址、数据 和长度。
n 然后检查地址,如果是广播地址或者是本机地址,就调用 xMBP
原创力文档

文档评论(0)