Работа с GPIO на примере Banana Pi BPI-M64. Часть 2. Device Tree overlays

Linux device tree

Дерево устройств (Device Tree, DT) — это структура данных в системе Linux, состоящая из именованных узлов и свойств, описывающих оборудование, которое невозможно обнаружить путем опроса оборудования. Дерево должно включать имя базового процессора, конфигурацию его памяти и любые периферийные устройства (внутренние и внешние). DT не используется для описания программного обеспечения, хотя перечисление аппаратных модулей вызывает загрузку модулей драйверов. Пост раскрывает принцип формирования DT на примере отладочной платы Banana Pi BPI-M64, по итогу Вы сможете самостоятельно конфигурировать периферийные устройства GPIO, включая другие платы, например Raspberry Pi.

Сердцем любой отладочной платы или одноплатного компьютера является SoC. SoC имеет множество контактов (ног) для подключения линий электропитания и различных устройств.

Allwinner V3s

Контакты могут быть объедены вместе для формирования интерфейса, например MIPI DSI(MIPI Display Serial Interface). Интерфейс MIPI DSI предназначен для подключения LCD панелей, активно используется в смартфонах и планшетах. Но если к устройству не планируется подключать дисплей по MIPI DSI, то эти линии можно использовать для других целей, путем изменения DT. В отличие от архитектуры x86 в системах построенных на SoC нет возможности произвести полностью опознание всех устройств в режиме Plug and Play. Поэтому необходимо явное декларирование какие контакты используются для интерфейсов и какие именно устройства подключены к этим интерфейсам.

До появления DT информация об устройствах в Linux являлась неотъемлемой частью ядра, и в случае изменения состава периферийных устройств требовалось пересобрать образ системы. Это было крайне неудобно, и поэтому описание периферийных устройств перенесли в конфигурационные файлы, которые собираются на логическом уровне в дерево. Где ветвь — устройство с указанием драйвера необходимого для работы этого устройства.

После использования DT отпала необходимость в формирование индивидуального образа для каждого набора периферии устройств. Теперь достаточно сформировать один образ, включить в него набор драйверов для различных устройств, и для каждого устройства сформировать свой DT.

Наложения дерева устройств (Device Tree overlays)

Device Tree overlays (наложения дерева устройств) — добавление к DT принципа наложения слоев устройств. Если конфигурация описывает интерфейс UART к которому был подключен Bluetooth, и необходимо Bluetooth заменить на GPS модуль, то можно не удалять существующие настройки Bluetooth а добавить  дополнительный слой для GPS модуля который переопределит предыдущие настройки. 

Для работы с DT используются следующие термины:

DT Дерево устройств
DTB (*.dtb) Бинарный файл дерева устройств
DTBO (*.dtbo) Бинарный файл дерева устройств для наложения
DTC Компилятор дерева устройств
DTO Наложения дерева устройств
DTS (*.dts) Исходный файл для дерева устройств
FDT Flattened Device Tree, двоичный формат, содержащийся в файле .dtb

Аппаратная конфигурация  описывается в файлах исходниках DT ( .dts ) затем они компилируется в бинарные файлы DT ( .dtb ) уже для конечного использования в системе. Так же можно выполнить обратную процедуру декомпиляции файлов *. dtb  в *. dts, компилятор/декомпилятор присутствует в системе.

Linux device tree bootloader

Реализация DTO включает разделение дерева устройств, построение, разбиение на разделы и исполнение.

Разделение DT

DT разделяются на две части:

  • Main DT (основное дерево устройств). Предоставляет разработчик SoC и является настройкой по умолчанию. В данном случае предоставляет компания Allwinner разработчик процессора Allwinner A64.
  • Overlay DT (Накладываемое дерево устройств). Специфическая конфигурация производителя платы, включает периферийные устройства которые размещены на плате. Для платы Banana Pi BPI-M64 предоставляет компания SinoVoip Co.,

Видео с конференции Linux Piter 2016. Ходырев Дмитрий и Олейников Иван: «Device Tree Overlay» [RUS]

