小言_互联网的博客

libmodbus源码分析(2)主机(客户端)功能源码分析

408人阅读  评论(0)

在上一篇文章《 libmodbus 源码分析(1)基本框架、关键数据结构、接口 》中,分析了libmodbus的源码基本框架和关键的数据结构、接口,本文就分析一下 libmodbus 作为 主机(客户端)的功能源码实现,这里我们以 modbus rtu 协议 的读 4x 区保持寄存器功能 进行举例说明,

我们简单的写一下 modbus rtu 下读 4x 区保持寄存器的 伪代码 流程:


  
  1. int main()
  2. {
  3. modbus_t *ctx = NULL;
  4. uint16_t tab_rp_register[ 200]; // 不一定是200个,根据自己的需要来定义
  5. /* 创建并初始化 modbus_t 指针 */
  6. ctx = modbus_new_rtu( "/dev/ttyUSB1", 115200, 'N', 8, 1);
  7. /* 设置 错误 恢复模式 */
  8. modbus_set_error_recovery(ctx,
  9. MODBUS_ERROR_RECOVERY_LINK |
  10. MODBUS_ERROR_RECOVERY_PROTOCOL);
  11. /* 设置 从机 (服务器) 地址, 支持运行中 设定,也就是可以 实现多从机的轮询 */
  12. modbus_set_slave(ctx, SERVER_ID);
  13. /* 4x区保持寄存器 的读 功能, 从 地址 start_addr开始,共读 nb 个寄存器
  14. * 读到的寄存器值存放到 tab_rp_registers 中
  15. */
  16. modbus_read_registers(ctx, start_addr, nb, tab_rp_registers);
  17. /* 关闭 modbus */
  18. modbus_close( ctx );
  19. /* 释放 modbus 资源 */
  20. modbus_free( ctx );
  21. }

 上面的伪代码是 是读1次的实现,如果想要对不同的从设备进行轮询,我们只需要在while(1)循环中 先设定 从设备地址,然后再 调用 modbus_read_registers即可。

   上面的代码中,大部分的接口函数都是比较容易理解,只有 modbus_read_registers 相对复杂一些,因为它实现的功能也比较多,分别为:

 ① 创建并打包 读命令。

 ② 发送 步骤①中的读指令。

 ③ 接收从机返回数据,分三次接收数据,先接收前2个字节(功能),再接收 第3个字节(数据长度),再接收剩下的字节数。

     选择3次进行接收,一方面是为了随时校验,在linux下接收不定长数据的实现不太方便,所以根据modbus协议框架,先接收 到总数据长度,然后就能按照指定长度进行接收。

 ④ 对返回数据 进行各种校验,比如设备地址,地址、数量、CRC校验等。

 ⑤ 将正确的返回 有效数据 存放到 我们指定的 缓存中。

 接下来就通过层层的调用关系来分析该代码功能,如下图所示:

 其他的 modbus_read_xxx和write功能代码实现与上面的类似。


转载:https://blog.csdn.net/u012351051/article/details/104088551
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场