linux - 如何解决 Linux 和 Modbus 的错误文件描述符
问题描述
我正在尝试在运行 Raspian Buster 的 Raspberry Pi 上使用 libmodbus 设置半双工 RS-485 通信,并带有 FTDI USB 到串行适配器。当我运行 ls /dev/ 时,我的 FTDI 适配器显示为 ttyUSB0。
我尝试了以下示例代码:
#include <modbus.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main(void) {
modbus_t *ctx = modbus_new_rtu("/dev/ttyUSB0", 19200, 'N', 8, 1);
if (ctx == NULL) {
fprintf(stderr, "Unable to create the libmodbus context\n");
return 0;
}
if (modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS485) == -1) {
fprintf(stderr, "Error setting the serial port as RS-485\n");
fprintf(stderr, "errno: %d\n (EBADF == 9)", errno);
modbus_free(ctx);
return 0;
}
}
编译gcc test1.c -I/usr/include/modbus -lmodbus
。我得到errno
as9
或EBADF
,即使我使用sudo
.
解决方案
您的问题有一个非常简单的解决方案:只是不要设置MODBUS_RTU_RS485
,很可能您不需要它。
对于没有自动(硬件)方向控制的设备,这种模式实际上是一种解决方法。如您所知,Modbus RTU 在半双工 RS485 链路上工作(只允许一个设备通话,而所有其他设备必须只监听),因此需要一个额外的(到 RX 和 TX)信号来控制正在写入的设备总线始终(方向控制)。
因此,您只需要在MODBUS_RTU_RS485
您的设备缺少此功能时进行设置,这在现在是不太可能的,或者您正在构建自己的收发器。特别是大多数基于 FTDI 芯片的设备都应该具有此功能,因为芯片本身具有 TXDEN(发送使能)引脚。有关更多详细信息和将 TXDEN 信号暴露给非默认引脚的技巧,请参见此处。
当您没有此功能时(一种常见的情况是,当您想使用 Rpi 上的嵌入式 UART 用于 RS485 上的 Modbus,实现您自己的收发器)时,您需要软件(或硬件)解决方法。这就是MODBUS_RTU_RS485
应该派上用场的地方,重新利用 RTS 流控制信号。不幸的是,大多数串行驱动程序(包括ftdi_sio
您可能正在使用的那个)不支持这种模式(再次参考上面的链接)。
幸运的是,该变通方法有一些变通方法:完整讨论请参见此处。您还可以查看这个答案,其中我解释了如何设置libmodbus以支持使用 Rpi 上的 GPIO 引脚切换总线上的方向(也适用于大多数 SBC,我已成功使用此方法与 Pocket以芯片计算机为例)。
推荐阅读
- javascript - 由于回调、异步和等待而面临错误
- angular - 申请方法 PUT angular
- javascript - 为什么我们使用 textcontent 来改变 javaScript 中的值,而我们可以使用 HTML 来改变值?
- angular - Angular - 如何从垫表中获取选定的单元格值
- hadoop - 如何在不删除数据的情况下更改分区外部 Hive 表(镶木地板)上列的数据类型?
- jquery - jQuery.Deferred 异常:chart.axisX 未定义
- python - Python - 重命名特定文件
- mysql - Mysql从数组中选择元素
- c - 使用函数 fclose 损坏的大小与 prev_size 中止(“核心”generado)
- css - 如何为 Angular 中的特定打字稿组件应用 font-sze:62.5%