16. RS485使用

RS485的使用与串口终端的使用基本相同,差别在于使用不同的设备树插件。

16.1. 使能RS485设备树插件

使能485的设备树插件。 修改 boot/uEnv.txt 文件,找到485相关设备树插件修改如下:

boot/uEnv.txt
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
未找到图片07|

开发板接收数据:

接收数据
1
cat /dev/ttymxc2
未找到图片07|

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. 编译

  1. 拉取下来后看到本地有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
  1. 运行上一步之后,在当前目录下将产生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接口)。如下所示

终端1
  ./unit-test-server rtu
终端2
 ./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 ,源码如下所示

/arch/arm64/boot/dts/freescale/overlay/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行即可。