====================================================== Программа `test_rgb_user.c` и UIO-драйвер `rgb_uio.ko` ====================================================== Введение -------- В данной системе реализовано управление RGB-светодиодом с помощью пользовательского приложения `test_rgb_user.c`, использующего интерфейс UIO (Userspace I/O) к модулю ядра `rgb_uio.ko`. Такое разделение позволяет управлять оборудованием напрямую из пользовательского пространства без написания специфического ioctl-интерфейса, используя `mmap()`. UIO-драйвер `rgb_uio.ko` ------------------------ Драйвер реализован как `platform_driver` и использует интерфейс `uio_info`, предоставляемый ядром Linux для создания пользовательских I/O-устройств. Он: - Получает из Device Tree описания GPIO-пинов `red-gpios`, `green-gpios`, `blue-gpios`. - Инициализирует эти пины в режиме вывода (`GPIOD_OUT_LOW`). - Выделяет один байт памяти в kernel space (`kmalloc()` через `devm_kzalloc()`), который затем отображается в userspace с помощью `mmap()`. - Регистрирует структуру `uio_info`, чтобы создать `/dev/uio0`. Младшие три бита выделенного байта отвечают за включение каналов: * Бит 0 — красный светодиод * Бит 1 — зелёный светодиод * Бит 2 — синий светодиод Изменение значения этого байта изменяет состояния пинов, тем самым включая или выключая соответствующие цвета. Файл устройства `/dev/uio0` --------------------------- После загрузки драйвера ядро автоматически создаёт символьное устройство `/dev/uio0`, которое пользователь может открыть с правами на `read/write` и использовать `mmap()` для доступа к зарезервированной области памяти. Программа `test_rgb_user.c` --------------------------- Данная утилита компилируется как обычная C-программа и предназначена для запуска из терминала. Она: 1. Принимает аргумент командной строки — байт, задающий цвет в формате `0xXY`. 2. Открывает `/dev/uio0` с правами `O_RDWR`. 3. Выполняет отображение одного байта памяти (`mmap()`) из устройства в адресное пространство процесса. 4. Записывает полученное значение в отображённую память. 5. Это значение читается ядром и используется для управления состояниями GPIO-пинов. Пример использования: .. code-block:: bash ./test_rgb_user 0x01 # Включить только красный ./test_rgb_user 0x02 # Включить только зелёный ./test_rgb_user 0x04 # Включить только синий ./test_rgb_user 0x07 # Все три цвета включены ./test_rgb_user 0x00 # Все выключены Связь с железом ---------------- Светодиод подключён к GPIO-пинам Raspberry Pi: * Красный — GPIO 16 * Зелёный — GPIO 20 * Синий — GPIO 21 Сами пины определяются в Device Tree и передаются драйверу через `devm_gpiod_get()` в `rgb_uio.c`. Установка значений с помощью `gpiod_set_value_cansleep()` позволяет безопасно управлять пинами в любых условиях. Заключение ----------- Данная реализация UIO-драйвера и пользовательской утилиты показывает, как можно легко и эффективно связать ядро Linux, пользовательское пространство и реальное оборудование. Это прекрасная демонстрация low-level управления без необходимости писать сложные драйверы с ioctl-интерфейсом.