Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
libmodbus
基于 serialX 串口驱动移植 libmodbus
发布于 2023-02-14 11:45:19 浏览:1365
订阅该版
[tocm] ## 关于 serialX 上一篇我们基于 serialX 驱动,移植 freemodbus 并填了几个坑。今天换 libmodbus 看看会遇到什么。 ### 测试环境 开发板: NK-980IOT V1.0 的开发板 rt-thread 版本:4.1.1 IDE:keil + env ### NUC980 serialX 驱动 之前,笔者介绍 serialX 的时候,曾详细的讲解过 `struct rt_uart_ops` 接口中的每一个函数的功能。完全按照每一个函数功能定义去做,后面的事情就是水到渠成的。 花了小半天的时间从 drv\_uart.c 改成 drv\_uartX.c 。 然后使用 [serialX](https://gitee.com/thewon/serialX) 中提供的 测试程序 serialX\_test.c 简单测试了一下,收发回环没发现严重问题(没有数据丢失,没有数据错误)。 启用控制台和 finsh 。改成“中断收发读写”模式,试了几个命令,打印结果完整。 可以说,验证了这次写的驱动还是很不错的,是成功的。 ### 启用 libmodbus env 环境里启用 libmodbus,使能 "Enable libmodbus rtu mode" rtu 模式并使能 "Enable rtu example" rtu 样例程序。 使用命令 `pkgs --update` 下载 libmodbus 源码。 libmodbus 的源码文件数量比 freemodbus 少很多了。看起来清晰很多。 ### 第一次试编译 生成项目后先尝试编译一次,出现了很多错误。 #### 首先,第一类错误是: ``` error: #20: identifier "EBADF" is undefined error: #20: identifier "ECONNRESET" is undefined ... ``` 这几个宏定义在 "errno.h" 头文件,这个文件呢,在某个版本移动过路径,没记错的话也是从 4.0.3 之后开始的。现在的用法是 `#include
` modbus-rtu.c 修改 `#include
` -> `#include
` modbus.c 修改 `#include
` -> `#include
` #### 然后,第二种错误是: ``` error: #20: identifier "fd_set" is undefined warning: #223-D: function "FD_ZERO" declared implicitly warning: #223-D: function "FD_SET" declared implicitly ``` 这几个定义在 "sys/select.h" ,可以 `#include
` ,也可以 `#include
`,因为后者文件也只有一行内容就是 `#include
`。 modbus.c 添加 `#include
` 至此,应该是把所有版本升级引起的兼容错误修正了。 ### 第一次运行测试程序 开始跑测试程序之前,去掉 RS485 的所有相关代码。添加 libmodbus 的 debug `modbus_set_debug(ctx, TRUE);`。这可以让我们看到很多的有用信息。 和上次的 freemodbus 样例程序不一样的是,这次是读保持寄存器,并不是写寄存器。 测试开始以后,笔者在控制台终端里看到如下信息, ``` [01][03][00][00][00][0A][C5][CD] Waiting for a confirmation... msh >ERROR Unknown error: select ------------------------------------------- [ 0][read num = -1]<0><0><0><0><0><0><0><0><0><0> ------------------------------------------- ``` 而,在 slave 端的调试信息是: ``` qt.modbus.lowlevel: (RTU server) Received ADU: "01030000000ac5cd" qt.modbus: (RTU server) Request PDU: 0x030000000a qt.modbus: (RTU server) Response PDU: 0x031400110022003300440055006600770088009900aa qt.modbus.lowlevel: (RTU server) Response ADU: "01031400110022003300440055006600770088009900aa4584" ``` 分析两端的调试信息, slave 端既接收到了请求 ADU,也正常回复了响应 ADU。但是 libmodbus 的 master 端并没有收到任何响应! #### 问题定位过程 首先确定串口接收中断没触发,也就是给开发板发的数据并没有接收中断; 调出串口外设寄存器发现,中断使能寄存器的值变成 0 了!串口中断使能寄存器被某个力量情况复位了! 再次回到串口驱动测试程序,笔者很确定是使用的中断接收模式,并且可以有接收中断。 问题好像很明显,libmodbus 在打开串口外设的过程中,某些操作清理了串口外设寄存器。 经过详细比对,libmodbus 打开串口设备后使用 termios 配置串口设备的波特率数据位等。而笔者上次在测试 posix 接口时使用的默认配置,并没有修改波特率。为了验证并跟踪问题位置,笔者在 "serialX_posix.c" 里添加 termios 配置函数。 经过一步步代码调试跟踪,得到函数调用链 `tcsetattr` -> `ioctl` -> `fcntl` -> `dfs_file_ioctl` -> `serial_fops_ioctl` -> `rt_device_control` -> `rt_serial_control` -> `nu_uart_configure` ,最后这个函数有一句 `nu_sys_ip_reset(((nu_uart_t)serial)->rstidx);` ,这句会复位中断寄存器的值。 ### 第二次运行测试程序 注释掉这句代码后,再跑 libmodbus 样例程序, ``` [01][03][00][00][00][0A][C5][CD] Waiting for a confirmation... <01><03><14><00><11><00><22><00><33><00><44><00><55><00><66><00><77><00><88><00><99><00>
<45><84> ------------------------------------------- [ 11][read num = 10]<0x11><0x22><0x33><0x44><0x55><0x66><0x77><0x88><0x99><0xaa> ------------------------------------------- ``` 终于看到想要的信息了。 ### 问题复盘 使用过 rt-thread 串口驱动框架的人都知道,`rt_device_find` `rt_device_control` `rt_device_open` 是读写串口设备前的三步曲,这三个步骤顺序的不能乱的。[rt_device_control和rt_device_open执行先后的问题](https://club.rt-thread.org/ask/question/ab9c84d606b1ad25.html) **也就是说,配置串口波特率数据位等必须在打开设备之前!** 我们再看 libmodbus 的做法,先 open ,然后调用 `tcsetattr` ... -> `rt_device_control`。 那么,笔者删掉的那句代码是错误的吗?好像也不能这么说,它是“有用的”,可能它是出现在了不该出现的地方。 ## 结束语 使用 libmodbus 的代价是很高的,从前边提到过的函数调用过程,就够人头疼的 但是,libmodbus 更适合系统,它只用了一个线程就能跑起来。freemodbus 用了三个(意味着更多的线程栈耗用)。 这次测试,我们发现了两处升级引入的版本兼容错误,以及 open configure 顺序引起的外设工作异常的问题。
15
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
出出啊
恃人不如自恃,人之为己者不如己之自为也
文章
43
回答
1518
被采纳
342
关注TA
发私信
相关文章
1
基于w5500的libmodbus复位后modbusTCP的监听一直失败
2
libmodbus rtu模式运行一段时间后,无法正常收取数据
3
libmodbus设为从机地址不同也会进行响应
4
libmodbus设置问题
5
wiznet与libmodbus软件包衔接对接SAL层传参问题
6
【已解决】求助 lwip 2.0.2+libmodbus重复的报文段引起的故障
7
AT32F403 LibModbus 接收中断失败
8
两个串口freemodbus是不是应该要写两份,用libmodbus又有问题
9
系统崩溃重启, Bus fault
10
请问485硬件上没有做RTS引脚,libmodbus主机RTS这块该如何配置
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
cubemx
PWM
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
xusiwei1236
8
个答案
2
次被采纳
踩姑娘的小蘑菇
1
个答案
2
次被采纳
用户名由3_15位
9
个答案
1
次被采纳
bernard
4
个答案
1
次被采纳
RTT_逍遥
3
个答案
1
次被采纳
本月文章贡献
聚散无由
2
篇文章
15
次点赞
catcatbing
2
篇文章
5
次点赞
Wade
2
篇文章
4
次点赞
Ghost_Girls
1
篇文章
7
次点赞
YZRD
1
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部