G-CAMS-DATU/packages/agile_modbus-v1.1.2/examples/README.md

208 lines
5.4 KiB
Markdown
Raw Normal View History

2024-05-13 08:08:47 +00:00
# 示例说明
## 1、介绍
该示例提供 RTU / TCP 主机和从机的功能演示。
`WSL``Linux` 下使用 `gcc` 可直接 `make all` 编译出所有示例,在电脑上运行测试程序。
目录结构:
| 名称 | 说明 |
| ---- | ---- |
| common | 公用源码 |
| figures | 素材 |
| rtu_master | RTU 主机示例 |
| tcp_master | TCP 主机示例 |
| slave | RTU + TCP 从机示例 |
| rtu_p2p | RTU 点对点传输文件 |
| rtu_broadcast | RTU 广播传输文件 (粘包处理示例) |
## 2、使用
需要准备的工具如下:
- 虚拟串口软件
- Modbus Poll
- Modbus Slave
命令行敲击 `make clean``make all`
### 2.1、主机
- RTU (rtu_master)
- 使用虚拟串口软件虚拟出一对串口
![VirtualCom](./figures/VirtualCom.jpg)
- 打开 `Modbus Slave` ,按下图设置
![ModbusSlaveSetup](./figures/ModbusSlaveSetup.jpg)
- `Modbus Slave` 连接,按下图设置
![ModbusSlaveRTUConnection](./figures/ModbusSlaveRTUConnection.jpg)
- 进入 `rtu_master` 目录,`./RtuMaster /dev/ttySX` 运行 `RTU` 主机示例,`ttySX` 为一对虚拟串口中的另一个
![RTUMaster](./figures/RTUMaster.jpg)
- TCP (tcp_master)
- 打开 `Modbus Slave``SetUp` 设置同 `RTU` 一致
- `Modbus Slave` 连接,按下图设置
![ModbusSlaveTCPConnection](./figures/ModbusSlaveTCPConnection.jpg)
- 进入 `tcp_master` 目录,`./TcpMaster 127.0.0.1 502` 运行 `TCP` 主机示例
![TCPMaster](./figures/TCPMaster.jpg)
### 2.2、从机
- 该示例 (slave) 同时提供 `RTU``TCP` 从机功能演示,控制的是同一片内存。`TCP` 最大可接入 5 个客户端,每个客户端无数据超时为 10s, 10s 后自动断开。
- 示例支持所有功能码(除了功能码 0x07)。
-`bit`、`input_bit`、`register`、`input_register` 寄存器每个文件单独定义。
- 使用 `agile_modbus_slave_util_callback`
- 寄存器地址域:
| 寄存器 | 地址范围 |
| --- | --- |
| 线圈寄存器 | 0x041A ~ 0x0423 (1050 ~ 1059) |
| 离散量输入寄存器 | 0x041A ~ 0x0423 (1050 ~ 1059) |
| 保持寄存器 | 0xFFF6 ~ 0xFFFF (65526 ~ 65535) |
| 输入寄存器 | 0xFFF6 ~ 0xFFFF (65526 ~ 65535) |
**注意**: 读写其他地址寄存器都能成功,但值都为 0。
使用:
- 使用虚拟串口软件虚拟出一对串口
![VirtualCom](./figures/VirtualCom.jpg)
- 进入 `slave` 目录,`./ModbusSlave /dev/ttyS2 1025` 运行示例
/dev/ttySX: 虚拟串口中的一个
1025监听端口号如果不是 `root` 权限,端口号必须大于 `1024`
- 打开 `Modbus Poll` 按下图设置和连接 RTU
![ModbusPollSetup](./figures/ModbusPollSetup.jpg)
![ModbusPollRTUConnection](./figures/ModbusPollRTUConnection.jpg)
- 打开 5 个 `Modbus Poll` ,设置同 RTU连接如下图
![ModbusPollTCPConnection](./figures/ModbusPollTCPConnection.jpg)
- 效果演示
![ModbusSlaveShow](./figures/ModbusSlaveShow.jpg)
- 超时断开演示
`Modbus Poll` 的 poll 界面关闭,看控制台打印可以看到 close 报文。
![ModbusSlaveTimeoutShow](./figures/ModbusSlaveTimeoutShow.jpg)
### 2.3、RTU 传输文件
![ModbusProtocol](./figures/ModbusProtocol.jpg)
使用 `0x50` 作为传输文件的特殊功能码。
分包传输文件数据,每包数据最大 1024 字节。
`Data` 字段协议定义:
- 主机请求
| 命令 | 字节数 | 数据 |
| ---- | ---- | ---- |
| 2 Bytes | 2 Bytes | N Bytes |
命令:
| 命令 | 说明 | 数据 |
| ---- | ---- | ---- |
| 0x0001 | 开始发送 | 文件大小(4 Bytes) + 文件名称(字符串) |
| 0x0002 | 传输数据 | 标志(1 Byte) + 文件数据 |
标志:
| 状态 | 说明 |
| ---- | ---- |
| 0x00 | 最后一包数据 |
| 0x01 | 不是最后一包数据 |
- 从机响应
| 命令 | 状态 |
| ---- | ---- |
| 2 Bytes | 1 Byte |
状态:
| 状态 | 说明 |
| ---- | ---- |
| 0x00 | 失败 |
| 0x01 | 成功 |
- 使用虚拟串口软件虚拟出 3 个串口,组成串口群组
这里我使用的时 MX 虚拟串口
![VirtualComGroup](./figures/VirtualComGroup.jpg)
#### 2.3.1、点对点传输
- 进入 `rtu_p2p` 目录,打开 `Linux Shell`,演示效果如下
**注意**:
- 传输的文件必须是一般文件,像可执行文件、目录等不支持
- 文件路径必须是 `Linux` 环境下的路径
- 从机接收到数据后修改文件名称 (从机地址_原文件名) 写入在当前目录。
![rtu_p2p](./figures/rtu_p2p.gif)
#### 2.3.2、广播传输
该例子主要演示 `agile_modbus_slave_handle``frame_length` 的用处。
`broadcast_master` 中,使用广播地址 0周期 5ms 发送数据包。同时每包数据后都发送 100 字节的脏数据。
```C
int send_len = agile_modbus_serialize_raw_request(ctx, raw_req, raw_req_len);
serial_send(_fd, ctx->send_buf, send_len);
//脏数据
serial_send(_fd, _dirty_buf, sizeof(_dirty_buf));
```
在如此快速的数据流下,`broadcast_slave` 必须使用 `agile_modbus_slave_handle``frame_length` 参数来对粘包进行处理。
- 进入 `rtu_broadcast` 目录,打开 `Linux Shell`,演示效果如下
**注意**:
- 传输的文件必须是一般文件,像可执行文件、目录等不支持
- 文件路径必须是 `Linux` 环境下的路径
- 从机接收到数据后修改文件名称 (从机地址_原文件名) 写入在当前目录。
![rtu_broadcast](./figures/rtu_broadcast.gif)