Как решить Bad File Descriptor для Linux и Modbus - PullRequest
1 голос
/ 30 октября 2019

Я пытаюсь настроить полудуплексное соединение RS-485 с использованием libmodbus на Raspberry Pi с Raspian Buster, с адаптером FTDI USB-Serial. Мой FTDI-адаптер отображается как ttyUSB0 при запуске ls /dev/.

. Я попробовал следующий пример кода:

#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 как 9 или EBADF, даже если я запускаю этот код с sudo.

1 Ответ

1 голос
/ 30 октября 2019

Существует очень простое решение вашей проблемы: просто не устанавливайте MODBUS_RTU_RS485, вполне вероятно, что оно вам не нужно.

Этот режим на самом деле является обходным решением для устройств без автоматического (аппаратного)управление направлениемКак вы знаете, Modbus RTU работает по полудуплексному каналу RS485 (только одно устройство может разговаривать, в то время как все остальные должны только слушать), и, следовательно, требуется дополнительный (для RX и TX) сигнал для управления тем, на какое устройство выполняется запись. шина постоянно (управление направлением).

Таким образом, вам нужно будет установить MODBUS_RTU_RS485, только если ваше устройство не имеет этой функции, что в настоящее время весьма маловероятно или если вы создаете свой собственный трансивер. В частности, большинство устройств, основанных на микросхеме FTDI, должны иметь эту функцию, поскольку сама микросхема имеет вывод TXDEN (разрешение передачи). См. здесь для получения более подробной информации и хитрости для представления сигнала TXDEN на вывод не по умолчанию.

Это когда у вас нет этой функции (один частый сценарий - это когда вы хотитечтобы использовать встроенный UART на вашем Rpi для Modbus через RS485, реализуя собственный трансивер), вам нужен обходной путь программного (или аппаратного). И именно здесь MODBUS_RTU_RS485 должен пригодиться, переназначая сигнал управления потоком RTS. К сожалению, большинство последовательных драйверов (включая ftdi_sio, который вы, вероятно, используете) не поддерживают этот режим (см. Снова ссылку выше).

К счастью, есть обходные путик обходному пути: см. здесь для полного обсуждения. Вы также можете взглянуть на этот ответ , где я объяснил, как настроить libmodbus с поддержкой переключения направления на шине с помощью вывода GPIO на Rpi (также применимо к большинствуSBC, я успешно использовал этот метод, например, на Pocket Chip компьютере.

Вы можете найти более подробную информацию по этому вопросу в других местах: здесь и здесь .

...