21. 5.20: RGB LED через Device Tree и MMIO
21.1. Описание проекта
В этом упражнении мы реализовали драйвер для управления RGB-светодиодами на Raspberry Pi 3 с использованием:
Регистров MMIO (Memory-Mapped I/O)
Описания устройств в Device Tree (DT)
Создания трёх символических устройств /dev/ledred, /dev/ledgreen, /dev/ledblue
Работа через фреймворк miscdevice
Управление пинами напрямую через регистры (FSEL, SET, CLR)
Мы не использовали GPIO API (gpiod), а напрямую управляли GPIO на низком уровне через регистры SoC.
21.2. Физические соединения
RGB LED подключён к пинам:
R → GPIO16 (BCM)
G → GPIO20
B → GPIO21
Все пины конфигурируются как output в probe() функции.
21.3. Код драйвера
В probe() мы:
читаем из DT: - метку устройства label - битовую маску led-mask — например, 1 << 16 (0x00010000) для GPIO16
вызываем ioremap() для диапазона регистров GPIO (0x3F200000, 0xB4)
конфигурируем FSEL регистр через set_gpio_output(gpio)
регистрируем miscdevice
При write() в /dev/ledred:
строка „1“ вызывает iowrite32(mask, gpio_base + GPIO_SET_OFFSET)
строка „0“ вызывает iowrite32(mask, gpio_base + GPIO_CLR_OFFSET)
При read() возвращается текущий символ: „1“ или „0“.
21.4. Device Tree (DT)
Пример узла для одного светодиода (вставляется в soc {}):
ledred@3 {
compatible = "kontakts,rgb-led";
label = "ledred";
reg = <3>;
status = "okay";
led-mask = <0x10000>; // GPIO16
};
Устройства создаются на основании compatible и label, led-mask определяет нужный пин.
21.5. Проверка DT
ls /proc/device-tree/soc/ledred@3
cat /proc/device-tree/soc/ledred@3/label
hexdump -C /proc/device-tree/soc/ledred@3/led-mask
21.6. Проверка драйвера
Загрузка:
sudo insmod rgb_led_dt.ko
Проверка устройств:
ls -l /dev/ledred /dev/ledgreen /dev/ledblue
Включение и чтение:
echo "1" > /dev/ledred
cat /dev/ledred
21.7. Проверка GPIO через gpioinfo и raspi-gpio
gpioinfo | grep 16
gpioinfo | grep 20
gpioinfo | grep 21
Вывод:
line 16: unnamed unused output active-high
line 20: unnamed unused output active-high
line 21: unnamed unused output active-high
Или:
sudo raspi-gpio get 16
sudo raspi-gpio get 20
sudo raspi-gpio get 21
Результат:
GPIO 16: level=1 fsel=1 func=OUTPUT
21.8. Финальный вывод
Мы создали полноценный low-level RGB LED драйвер
Использовали MMIO напрямую
Применили Device Tree с масками пинов
Проверили работу через /dev/*, gpioinfo и raspi-gpio
Освободили пины, используя set_gpio_output()
21.9. Лицензия
GPL. Для обучения. Автор: ChatGPT + пользователь.