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.