На конференции Linux Piter 2016, разработчики FPGA из компании НТЦ Метротек Ходырев Дмитрий и Олейников Иван рассказали про Device Tree Overlay» [RUS]. Доклад рассказывает о основах технологии device tree, позволяющей абстрагироваться от аппаратной специфики при работе с ядром Linux.
В этом докладе мы будем говорить о файлах Device Tree, структуре и синтаксисе, о поддержке структуры Device Tree в ядре Linux.Рассмотрим несколько простых примеров решения практических задач используя Device Tree. Доклад расчитан на слушателей, которые хотели бы больше узнать о особенностях ядра Linux. Более всего доклад будет полезен разработчикам ARM-платформ, разработчикам систем с FPGA, разработчикам драйверов.

Построение основного и накладываемого дерева устройств

Построение основного дерева устройств:

  1. Скомпилируйте основное DT *.dts в *.dtb файл.
  2. Поместите файл *.dtd в раздел загрузчика(bootloader) системы

Построение накладываемого дерева устройств(DTO)

  1. Скомпилируйте накладываемые файлы DT *.dts в файлы *.dtbo. Несмотря на совпадение структур файла .dtb и .dtbo, файл .dtb является основным в системе, в то время как файлы .dtbo добавочные.
  2. Поместите файл *.dtd в раздел загрузчика(bootloader) системы

Файлы DT не монолитны, они могут быть разделены на несколько частей в нескольких файлах, включая каждый из них. .dtsi файлы включают файлы платформы, пока .dts файлы не определят конечный вид дерева устройств. Типичная связь, .dtsi файлы будут включать информацию для SoC уровня(или иногда общее определение к некоторым почти идентичным платам). .dts файл включает информацию уровня отладочной платы (платы разработки). Присоединение работает следующим образом, происходит наложение файлов описывающих платформу (включенных файлов в проект) и формирование единого описания для платформы.

Пример присоединение дерева устройств
Linux device tree inclusion

Linux device tree inclusion

Использование дерева устройств в загрузчике (bootloader)

Принцип работы объединения дерева устройств в загрузчике (bootloader):

  1. Загрузка .dtb с носителя данных в оперативную память
  2. Загрузка .dtbo с носителя данных в оперативную память
  3. Наложение файла .dtb с файлами .dtbo для слияния DT
  4. Запуск ядра с указателем в памяти на адрес объединенного DT

Linux device tree treble dto dtbo

Синтаксис DTO

Device Tree Source (.dts) текстовый формат файлов для представления дерева устройств. Компилятор дерева устройств (DTC) преобразует этот формат в бинарный вид .dtd который непосредственно читается ядром Linux.

Linux device tree syntax

Использование Ссылок
Проект DTC (Device Tree compiler + overlay patches) содержит описание формата DTS в dtc-format.txt и manual.txt . Формат и правила DTO описаны в dt-object-internal.txt . В этих документах описывается, как обновить основное DT, используя узел fragment@x и синтаксис __overlay__ в накладываемом DT. Например:

Linux device tree overlay

Google настоятельно рекомендует не использовать fragment@x и синтаксис __overlay__ , а вместо этого использовать синтаксис ссылки. Например: 

Linux device tree overlay

Ссылочный синтаксис компилируется DTS в тот же объект, что и выше, с использованием синтаксиса __overlay__ . Этот синтаксис не заставляет вас нумеровать фрагменты, что упрощает чтение и запись DTS.

Использование Меток
Для построения компилятором накладываемого  дерева устройств файл *.dts должен содержать метку /plugin/ в заголовке. . Например:

/dts-v1/;
/plugin/;

Здесь вы можете ссылаться на узлы в основном дереве устройств. Ссылки должны начинаться с амперсанда (&). Например, для node@0 в основном дереве устройств:

Linux device tree overlay

Перезапись
Если свойство в узле существует в DTO и DT, то оно переопределяется в DTO; в противном случае если его нет в DTO то добавляется. Например:

Linux device tree overlay

Добавление
Если ссылочное целевое свойство не существует в основном DT, оно добавляется после DTO. Например:

Linux device tree overlay

Дочерние узлы
Примеры синтаксиса дочернего узла:

