rs-485-uart

В: RS-485 не работает через параметры DTS (linux,rs485-enabled-at-boot-time), только через ioctl

О: Device Tree и ioctl настраивают один и тот же RS-485 режим на разных этапах.

Свойство:

linux,rs485-enabled-at-boot-time;

задаёт начальную конфигурацию RS-485 при инициализации UART. Serial core передаёт параметры из Device Tree драйверу UART через struct serial_rs485.

TIOCSRS485 изменяет ту же конфигурацию из userspace уже во время работы системы.

Если настройка из DTS не применяется, необходимо проверить:

  • что Linux загрузил именно тот DTB, который был изменён;

  • что свойство находится в узле нужного UART;

  • что драйвер данного UART реализует RS-485;

  • что RTS выведен в pinctrl, если он используется для управления DE;

  • полярность DE/RTS;

  • какие RS-485 flags фактически поддерживает драйвер.

Текущую конфигурацию можно прочитать через TIOCGRS485.

Пример настройки из userspace:

#include <linux/serial.h> #include <sys/ioctl.h> #include <string.h> struct serial_rs485 rs485; memset(&rs485, 0, sizeof(rs485)); rs485.flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND; if (ioctl(serial_fd, TIOCSRS485, &rs485) < 0) { /* обработка ошибки */ }

Для Device Tree высокий уровень RTS во время передачи является значением по умолчанию. Поэтому:

rs485-rts-active-high;

можно не указывать, если трансивер действительно должен включать передатчик высоким уровнем.

Если DE активен низким уровнем, используется:

rs485-rts-active-low;

В: В RS-485 режиме теряется последний байт при приёме собственного эхо

О: Установить флаг SER_RS485_RX_DURING_TX в структуре rs485. Его отсутствие обнуляет RX FIFO после передачи последнего байта при переключении TX→RX, из-за чего последний принятый байт теряется.

Схемотехническая рекомендация: соединить #RE и DE вместе — это исключает артефакты на RX при переключении.

В: При loopback-тесте UART (RX и TX замкнуты) ОС зависает, в dmesg rcu_preempt detected stalls

О: Причина — включённый DMA в конфигурации UART. Для тестов DMA вреден. Удалите из DTS-узла UART:

&uart9 { /delete-property/ dmas; /delete-property/ dma-names; };

DMA в UART нужен только для специфических применений (например, Bluetooth). Для стандартных RS-485 задач DMA не требуется.

В: Если убрать CTS из pinctrl UART, cat зависает при повторном использовании порта

О: CTS участвует в управлении приёмником RS-485. Если CTS убран из pinkontrol, оставьте только нужные сигналы:

pinctrl-0 = <&uart7m1_xfer>; /* без uart7m1_ctsn */

Убедитесь, что после первого сеанса RTS корректно отпускается — cat может не освобождать RTS при завершении, блокируя последующие открытия порта.