11.3.7 RTU/TCP关联接口函数
在文件modbus.h的最后位置,有如下语句
#include "modbus-tcp.h" #include "modbus-rtu.h"
可以发现,除了modbus.h包含的接口函数之外,modbus-rtu.h和modbus-tcp.h也包含了必要的接口函数。
1. RTU模式关联函数
MODBUS_API modbus_t * modbus_new_rtu(const char * device,int baud,char parity,int data_bit,int stop_bit):
此函数的功能是创建一个RTU类型的modbus_t结构体。参数constchar * device代表串口字符串,在Windows操作系统下形态如“COMx”,有一点需要注意的是,对于串口1串口9来说,传递“COM1”“COM9”可以成功,但是如果操作对象为COM10及以上端口,则会出现错误。
产生这种奇怪现象的原因是:微软预定义的标准设备中 含有“COM1”~“COM9”。所以,“COM1”~“COM9”作为文件名传递给函数时操作系统会自动地将之解析为相应的设备。但对于COM10及以上的串口,“COM10”之类的文件名系统只视之为 一般意义上的文件,而非串行设备。为了增加对COM10及以上串行端口的支持,微软规定,如果要访问这样的设备,应使用这样的文件名(以COM10 为例):\. COM10。
所以,使用时在代码中可以如此定义:
const char * device = “\\.\COM10”;
在Linux操作系统下可以使用“/dev/ttySo”或“/dev/ttyUSB0”等形式的字符串来表示。而参数int baud表示串口波特率的设置值,例如:9600、19200、57600、115200等。
参数char parity表示奇偶校验位,取值范围:
①‘N’:无奇偶校验;
②‘E’:偶校验;
③‘O’:奇校验。
参数int data_bit表示数据位的长度,取值范围为5、6、7和8。
参数int stop_bit表示停止位长度,取值范围为1或2。
用法举例:
左右滑动查看完整内容
modbus t *ctx; ctx=modbus_new_rtu("\\.\COM10",115200,'N',8,1); if (ctx ==NULL) { fprintf(stderr,"Unable to create the libmodbus context "); return -1; } modbus_set_slave(ctx,SLAVE_DEVICE_ID); if (modbus connect(ctx)==-1) { fprintf(stderr,"Connection failed:%s ",modbus_strerror(errno)); modbus_free(ctx); return -1; }
MODBUS_API int modbus_rtu_set_serial_mode (modbus_t * ctx,int mode):
该函数用于设置串口为MODBUS RTU RS232或MODBUSRTU_RS485模式,此函数只适用于Linux操作系统下。
左右滑动查看完整内容
MODBUS_API int modbus_rtu_set_rts (modbus_t * ctx, int mode)。 MODBUS_API int modbus_rtu_set_custom_rts (modbus_t * ctx, void ( * set_rts) (modbus_t * ctx, int on))。 MODBUS_API int modbus_rtu_set_rts_delay (modbus_t * ctx, int us)。
以上函数只适用于Linux操作系统下,RTS即Request ToSend的缩写,具体的意义可通过网络搜索,一般情况下,此类函数可忽略。
2. TCP模式关联函数
左右滑动查看完整内容
MODBUS_API modbus_t * modbus_new_tcp (const char *ip_address, int port)。
此函数的功能是创建一个TCP/IPv4类型的modbus_t结构体。
参数const char * ip_address为IP地址,port表示远端设备的端口号。
左右滑动查看完整内容
MODBUS_API int modbus_tcp_listen (modbus_t * ctx, int nb_connection)。
此函数创建并监听一个TCP/IPv4上的套接字。
参数int nb_connection代表最大的监听数量,在调用此函数之前,必须首先调用modbus_new_tcp()创建 modbus_t结构体。
MODBUS_API int modbus_tcp_accept(modbus_t * ctx,int * s)。
此函数接收一个TCP/IPv4类型的连接请求,如果成功将进入数据接收状态。
11.4 libmodbus移植
本节源码位于如下目录:
11.4.1 编译安装
libmodbus原生就支持Linux,所以不存在移植难度。
如下操作即可编译libmodbus:
左右滑动查看完整内容
$ source /opt/remi-sdk/environment-setup-aarch64-poky-linux $ tar xzf libmodbus-3.1.10.tar.gz $ cd libmodbus-3.1.10/ $ ./autogen.sh $ ./configure --prefix=$PWD/tmp --host=aarch64-poky-linux CFLAGS="-mtune=cortex-a55 -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wformat -Wformat-se curity -Werror=format-security --sysroot=/opt/remi-sdk/sysroots/aa rch64-poky-linux" $ make $ make install $ ls tmp/ include lib share // 复制到工具链里 $ sudo cp -rf tmp/include/* /opt/remi-sdk/sysroots/aarch64-poky-linux/usr/include/ $ sudo cp -rfd tmp/lib/* /opt/remi-sdk/sysroots/aarch64-poky-linux/usr/lib64/ $ ls tests/.libs/ bandwidth-client bandwidth-server-one random-test-server unit-test-server bandwidth-server-many-up random-test-client unit-test-client version
在“tmp/include”目录下生成了有文件,在“tmp/lib”目录下生成了库文件。在“tests/.libs/”目录下生成了测试程序“unit-test-server”、“unit-test-client”。
把库复制到开发板上,在Ubuntu上执行如下命令:
左右滑动查看完整内容
$ scp tmp/lib/*so* root@192.168.5.9:/usr/lib64/
11.4.2 上机测试
把测试程序和库复制到开发板上,在Ubuntu上执行如下命令:
左右滑动查看完整内容
$ scp tests/.libs/unit-test-server root@192.168.5.9:/home/root $ scp tests/.libs/unit-test-client root@192.168.5.9:/home/root
在开发板上执行如下命令,通过Modbus TCP协议进行测试:
左右滑动查看完整内容
root@myir-remi-1g:~# cd /home/root/ root@myir-remi-1g:~# ./unit-test-server tcp 127.0.0.1 & root@myir-remi-1g:~# ./unit-test-client tcp 127.0.0.1 Connecting to 127.0.0.1:1502 Client connection accepted from 127.0.0.1. Waiting for an indication... ** UNIT TESTING ** 1/1 No response timeout modification on connect: OK TEST WRITE/READ: [00][01][00][00][00][06][FF][05][01][30][FF][00] <00><01><00><00><00><06><05><01><30> <00> [00][01][00][00][00][06][FF][05][01][30][FF][00] Waiting for an indication... Waiting for a confirmation... <00><01><00><00><00><06> <05><01><30> <00> 1/2 modbus_write_bit: OK