ADU 》 应用数据单元,每个MODBUS帧
PDU 》 协议数据单元,除设备地址及CRC校验码的数据
Modbus从设备
字符接收:
串口字符中断 》RTUReceiveFSM 》读取一个字节 》保存至接收缓冲区,同时启动T3.5定时器(帧与帧之间需间隔至少3.5个字符传输时间);
每次收到新字符,定时器都会被重置,直至T3.5超时,表示一个MODBUS帧结束
定时器超时后:
发出FRAME_RECEIVED事件
主线程:
收到FRAME_RECEIVED事件后,对帧进行CRC校验,并从中获取到从机地址、帧数据起始地址以及帧数据长度,当帧地址为本机地址或广播地址时,发出EV_EXECUTE事件
收到EV_EXECUTE事件后,从帧数据中取得功能码,并依据功能码调用相应的处理函数,相同的帧数据地址用于保存处理结果数据,并返回结果数据的长度,然后调用RTUSend函数,通知发送任务进行数据发送
注意:
- T3.5超时到函数被处理这段时间内,如果有新的帧进来,因共享缓冲区的原因,数据帧将会被破坏,需要注意
- MODBUS-RTU是按照数据传输间的空闲时间作为帧与帧之间区分的依据,所以串口接收不能使用缓冲区,必须实时处理,以满足时序要求
Modbus主设备
主设备功能是由从设备移植而来,所以基本流程与从设备一致,流程如下:
- 应用任务填充PDU数据至发送缓冲区中,然后发送MASTER_FRAME_SENT事件,等待发送完成
- 主功能线程收到MASTER_FRAME_SENT事件后,调用MasterRTUSend函数,添加CRC校验码后,启动发送线程
- 发送线程调用MasterRTUTransmitFSM函数,送出所有数据,然后判断如果为广播模式,则启动广播命令固定延时定时器,否则启动等待从设备响应定时器
- 接收到从设备数据后,停止等待接收定时器,启动T3.5定时器
- T3.5定时器超时后,发送MASTER_FRAME_RECEIVED事件,通知主线程数据接收完成
- 主线程解析帧并获取从机地址、数据等信息,发送MASTER_EXECUTE事件
- 主线程收到MASTER_EXECUTE事件,根据功能码最高位判断是否发生异常,并解析出异常码
- 如果数据正常,则调用对应处理函数进行数据处理
注意:
- 主模式下定时器不再是单一的T3.5定时器,还有等待从设备响应超时定时,以及广播命令固定延时定时功能
- 定时器超时函数中,判断超时原因为接收等待超时,则发送MASTER_ERROR_PROCESS事件,主线程中根据超时类型调用对应的错误回调函数处理各种错误