34. UIO-драйвер RGB-светодиода: исходный код и сборка
34.1. Описание
Драйвер rgb_uio реализует управление RGB-светодиодом через интерфейс UIO (Userspace I/O). Он экспортирует 1 байт памяти в пространство пользователя через /dev/uioX, где каждый бит управляет отдельным цветом:
Бит 0 — красный
Бит 1 — зелёный
Бит 2 — синий
UIO предоставляет простой способ взаимодействия с железом без написания полноценного ядрового драйвера.
34.2. Как это работает
Связь с Device Tree: Драйвер ищет узел с compatible = «kontakts,rgb-uio», откуда получает GPIO-пины для управления светодиодами.
GPIO: С помощью devm_gpiod_get() он получает дескрипторы на пины, помеченные как red, green, blue.
MMAP: Драйвер выделяет 1 байт памяти (data->mem), отображаемый в userspace. Запись значения в эту память приводит к изменению состояния GPIO (и, соответственно, цвета).
UIO интерфейс: Через uio_register_device() создаётся файл /dev/uio0, который можно открыть, отобразить в память и напрямую писать значения.
34.3. Сборка .ko
Создайте Makefile в той же директории:
obj-m := rgb_uio.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
Соберите модуль:
make
После сборки появится файл rgb_uio.ko.
34.4. Загрузка модуля
Перед загрузкой убедитесь, что Device Tree узел добавлен (см. соответствующий раздел) и доступен /dev/uio0.
Загрузите модуль:
sudo insmod rgb_uio.ko
Убедитесь, что он загрузился:
dmesg | grep rgb_uio
lsmod | grep rgb_uio
Проверьте наличие устройства:
ls /dev/uio*
34.5. Выгрузка модуля
Для удаления модуля:
sudo rmmod rgb_uio
dmesg | tail
Появится сообщение rgb_uio: driver removed.
34.6. Заключение
Этот драйвер демонстрирует, как можно использовать UIO для управления железом из userspace. Это особенно удобно для экспериментов, разработки и обучения, когда нужен простой и контролируемый доступ к периферии без написания полного драйвера ядра.
Следующим шагом можно будет написать userspace-программу на C, Python или Rust, которая будет управлять светодиодами через mmap().