1. 5.1 Введение в Platform Drivers
Platform-драйверы — это особый тип драйверов ядра Linux, предназначенный для работы с устройствами, которые не могут быть автоматически обнаружены (в отличие от устройств на USB, PCI и т.д.). Они активно применяются в встраиваемых системах, таких как Raspberry Pi 3, где часто требуется вручную описать подключённые компоненты (например, LED-индикаторы, кнопки, GPIO-модули и т.д.).
1.1. Что такое platform driver и зачем он нужен?
Platform-драйвер — это часть драйвера, которая взаимодействует с platform-устройством (описанным вручную). Он обеспечивает регистрацию, связывание, инициализацию и работу с этим устройством. Используется, когда необходимо:
Обработать физически встроенные устройства, которые не могут быть найдены автоматически.
Использовать заранее известные адреса, IRQ и другие ресурсы.
Привязать драйвер к конкретному описанию устройства в Device Tree.
Platform-драйверы обеспечивают механизм, при котором ядро Linux «находит» соответствие между драйвером и описанием оборудования (обычно через compatible в Device Tree).
1.2. Где в системе Linux отображаются platform-устройства?
Информация о platform-устройствах отображается в файловой системе sysfs. Основные директории:
/sys/bus/platform/devices/ # список всех платформенных устройств
/sys/devices/platform/ # иерархия устройств
/sys/class/ # классы устройств (например, leds, gpio и т.д.)
Примеры команд:
ls /sys/bus/platform/devices/
cat /sys/bus/platform/devices/led@0/uevent
dmesg | grep platform
1.3. Как platform-драйверы взаимодействуют с Device Tree?
Device Tree (или DTB) — это структура данных, которая описывает оборудование. Platform-драйверы связываются с DT-узлами по ключу compatible. Например:
Device Tree:
led0: led@0 {
compatible = "rpi3,led";
reg = <0x01>;
gpio = <&gpio 17 0>;
};
Platform-драйвер:
static const struct of_device_id my_of_match[] = {
{ .compatible = "rpi3,led", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, my_of_match);
static struct platform_driver my_driver = {
.driver = {
.name = "led_driver",
.of_match_table = my_of_match,
},
.probe = my_probe,
.remove = my_remove,
};
module_platform_driver(my_driver);
Таким образом, ядро сопоставляет compatible строку и вызывает функцию probe() — это точка входа драйвера.
1.4. Какие функции ядра используются для работы с platform-драйверами?
Основные API-функции:
platform_driver_register() — регистрация платформенного драйвера.
platform_get_resource() — получение ресурсов (регистров, IRQ и др.).
devm_* функции — безопасное управление ресурсами (например, devm_gpio_request()).
of_match_device() — сопоставление DT с драйвером.
platform_device_register() — создание платформенного устройства (если не через DT).
dev_info(), dev_err() — логирование событий драйвера.
Также часто используется:
probe() — выполняется при обнаружении подходящего устройства.
remove() — вызывается при удалении устройства.
1.5. Что дальше?
В следующих разделах мы реализуем реальный модуль hellokeys_rpi3, работающий с GPIO-кнопками на Raspberry Pi 3. Вы научитесь:
описывать устройства в Device Tree;
связывать их с драйверами;
писать и отлаживать код ядра;
получать события от кнопок через GPIO и IRQ.