Вопрос или проблема
Когда я запускаю свой одноплатный компьютер, я могу столкнуться с выводом из UART
, который также называется /dev/ttyS0
. Я хочу зеркалить все на свой HDMI
порт, который находится на /dev/dri/card0
.
Как я могу это сделать? Здесь я запускаю команду drm_info
. Я использую Ubuntu 24.04 LTS.
>> drm_info
[?2004l
Узел: /dev/dri/card0
├───Драйвер: stm (STMicroelectronics SoC DRM) версия 1.0.0 (20170330)
│ ├───Поддерживается DRM_CLIENT_CAP_STEREO_3D
│ ├───Поддерживается DRM_CLIENT_CAP_UNIVERSAL_PLANES
│ ├───Поддерживается DRM_CLIENT_CAP_ATOMIC
│ ├───Поддерживается DRM_CLIENT_CAP_ASPECT_RATIO
│ ├───Поддерживается DRM_CLIENT_CAP_WRITEBACK_CONNECTORS
│ ├───DRM_CAP_DUMB_BUFFER = 1
│ ├───DRM_CAP_VBLANK_HIGH_CRTC = 1
│ ├───DRM_CAP_DUMB_PREFERRED_DEPTH = 0
│ ├───DRM_CAP_DUMB_PREFER_SHADOW = 0
│ ├───DRM_CAP_PRIME = 3
│ ├───DRM_CAP_TIMESTAMP_MONOTONIC = 1
│ ├───DRM_CAP_ASYNC_PAGE_FLIP = 0
│ ├───DRM_CAP_CURSOR_WIDTH = 64
│ ├───DRM_CAP_CURSOR_HEIGHT = 64
│ ├───DRM_CAP_ADDFB2_MODIFIERS = 1
│ ├───DRM_CAP_PAGE_FLIP_TARGET = 0
│ ├───DRM_CAP_CRTC_IN_VBLANK_EVENT = 1
│ ├───DRM_CAP_SYNCOBJ = 0
│ └───DRM_CAP_SYNCOBJ_TIMELINE = 0
├───Устройство: платформа st,stm32-ltdc
│ └───Доступные узлы: primary
├───Размер кадра
│ ├───Ширина: [0, 2048]
│ └───Высота: [0, 2048]
├───Разъемы
│ └───Разъем 0
│ ├───ID объекта: 32
│ ├───Тип: HDMI-A
│ ├───Статус: подключен
│ ├───Физический размер: 1210x680 мм
│ ├───Подпиксель: неизвестно
│ ├───Кодировщики: {0}
│ ├───Режимы
│ │ ├───[email protected] драйвер phsync pvsync 16:9
│ │ ├───[email protected] драйвер phsync pvsync 16:9
│ │ ├───[email protected] драйвер phsync pvsync 16:9
│ │ ├───[email protected] драйвер phsync pvsync
│ │ ├───[email protected] драйвер phsync pvsync 16:9
│ │ ├───[email protected] драйвер phsync pvsync 16:9
│ │ ├───[email protected] драйвер nhsync nvsync 16:9
│ │ ├───[email protected] драйвер nhsync nvsync 4:3
│ │ ├───[email protected] драйвер nhsync nvsync 16:9
│ │ └───[email protected] драйвер nhsync nvsync 4:3
│ └───Свойства
│ ├───"EDID" (неизменяемый): blob = 44
│ ├───"DPMS": enum {Включено, Режим ожидания, Приостановлено, Выключено} = Включено
│ ├───"состояние-соединения": enum {Хорошо, Плохо} = Хорошо
│ ├───"неклассический" (неизменяемый): диапазон [0, 1] = 0
│ ├───"ПЛИТКА" (неизменяемый): blob = 0
│ ├───"CRTC_ID" (атомарный): объект CRTC = 0
│ └───"дизеринг": enum {Выключено, Включено} = Выключено
├───Кодировщики
│ └───Кодировщик 0
│ ├───ID объекта: 31
│ ├───Тип: DPI
│ ├───CRTCS: {0}
│ └───Клоны: {0}
├───CRTCs
│ └───CRTC 0
│ ├───ID объекта: 38
│ ├───Легендарная информация
│ │ └───Размер гаммы: 256
│ └───Свойства
│ ├───"ACTIVE" (атомарный): диапазон [0, 1] = 0
│ ├───"MODE_ID" (атомарный): blob = 0
│ ├───"OUT_FENCE_PTR" (атомарный): диапазон [0, UINT64_MAX] = 0
│ ├───"VRR_ENABLED": диапазон [0, 1] = 0
│ ├───"GAMMA_LUT": blob = 0
│ └───"GAMMA_LUT_SIZE" (неизменяемый): диапазон [0, UINT32_MAX] = 256
└───Плоскости
├───Плоскость 0
│ ├───ID объекта: 34
│ ├───CRTCS: {0}
│ ├───Легендарная информация
│ │ ├───ID FB: 0
│ │ └───Форматы:
│ │ ├───ARGB8888 (0x34325241)
│ │ ├───XRGB8888 (0x34325258)
│ │ ├───RGB888 (0x34324752)
│ │ ├───RGB565 (0x36314752)
│ │ ├───ARGB1555 (0x35315241)
│ │ ├───XRGB1555 (0x35315258)
│ │ ├───ARGB4444 (0x32315241)
│ │ ├───XRGB4444 (0x32315258)
│ │ └───C8 (0x20203843)
│ └───Свойства
│ ├───"тип" (неизменяемый): enum {Накладка, Основной, Курсор} = Основной
│ ├───"FB_ID" (атомарный): объект framebuffer = 0
│ ├───"IN_FENCE_FD" (атомарный): srange [-1, INT32_MAX] = -1
│ ├───"CRTC_ID" (атомарный): объект CRTC = 0
│ ├───"CRTC_X" (атомарный): srange [INT32_MIN, INT32_MAX] = 0
│ ├───"CRTC_Y" (атомарный): srange [INT32_MIN, INT32_MAX] = 0
│ ├───"CRTC_W" (атомарный): диапазон [0, INT32_MAX] = 0
│ ├───"CRTC_H" (атомарный): диапазон [0, INT32_MAX] = 0
│ ├───"SRC_X" (атомарный): диапазон [0, UINT32_MAX] = 0
│ ├───"SRC_Y" (атомарный): диапазон [0, UINT32_MAX] = 0
│ ├───"SRC_W" (атомарный): диапазон [0, UINT32_MAX] = 0
│ ├───"SRC_H" (атомарный): диапазон [0, UINT32_MAX] = 0
│ ├───"IN_FORMATS" (неизменяемый): blob = 35
│ │ └───DRM_FORMAT_MOD_LINEAR (0x0)
│ │ ├───ARGB8888 (0x34325241)
│ │ ├───XRGB8888 (0x34325258)
│ │ ├───RGB888 (0x34324752)
│ │ ├───RGB565 (0x36314752)
│ │ ├───ARGB1555 (0x35315241)
│ │ ├───XRGB1555 (0x35315258)
│ │ ├───ARGB4444 (0x32315241)
│ │ ├───XRGB4444 (0x32315258)
│ │ └───C8 (0x20203843)
│ ├───"alpha": диапазон [0, UINT16_MAX] = 65535
│ └───"zpos" (неизменяемый): диапазон [0, 0] = 0
└───Плоскость 1
├───ID объекта: 39
├───CRTCS: {0}
├───Легендарная информация
│ ├───ID FB: 0
│ └───Форматы:
│ ├───ARGB8888 (0x34325241)
│ ├───RGB888 (0x34324752)
│ ├───RGB565 (0x36314752)
│ ├───ARGB1555 (0x35315241)
│ ├───ARGB4444 (0x32315241)
│ └───C8 (0x20203843)
└───Свойства
├───"тип" (неизменяемый): enum {Накладка, Основной, Курсор} = Накладка
├───"FB_ID" (атомарный): объект framebuffer = 0
├───"IN_FENCE_FD" (атомарный): srange [-1, INT32_MAX] = -1
├───"CRTC_ID" (атомарный): объект CRTC = 0
├───"CRTC_X" (атомарный): srange [INT32_MIN, INT32_MAX] = 0
├───"CRTC_Y" (атомарный): srange [INT32_MIN, INT32_MAX] = 0
├───"CRTC_W" (атомарный): диапазон [0, INT32_MAX] = 0
├───"CRTC_H" (атомарный): диапазон [0, INT32_MAX] = 0
├───"SRC_X" (атомарный): диапазон [0, UINT32_MAX] = 0
├───"SRC_Y" (атомарный): диапазон [0, UINT32_MAX] = 0
├───"SRC_W" (атомарный): диапазон [0, UINT32_MAX] = 0
├───"SRC_H" (атомарный): диапазон [0, UINT32_MAX] = 0
├───"IN_FORMATS" (неизменяемый): blob = 40
│ └───DRM_FORMAT_MOD_LINEAR (0x0)
│ ├───ARGB8888 (0x34325241)
│ ├───RGB888 (0x34324752)
│ ├───RGB565 (0x36314752)
│ ├───ARGB1555 (0x35315241)
│ ├───ARGB4444 (0x32315241)
│ └───C8 (0x20203843)
├───"alpha": диапазон [0, UINT16_MAX] = 65535
└───"zpos" (неизменяемый): диапазон [1, 1] = 1
[?2004hroot@stm32-os:~#
Ответ или решение
Для того чтобы отобразить выходные данные с последовательного порта /dev/ttyS0
на HDMI-порт /dev/dri/card0
, требуется несколько шагов. В этом ответе я объясню, как это сделать с использованием утилит Linux.
Шаг 1: Установка необходимых утилит
Для отображения данных с последовательного порта на экран потребуется установить некоторые утилиты. Убедитесь, что у вас установлены socat
и fbset
(или аналогичные утилиты для взаимодействия с фреймбуфером).
sudo apt update
sudo apt install socat fbset
Шаг 2: Чтение данных с последовательно порта
Мы будем использовать команду socat
для считывания данных с порта /dev/ttyS0
и перенаправления их в виртуальный терминал. Предположим, что вы хотите отобразить данные в терминале на HDMI. Для этого создайте новый терминал и выполните следующую команду:
socat -u /dev/ttyS0 STDOUT | fbset -fb /dev/fb0
Однако, в большинстве случаев консольное приложение, работающее с фреймбуфером, не будет выводить текст в должном формате. Поэтому лучше использовать cat
и echo
.
Шаг 3: Отображение данных на HDMI
Вместо прямого вывода через socat
, можно выполнить вывод данных в терминал таким образом:
socat -u /dev/ttyS0 - | while IFS= read -r line; do echo "$line" > /dev/tty1; done
Шаг 4: Создание скрипта для автоматизации
Для автоматизации процесса можно создать bash-скрипт. Создайте файл mirror_serial_to_hdmi.sh
:
#!/bin/bash
# Открывает последовательный порт и перенаправляет выходные данные в HDMI
socat -u /dev/ttyS0 - | while IFS= read -r line; do
echo "$line" > /dev/tty1
done
Сделайте файл исполняемым:
chmod +x mirror_serial_to_hdmi.sh
Шаг 5: Запуск скрипта при запуске системы
Если вы хотите, чтобы этот скрипт автоматически запускался при загрузке системы, вы можете добавить его в автозагрузку. Один из способов сделать это — добавить команду в файл /etc/rc.local
, если он модифицируем:
# Включите редактирование rc.local
sudo nano /etc/rc.local
Добавьте строку перед exit 0
:
/path/to/mirror_serial_to_hdmi.sh &
Заключение
Таким образом, вы сможете отображать данные, получаемые с последовательного порта /dev/ttyS0
, на подключенном устройстве HDMI, представленном как /dev/dri/card0
, используя утилиты socat
и fbset
. Не забудьте протестировать работу и убедиться, что все необходимые параметры последовательного порта (скорость передачи, биты данных и т.д.) настроены корректно.