Освоение подсистемы управления пинами для драйверов устройств Linux
Примечание редактора: Embedded Linux становится основой Интернета вещей, а драйверы устройств — мостом между приложениями и железом. В «Linux Device Drivers Development» автор Джон Мадье предлагает детальное, код-riche руководство по построению этих драйверов.
Этот отрывок — Глава 14 книги — погружается в управление пинами и GPIO, критическую область для разработчиков, которым нужно интерфейсить кастомное железо с ядром. Первая часть вводит подсистему управления пинами.
Адаптировано из Linux Device Drivers Development, Джоном Мадье.
Глава 14. Подсистема управления пинами и GPIO
Джон Мадье
В встроенном Linux драйверы почти всегда взаимодействуют с GPIO или конфигурируют мультиплексирование пинов. «Пин» — это физическая выходная линия компонента, и многие SoC переиспользуют один пин для нескольких функций. Например, пин i.MX6QDL MX6QDL_PAD_SD3_DAT1 может служить линией данных SD, линией UART RTS/CTS, линией FlexCAN Rx или общим GPIO.
Процесс выбора функции пина называется pin muxing, и компонент ядра, оркеструющий это, — pin controller. Во второй части этой главы мы исследуем подсистему General Purpose Input/Output (GPIO), общую функцию пина.
В этой главе вы:
- Пройдете через подсистему управления пинами и научитесь декларировать pin-control узлы в Device Tree.
- Сравните устаревший integer-based GPIO API с новым descriptor-based интерфейсом.
- Обработаете GPIO, которые также используются как прерывания.
- Исследуете sysfs интерфейсы, посвященные управлению GPIO.
Подсистема управления пинами
pinctrl подсистема управляет мультиплексированием и конфигурацией пинов. Устройства, требующие специфическую раскладку пинов, должны описывать это расположение в Device Tree. Драйвер pin-контроллера парсит эти описания и программирует I/O контроллер SoC соответственно.
Подсистема предлагает:
- Мультиплексирование пинов — переиспользование одного пина для множественных ролей (UART TX, GPIO, HSI, и т.д.) на основе per-group или per-pin.
- Конфигурация пинов — установка электрических свойств таких как pull-up/pull-down, сила драйвера, дебаунс и больше.
Заметьте, что эта книга фокусируется на использовании pin-controller API; она не покрывает написание pin-controller драйвера самим.
Pinctrl и Device Tree
В Device Tree узел pin-контроллера описывает все доступные группы пинов и функции. Каждой группе присваивается целочисленный ID, опционально сопровождаемый pinctrl-name, который мапит человекочитаемые имена к IDs.
Байдинг устройства специфицирует состояния пинов, которые оно требует. Два свойства связывают устройство с состояниями пинов:
pinctrl-— список phandles, указывающих на узлы конфигурации пинов. Множественные записи позволяют устройству быть сконфигурированным несколькими pin контроллерами или комбинировать множественные узлы для одного контроллера.pinctrl-name— параллельный список, присваивающий имена каждому state ID. State 0 обычно называетсяdefaultи следует стандартному списку, определенному вinclude/linux/pinctrl/pinctrl-state.h.
Ниже типичный отрывок Device Tree, показывающий конфигурацию пинов для двух устройств:

Каждая строка следует формату <PIN_FUNCTION> <PIN_SETTING>:
MX6QDL_PAD_DISP0_DAT15__GPIO5_IO09 0x80000000 MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
Первый токен (MX6QDL_PAD_DISP0_DAT15__GPIO5_IO09) идентифицирует функцию пина; второй токен (0x80000000) кодирует биты конфигурации (pull-up/down, сила драйвера, и т.д.). Эти макросы определены в архитектурно-специфичных заголовочных файлах вроде arch/arm/boot/dts/imx6q-pinfunc.h.
Для программирования состояния пина в коде драйвера, следуйте этим шагам во время инициализации (обычно в probe()):
struct pinctrl *pinctrl; pinctrl = devm_pinctrl_get_select_default(&pdev->dev); if (IS_ERR(pinctrl)) dev_warn(&pdev->dev, "pins are not configured from the driver");
Хелпер pinctrl_get_select_default() автоматически извлекает и применяет состояние default. Если устройство предоставляет состояние init, ядро применит это состояние перед probe(), а затем вернется к default после, если драйвер не изменит его.
Когда закончите, освободите контроллер с pinctrl_put(pinctrl) или используйте resource-managed вариант devm_pinctrl_put(pinctrl).
Вот конкретный пример из файла am335x-evm.dts:
dcan1: d_can@481d0000 { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&d_can1_pins>; };
В соответствующем драйвере:
pinctrl = devm_pinctrl_get_select_default(&pdev->dev); if (IS_ERR(pinctrl)) dev_warn(&pdev->dev, "pins are not configured from the driver");
К моменту запуска probe() драйвера, конфигурация пинов default уже на месте.
Следующая часть покроет GPIO подсистему в деталях.
Воспроизведено с разрешения Packt Publishing. Copyright © 2017 Packt Publishing
Джон Мадье — инженер встроенного Linux и ядра, базирующийся в Париже. Он разрабатывает драйверы и BSP для клиентов в автоматизации, транспорте, здравоохранении, энергетике и обороне. Джон работает в EXPEMB, пионере в дизайне computer-on-module, и активный open-source адвокат, верящий, что обмен знаниями ускоряет инновации.
Интернет вещей
- Почему промышленные IoT-системы — главные цели для кибератак — и как их защитить
- От слоновой кости к бакелиту: прослеживая эволюцию современных пластмасс
- Будущий взгляд: продвижение Industrial IoT для производственного превосходства
- Кто за рулем коннектед кара? Взгляд с позиции водителя
- Шесть проверенных шагов к защите встроенных IoT-систем
- Принятие SaaS в разработке продуктов растет: ключевые барьеры и возможности — Часть 2
- Внедрение SaaS достиг точки перехода в разработке продуктов — инсайты PTC
- Как выбрать идеального партнера по разработке IoT: ключевые вызовы и решения
- Промышленные ПК: краеугольный камень сложного контроля в революции IIoT
- Ключевые драйверы успешного энтерпрайз IoT: инсайты экспертов Nokia