在之前的文章《Freemodbus原理分析》,结合代码对 freemodbus 进行了分析,这里对 freemodbus机制做一下分析小结。freemodbus 的应用场景 主要是在 非linux下的 单片机系统,当然了,freemodbus 1.6 版本也开始支持了 linux,不过在linux下,如果不是一定要移植源码的话,个人觉得 libmodbus 相比 freemodus 还是更方便一些,功能更加灵活而且丰富。当然如果是 普通单片机系统,freemodbus 是一个不错的 开源modbus 从机 功能,不仅代码开源,重要的是非常稳定可靠。
这里先简单的 从文字的角度 来分析一下 freemodbus 从机的 实现机制,freemodbus 将状态机 的编程思想 用到了机制,作为从机,最基本的就是串口接收,而modbus通信的数据 接收长度是不定的,这一点,freemodbus v1.5 版本是采用
串口中断 + 定时器 的方式实现 接收不定长数据的。在freemodbus V1.6版本中,作者为了兼容linux和非linux 单片机系统代码统一,通过select机制进行接收数据,然后再 重新的 模拟实现 逐字节的 接收 机制,每接收1个字节,复位一下定时器,接收完成后,等待定时器溢出,更新状态标志。也就是不管是1.5版本还是1.6版本,都是通过 定时器溢出,然后更新接收完成标志,一旦接收完成后,套路是一样的,地址校验、功能码筛选,根据不同的功能码,执行不同的动作指令。
还有一点,就是串口的收、发都是通过中断,默认是接收中断使能,发送中断禁止,接收完成后,打包好 返回的数据帧,使能串口发送中断,然后通过 发送中断 发送数据。在linux 系统下,没有使用 硬中断,而是采用 通过不同的标志来区分的,接收使能时,通过select 阻塞接收,发送使能时,就发送数据。
最后就是
volatile UCHAR ucRTUBuf[MB_SER_PDU_SIZE_MAX];
它是一个全局的 数据缓存,不仅存放 接收的数据,还存放 发送的数据,具体表现为,当处于接收状态时,将接收的字节存放到
ucRTUBuf 中,然后 筛选出 地址、功能码、起始地址、长度等有效数据,然后进行对应功能码的 操作,到这里 ucRTUBuf里的内容就不重要了,将需要返回的数据,按照协议逐个填充到 ucRTUBuf 中,当然要记录并计算出 要发送的 数据帧长度,然后再通过串口返回给 主机(客户端)。我们在理解源码时,部分可能难以理解的原因就是,使用了很多的局部 指针变量,还有二级指针,但是这些指针最终都是 指向 ucRTUBuf的,了解到这一点,就便于我们 去理解源码了。