Linux device tree overlay

Компиляция

Получение файла .dts из .dtb:

dtc -I dtb -O dts /boot/dtb/allwinner/sun50i-a64-bananapi-m64.dtb -o /boot/dtb/allwinner/sun50i-a64-bananapi-m64.dts

Компилирует файл .dts в .dtb

dtc -I dts -O dtb /boot/dtb/allwinner/sun50i-a64-bananapi-m64.dts -o /boot/dtb/allwinner/sun50i-a64-bananapi-m64.dtb

 

Плагин DeviceTree Language Support для Visual Studio Code

Редактировать DTS файлы в блокноте крайне неудобно из-за отсутствия подсветки синтаксиса, и возможности сворачивать/разворачивать узлы. Для редактирования DTS можно загрузить бесплатную Visual Studio Code и установить плагин DeviceTree Language Support.

DeviceTree Language Support for Visual Studio Code
DeviceTree Language Visual Studio Code

 

Дерево устройств в образе Armbian для Banana Pi BPI-M64

Для рассмотрения взята версия Armbian_20.08.2_Bananapim64_bionic_current_5.8.6_minimal.img.xz, основанная на Ubuntu 18.04.5 LTS Linux bananapim64 5.8.6-sunxi64 #20.08.2 SMP Fri Sep 4 08:52:31 CEST 2020 aarch64 aarch64 aarch64 GNU/Linux. Исходники DTS в репозитории Linux располагаются по пути: /linux/arch/arm/boot/dts. Ссылка на зеркало Linux-Armbian.

Все бинарные файлы дерева устройств (DTB) располагаются по пути: /boot/dtb/allwinner

Device tree bpi m64

В этом каталоге располагаются DTB всех плат которые поддерживаются Armbian. В зависимости от модели платы загружается нужный файл DTB.

Для платы Banana Pi BPI-M64 в каталоге предназначен файл: sun50i-a64-bananapi-m64.dtb, из него получим файл DTS, командой (файл sun50i-a64-bananapi-m64.dts):

dtc -I dtb -O dts /boot/dtb/allwinner/sun50i-a64-bananapi-m64.dtb -o /boot/dtb/allwinner/sun50i-a64-bananapi-m64.dts

В каталоге /boot/dtb/allwinner/overlay располагаются DTBO. Для  платы Banana Pi BPI-M64 в каталоге предназначены файлы с префиксом: sun50i-a64-*.dtbo

Device tree bpi m64

В предыдущей публикации Работа с GPIO на примере Banana Pi BPI-M64. Часть 1. Интерфейс sysfs LED и DS18B20 на 18-контакте разъема типа Raspberry Pi в утилите конфигурирования

armbian-config

был включен интерфейс 1-Wire, в меню называется: w1-gpio. При включение пункта w1-gpio активируется слой в файле sun50i-a64-w1-gpio.dtbo. Конфигурация о подключенных DTBO располагается в файле /boot/armbianEnv.txt. Как раз в строке с ключем overlays= указан файл w1-gpio. Префикс sun50i-a64-* — настроен в конфигурационном файле(параметр overlay_prefix=) и является обязательным для всех DTBO платы Banana Pi BPI-M64

Device tree bpi m64

Если помимо w1-gpio включить интерфейс uart1 файл: sun50i-a64-uart1.dtbo 

то в файле /boot/armbianEnv.txt строка overlays измениться: overlays=uart1 w1-gpio:. названия файлов:

Device tree bpi m64

Использование компилятора DTC

Файл sun50i-a64-w1-gpio.dtbo представлен в бинарном виде и редактировать его напрямую затруднительно, поэтому конвертируем файл формата DTBO в DTS:

dtc -I dtb -O dts /boot/dtb/allwinner/overlay/sun50i-a64-w1-gpio.dtbo -o /boot/dtb/allwinner/overlay/sun50i-a64-w1-gpio.dts

На выходе получим файл: sun50i-a64-w1-gpio.dts. После изменений DTS необходимо обратно его перевести в формат DTBO командой:

cd /boot/dtb/allwinner/overlay
dtc -O dtb -o sun50i-a64-w1-gpio.dtbo sun50i-a64-w1-gpio.dts

