本文主要是介绍libmodbus源码分析(2)主机(客户端)功能源码分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在上一篇文章《 libmodbus 源码分析(1)基本框架、关键数据结构、接口 》中,分析了libmodbus的源码基本框架和关键的数据结构、接口,本文就分析一下 libmodbus 作为 主机(客户端)的功能源码实现,这里我们以 modbus rtu 协议 的读 4x 区保持寄存器功能 进行举例说明,
我们简单的写一下 modbus rtu 下读 4x 区保持寄存器的 伪代码 流程:
int main()
{modbus_t *ctx = NULL;uint16_t tab_rp_register[200]; // 不一定是200个,根据自己的需要来定义/* 创建并初始化 modbus_t 指针 */ctx = modbus_new_rtu("/dev/ttyUSB1", 115200, 'N', 8, 1);/* 设置 错误 恢复模式 */modbus_set_error_recovery(ctx,MODBUS_ERROR_RECOVERY_LINK |MODBUS_ERROR_RECOVERY_PROTOCOL);/* 设置 从机 (服务器) 地址, 支持运行中 设定,也就是可以 实现多从机的轮询 */modbus_set_slave(ctx, SERVER_ID);/* 与从机建立连接 */modbus_connect(ctx);/* 4x区保持寄存器 的读 功能, 从 地址 start_addr开始,共读 nb 个寄存器 * 读到的寄存器值存放到 tab_rp_registers 中*/modbus_read_registers(ctx, start_addr, nb, tab_rp_registers);/* 关闭 modbus */modbus_close( ctx );/* 释放 modbus 资源 */modbus_free( ctx );
}
上面的伪代码是 是读1次的实现,如果想要对不同的从设备进行轮询,我们只需要在while(1)循环中 先设定 从设备地址,然后再 调用 modbus_read_registers即可。
上面的代码中,大部分的接口函数都是比较容易理解,只有 modbus_read_registers 相对复杂一些,因为它实现的功能也比较多,分别为:
① 创建并打包 读命令。
② 发送 步骤①中的读指令。
③ 接收从机返回数据,分三次接收数据,先接收前2个字节(功能),再接收 第3个字节(数据长度),再接收剩下的字节数。
选择3次进行接收,一方面是为了随时校验,在linux下接收不定长数据的实现不太方便,所以根据modbus协议框架,先接收 到总数据长度,然后就能按照指定长度进行接收。
④ 对返回数据 进行各种校验,比如设备地址,地址、数量、CRC校验等。
⑤ 将正确的返回 有效数据 存放到 我们指定的 缓存中。
接下来就通过层层的调用关系来分析该代码功能,如下图所示:
其他的 modbus_read_xxx和write功能代码实现与上面的类似。
这篇关于libmodbus源码分析(2)主机(客户端)功能源码分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!