16. RS485使用¶
RS485的使用与串口终端的使用基本相同,差别在于使用不同的设备树插件。
16.1. 使能RS485设备树插件¶
使能485的设备树插件。 修改 boot/uEnv.txt 文件,找到485相关设备树插件修改如下:
1 | dtoverlay=/usr/lib/linux-image-5.4.47-imx8mm/freescale/overlays/imx8mm-fire-rs485.dtbo
|
16.2. 简单测试485功能¶
修改 boot/uEnv.txt 之后重启开发板, 使用usb转485串口线连接开发板和PC
查看485总线设备
1 2 3 | root@lubancat:~# ls -l /dev/ttymxc*
crw------- 1 root tty 207, 17 12月 11 15:42 /dev/ttymxc1
crw-rw---- 1 root dialout 207, 18 12月 11 15:02 /dev/ttymxc2
|
其中ttymxc1为开发板默认串口设备,ttymxc2为485设备。
打开终端和pc串口助手,实现485的发送和接收数据
开发板发送数据:
1 | echo "board to pc" > /dev/ttymxc2
|

开发板接收数据:
1 | cat /dev/ttymxc2
|

16.3. libmodbus简介¶
libmodbus是一个与使用modbus协议的设备进行数据 发送/接收 的库, 它包含各种后端(backends)通过不同网络进行通信 (例如,RTU模式下的串口、485总线或TCP / IPv6中的以太网)。 libmodbus还提供了较低通信层的抽象,并在所有支持的平台上提供相同的API。
libmodbus是开源的,它遵循 LGPL v2.1 开源协议,这个协议没有GPL协议那么严格, 简单来说,只要你不修改libmodbus库里面的东西(只调用、链接该库),你是可以闭源你的代码的, 你也可以用于商业用途,这是非常好的。
16.3.1. 前期准备¶
在拉取仓库源码前,需要先安装一些编译工具。
1 2 | sudo apt update
sudo apt install gcc make git autoconf libtool
|
官方代码仓库位于:https://github.com/stephane/libmodbus。
也可从野火的代码仓库中拉取libmodbus源码,
1 2 3 4 5 | #github仓库地址
git clone https://github.com/Embedfire/libmodbus.git
#gitee仓库地址
git clone https://gitee.com/Embedfire/libmodbus.git
|
16.3.2. 编译¶
拉取下来后看到本地有libmodbus文件夹,我们进入libmodbus目录下, 运行它提供的脚本,它主要是自动生成一些用于配置的文件:
1 | ./autogen.sh
|
打印消息如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | libtoolize: putting auxiliary files in AC_CONFIG_AUX_DIR, 'build-aux'.
libtoolize: linking file 'build-aux/ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.
libtoolize: linking file 'm4/libtool.m4'
libtoolize: linking file 'm4/ltoptions.m4'
libtoolize: linking file 'm4/ltsugar.m4'
libtoolize: linking file 'm4/ltversion.m4'
libtoolize: linking file 'm4/lt~obsolete.m4'
configure.ac:33: installing 'build-aux/compile'
configure.ac:32: installing 'build-aux/missing'
src/Makefile.am: installing 'build-aux/depcomp'
------------------------------------------------------
Initialized build system. You can now run ./configure
------------------------------------------------------
|
2.运行完毕后,接着运行configure去配置编译相关的信息。
1 | ./configure
|
最后打印信息如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | libmodbus 3.1.6
===============
prefix: /usr/local
sysconfdir: ${prefix}/etc
libdir: ${exec_prefix}/lib
includedir: ${prefix}/include
compiler: gcc
cflags: -g -O2
ldflags:
documentation: no
tests: yes
|
运行上一步之后,在当前目录下将产生Makefile文件,使用make命令编译即可:
1 | make
|
4. 在编译完成后,在test目录下你会发现有很多可执行的文件, 比如我们稍后要运行的程序unit-test-server、unit-test-client:
1 2 3 4 5 6 7 8 9 10 11 12 | root@npi:/home/debian/libmodbus# ls tests/
bandwidth-client Makefile.am unit-test-client.c
bandwidth-client.c Makefile.in unit-test-client.o
bandwidth-client.o random-test-client unit-test.h
bandwidth-server-many-up random-test-client.c unit-test.h.in
bandwidth-server-many-up.c random-test-client.o unit-test-server
bandwidth-server-many-up.o random-test-server unit-test-server.c
bandwidth-server-one random-test-server.c unit-test-server.o
bandwidth-server-one.c random-test-server.o unit-tests.sh
bandwidth-server-one.o README.md version
LICENSE stamp-h2 version.c
Makefile unit-test-client version.o
|
16.3.3. 运行¶
打开两个终端,一个用于运行服务端一个用于运行客户端(ps:笔者这边使用两块开发板的485接口)。如下所示
./unit-test-server rtu
./unit-test-client rtu
在client终端中最终打印
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | [11][10][01][60][00][7B][06][02][2B][00][01][00][64][AC][1F]
* try function 0x10: write 123 values: Waiting for a confirmation...
<11><90><03><0D><C4>
OK
[11][0F][01][60][00][00][00][02][2B][00][01][00][64][59][63]
* try function 0xF: write 0 values: Waiting for a confirmation...
<11><8F><03><05><F4>
OK
[11][0F][01][60][07][B0][06][02][2B][00][01][00][64][12][27]
* try function 0xF: write 1968 values: Waiting for a confirmation...
<11><8F><03><05><F4>
OK
[11][42][00][00][00][00][7B][55]
Waiting for a confirmation...
<11><C2><01><B1><65>
Return an exception on unknown function code: OK
TEST INVALID INITIALIZATION:
The device string is empty
OK
The baud rate value must not be zero
OK
The service string is empty
OK
ALL TESTS PASS WITH SUCCESS.
|
以上代码均做测试用,关于具体用法请读者自行研究。 参考资料: https://github.com/stephane/libmodbus
16.4. RS485设备树¶
官方参考文档: 内核源码/Documentation/devicetree/bindings/serial 目录下的 rs485.txt、fsl-imx-uart.txt、serial.txt 。
野火MX8M-Mini提供了很多的设备树插件源码,若想要添加或修改不同的引脚作为485引脚, 可参考:
其中485的设备树插件文件为 imx8mm-fire-rs485-overlay.dts ,源码如下所示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /dts-v1/;
/plugin/;
#include "../imx8mm-pinfunc.h"
#include "dt-bindings/gpio/gpio.h"
#include "dt-bindings/clock/imx8mm-clock.h"
/ {
fragment@0 {
target = <&uart3>;
__overlay__ {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_rs485>;
assigned-clocks = <&clk IMX8MM_CLK_UART3>;
assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
fsl,uart-has-rtscts;
linux,rs485-enabled-at-boot-time;
rts-gpios = <&gpio5 8 GPIO_ACTIVE_HIGH>;
status = "okay";
};
};
fragment@1 {
target= <&iomuxc>;
__overlay__{
pinctrl_rs485: rs485grp {
fsl,pins = <
MX8MM_IOMUXC_ECSPI1_SCLK_UART3_DCE_RX 0x140
MX8MM_IOMUXC_ECSPI1_MOSI_UART3_DCE_TX 0x140
MX8MM_IOMUXC_ECSPI1_MISO_GPIO5_IO8 0x140
>;
};
};
};
};
|
485设备树插件修改相对简单,若想修改相对应的引脚,只需修改代码的18,28-30行即可。