如何解决 Linux 和 Modbus 的错误文件描述符

How to solve Bad File Descriptor for Linux and Modbus

我正在尝试使用 libmodbus 在 Raspberry Pi 运行ning Raspian Buster 上使用 FTDI USB 转串口适配器设置半双工 RS-485 通信。当我 运行 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 作为 9EBADF,即使我 运行 此代码带有 sudo.

有一个非常简单的方法可以解决您的问题:只是不要设置 MODBUS_RTU_RS485,很可能您不需要它。

此模式实际上是针对没有自动(硬件)方向控制的设备的解决方法。如您所知,Modbus RTU 在半双工 RS485 link 上工作(只允许一个设备通话,而所有其他设备必须只听),因此需要一个额外的(到 RX 和 TX)信号来控制什么设备一直在写入总线(方向控制)。

因此,如果您的设备缺少此功能,那么您只需要设置 MODBUS_RTU_RS485,这在当今不太可能发生,或者如果您正在构建自己的收发器。大多数基于 FTDI 芯片的设备尤其应该具有此功能,因为芯片本身具有 TXDEN(传输启用)引脚。有关详细信息和将 TXDEN 信号暴露给非默认引脚的技巧,请参阅

当你没有这个功能时(一个常见的情况是当你想在你的 Rpi 上使用嵌入式 UART for Modbus over RS485,实现你自己的收发器)你需要一个软件(或硬件)解决方法。这就是 MODBUS_RTU_RS485 应该派上用场的地方,重新利用 RTS 流量控制信号。不幸的是,大多数串行驱动程序(包括 ftdi_sio,您可能正在使用的驱动程序)不支持此模式(再次参考上面的 )。

幸运的是,有一些解决方法:请参阅 for a complete discussion. You can also take a look at this answer,我在其中解释了如何设置 libmodbus 以支持使用 GPIO 切换总线上的方向固定在 Rpi 上(也适用于大多数 SBC,例如,我已经成功地将此方法用于袖珍芯片计算机)。

您可以在其他地方找到有关此问题的更多背景信息:here and here