Структура файла sun50i-a64-w1-gpio.dts

Файлы DT доступны в GitHub armbian/sunxi-DT-overlays.

Если получать файл DTS из DTBO, то в нем будут содержаться ссылочные секции и символьные понятные метки будут заменены на шестнадцатеричный вид. Поэтому файл sun50i-a64-w1-gpio.dts лучше взять из GitHub sun50i-a64-w1-gpio.dts. Рассмотрим sun50i-a64-w1-gpio.dts:

Device tree bpi m64

Очень интересно получилось, но абсолютно непонятно. Выше был получен файл sun50i-a64-bananapi-m64.dts основного DT процессора AllWinner A64, поэтому составим понятную диаграмму, со ссылками к основному DT, и добавим результирующее DT Linux после загрузки:

Device tree bpi m64 1-wire

Замечание: по мере изучения литературы этот раздел будет в дальнейшем дополняться. Учитывая что новая ветка ядра мало документирована в части GPIO, то потребуется некоторое время на чтение исходников.

Создание своего DTBO для протокола 1-Wire

В предыдущей публикации Работа с GPIO на примере Banana Pi BPI-M64. Часть 1. Интерфейс sysfs LED и DS18B20 на 18-контакте разъема типа Raspberry Pi, был включен интерфейс 1-Wire. Из схемы, 18-контакт называется «PD4«, этот контакт мультиплексирован и также имеет функцию UART4_RTS. При включение 1-Wire лишись полноценного UART4, поэтому перенесем интерфейс на другой контакт. Удалять файл sun50i-a64-w1-gpio.dtbo нет необходимости т.к. в конфигурации его выключим после создания своего DTBO. В качестве шаблона возьмем GitHub sun50i-a64-w1-gpio.dts, и переименуем в sun50i-a64-w1-gpio-custom.dts.

Из схемы возьмем 22-контакт, название «PC0«, никакие функции с этим контактом не связаны.

Внесем изменения в файл sun50i-a64-w1-gpio-custom.dts:

Device tree bpi m64

Компилирует файл .dts в .dtb

cd /boot/dtb/allwinner/overlay
dtc -I dts -O dtb sun50i-a64-w1-gpio-custom.dts -o sun50i-a64-w1-gpio-custom.dtbo

Запустим утилиту конфигурирования платы:

armbian-config

Перейдем по меню: System > Hardware. Список дополнился новым пунктом w1-gpio-custom, выберем его:

Device tree bpi m64

Затем сохранить <Save> и < Back >. Будет предложено перезагрузить палату, соглашаемся и ждем перезагрузки:

Banana Pi BPI-M64 ds18b20

После перезагрузки выполняем команду: 

dmesg | grep -E 'w1|wire'

В результате должны получить примерно такой результат:

Device tree bpi m64 ds18b20

Из которого следует что драйвер 1-Wire был включен на контактах gpio-100 и gpio-64. Теперь можем посмотреть какие контакты использованы в устройстве /soc/pinctrl@1c20800:

cat /sys/kernel/debug/gpio

Device tree bpi m64

Получим значения температуры:

cat /sys/bus/w1/devices/28-0000034aa0ba/w1_slave

Device tree bpi m64

Устройства зарегистрированные в системе, в том числе onewire@0 и onewire@1, можно посмотреть командой:

cd /proc/device-tree/
ls -l

Добавление cron задачи

Но как видим точность вывода установлена по умолчанию, а хотелось бы получать более точные значения, без ручной настройки. Узнать как установить точность на уровне скрипта к драйверу, не удалось. Поэтому настройку будем выполнять через привычный интерфейс sysfs и добавим команду выполнения после загрузки ОС через cron задачи:

Проверка работы демона cron

systemctl status cron

Редактировать cron задачи

crontab -e

Вставить строку, сохранить изменения и перезагрузить плату:
@reboot sleep 5 && sudo echo 12 > /sys/bus/w1/devices/28-0000034aa0ba/w1_slave

Ссылки

Вам также может понравиться

About the Author: Anton

Programistik