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的,了解到这一点,就便于我们 去理解源码了。