Разработка драйверов устройств Linux:подсистема управления контактами
Примечание редактора:встроенное ядро Linux уже играет жизненно важную роль во встраиваемых системах, и его важность будет расти в удовлетворении разнообразных требований Интернета вещей (IoT). В свою очередь, драйверы устройств обеспечивают критически важную связь между приложениями и самими устройствами Интернета вещей. В разделе «Разработка драйверов устройств для Linux» автор Джон Мадье предлагает всесторонний взгляд на разработку этих драйверов, сочетая подробное объяснение с множеством примеров кода.
В этом отрывке, главе 14 книги, основное внимание уделяется контролю контактов и GPIO - области, имеющей особое значение для разработчиков встроенных систем, стремящихся взаимодействовать с настраиваемыми аппаратными устройствами. Эта первая часть этого отрывка знакомит с подсистемой управления выводами.
Адаптировано из статьи Джона Мадье по разработке драйверов устройств для Linux.
Глава 14. Управление контактами и подсистема GPIO
Автор:Джон Мадье
Большинство разработчиков встроенных драйверов и ядра Linux пишут с использованием GPIO или играют с мультиплексированием контактов. Под выводами я подразумеваю исходящую линию компонента. SoC выполняет мультиплексирование контактов, что означает, что контакт может иметь несколько функций, например, MX6QDL_PAD_SD3_DAT1 в arch / arm / boot / dts / imx6dl-pinfunc.h может быть либо линией данных SD3 1, cts / rts UART1, Rx Flexcan2, либо нормальный GPIO.
Механизм выбора режима работы вывода называется мультиплексированием выводов. Система, за которую отвечает, называется контроллером контактов. Во второй части главы мы обсудим ввод вывода общего назначения ( GPIO ), который представляет собой особую функцию (режим), в которой может работать пин.
В этой главе мы:
-
Пройдитесь по подсистеме управления контактами и посмотрите, как можно объявить свои узлы в DT
-
Изучите как устаревшие интерфейсы GPIO на основе целых чисел, так и новый интерфейс API на основе дескрипторов
-
Работа с GPIO, сопоставленным с IRQ
-
Обрабатывать интерфейсы sysfs, выделенные для GPIO
Подсистема управления контактами
Элемент управления Закрепить ( pinctrl ) подсистема позволяет управлять мультиплексированием контактов. В DT устройства, которым необходимо мультиплексировать выводы определенным образом, должны декларировать необходимую им конфигурацию управления выводами.
Подсистема pinctrl обеспечивает:
-
Мультиплексирование выводов, которое позволяет повторно использовать один и тот же вывод для разных целей, например, один вывод является выводом UART TX, линией GPIO или Линия данных HSI. Мультиплексирование может влиять на группы контактов или отдельные контакты.
-
Конфигурация выводов с применением электронных свойств выводов, таких как подтягивание, опускание, сила драйвера, период устранения дребезга и т. д.
Цель этой книги ограничивается использованием функций, экспортируемых драйвером контроллера контактов, а не написанием драйвера контроллера контактов.
Pinctrl и дерево устройств
Pinctrl - это не что иное, как способ собрать контакты (не только GPIO) и передать их драйверу. Драйвер контроллера выводов отвечает за анализ описаний выводов в DT и применение их конфигурации в микросхеме. Драйверу обычно требуется набор из двух вложенных узлов для описания групповых конфигураций контактов. Первый узел описывает функцию группы (для какой цели будет использоваться группа), второй содержит конфигурацию контактов.
То, как назначаются группы контактов в DT, сильно зависит от платформы и, следовательно, от драйвера контроллера контактов. Каждому состоянию управления выводом дается целочисленный идентификатор, начинающийся с 0 и идущий подряд. Можно использовать свойство name, которое будет отображаться поверх идентификаторов, чтобы одно и то же имя всегда указывало на один и тот же идентификатор.
Собственная привязка каждого клиентского устройства определяет набор состояний, которые должны быть определены в его узле DT, а также следует ли определять набор идентификаторов состояний, которые должны быть предоставлены, или определять набор имен состояний, которые должны быть предоставлены. В любом случае узел конфигурации контактов может быть назначен устройству с помощью двух свойств:
-
pinctrl-
:позволяет указать список конфигураций pinctrl, необходимых для определенного состояния устройства. Это список фандлов, каждый из которых указывает на узел конфигурации выводов. Эти указанные узлы конфигурации контактов должны быть дочерними узлами контроллера контактов, который они настраивают. В этом списке может существовать несколько записей, чтобы можно было настроить несколько контроллеров контактов или чтобы состояние могло быть построено из нескольких узлов для одного контроллера контактов, каждый из которых вносит свой вклад в общую конфигурацию. -
pinctrl-name:позволяет дать имя каждому состоянию в списке. Запись списка 0 определяет имя для целочисленного идентификатора состояния 0, запись списка 1 для идентификатора состояния 1 и т. Д. Идентификатору состояния 0 обычно присваивается имя default . . Список стандартизованных состояний можно найти в include / linux / pinctrl / pinctrl-state.h.
Ниже приводится отрывок из DT, показывающий некоторые узлы устройств вместе с их узлами управления контактами:
В предыдущем примере конфигурация контактов дается в форме
MX6QDL_PAD_DISP0_DAT15__GPIO5_IO09 0x80000000
MX6QDL_PAD_DISP0_DAT15__GPIO5_IO09 представляет функцию вывода, которая в данном случае является GPIO, а 0x80000000 представляет настройки вывода. Для этой строки
MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
MX6QDL_PAD_EIM_D25__UART3_RX_DATA представляет функцию вывода, которая является линией RX UART3, а 0x1b0b1 представляет собой настройки.
Функция вывода - это макрос, значение которого имеет значение только для драйвера контроллера вывода. Обычно они определяются в файлах заголовков, расположенных в arch // boot / dts /. Если, например, используется четырехъядерный процессор UDOO с четырехъядерным процессором i.MX6 (ARM), заголовок функции вывода будет иметь вид arch / arm / boot / dts / imx6q-pinfunc.h. Ниже приведен макрос, соответствующий пятой строке контроллера GPIO5:
#define MX6QDL_PAD_DISP0_DAT11__GPIO5_IO05 0x19c 0x4b0 0x000 0x5 0x0
Эти предыдущие узлы вызываются из соответствующего узла, зависящего от драйвера. Причем эти контакты настраиваются при инициализации соответствующего драйвера. Перед выбором состояния группы контактов необходимо сначала получить управление контактами с помощью функции pinctrl_get (), вызвать pinctrl_lookup_state (), чтобы проверить, существует ли запрошенное состояние или нет, и, наконец, pinctrl_select_state (), чтобы применить состояние.
Ниже приведен пример, показывающий, как получить контактный элемент управления и применить его конфигурацию по умолчанию:
Обычно такие действия выполняются при инициализации драйвера. Подходящим местом для этого кода может быть функция probe ().
pinctrl_select_state () внутренне вызывает pinmux_enable_setting (), который, в свою очередь, вызывает pin_request () на каждом контакте в узле управления контактами.
Управление выводом можно освободить с помощью функции pinctrl_put (). Можно использовать версию API с управлением ресурсами. Тем не менее, можно использовать pinctrl_get_select (), учитывая имя состояния, которое нужно выбрать, для настройки pinmux. Функция определена в include / linux / pinctrl / consumer.h следующим образом:
статическая структура pinctrl * pinctrl_get_select (struct device * dev,
const char * name)
где * name - это название штата, записанное в свойстве pinctrl-name. Если имя состояния задано по умолчанию, можно просто вызвать функцию pinctr_get_select_default (), которая является оболочкой для pinctl_get_select ():
статическая структура pinctrl * pinctrl_get_select_default (
struct device * dev)
{
return pinctrl_get_select (dev, PINCTRL_STATE_DEFAULT);
}
Давайте посмотрим на реальный пример в файле dts для конкретной платы (am335x-evm.dts):
dcan1:d_can @ 481d0000 {
status =«хорошо»;
pinctrl-names =«по умолчанию»;
pinctrl-0 =<&d_can1_pins>;
};
И в соответствующем драйвере:
pinctrl =devm_pinctrl_get_select_default (&pdev-> dev);
if (IS_ERR (pinctrl))
dev_warn (&pdev-> dev, «выводы не настраиваются из драйвера»);
Ядро управления контактами автоматически потребует для нас состояние pinctrl по умолчанию при зондировании устройства. Если определить состояние инициализации, ядро pinctrl автоматически установит pinctrl в это состояние перед функцией probe (), а затем переключится в состояние по умолчанию после probe () (если драйвер уже явно не изменил состояния).
В следующей статье будет обсуждаться подсистема GPIO.
Перепечатано с разрешения Packt Publishing. Авторские права © 2017 Packt Publishing
Джон Мадье (John Madieu) - разработчик встроенного Linux и ядра, живущий во Франции, в Париже. Его основная деятельность состоит в разработке драйверов и пакетов поддержки (BSP) для компаний в таких областях, как автоматизация, транспорт, здравоохранение, энергетика и военная промышленность. Джон работает в EXPEMB, французской компании, которая является пионером в разработке электронных плат на основе «компьютер на модуле» и во встроенных решениях Linux. Он энтузиаст открытого исходного кода и встраиваемых систем, убежденный в том, что можно узнать больше, только поделившись знаниями.
Интернет вещей
- Устранение уязвимостей безопасности промышленного Интернета вещей
- Развитие современных пластмасс
- Перспективы развития промышленного Интернета вещей
- Кто отвечает за подключенный автомобиль? Спросите у водителя в цикле
- Шесть шагов для защиты встроенных систем в IoT
- Переломный момент для SaaS в разработке продукта (часть 2)
- Переломный момент для SaaS в разработке продукта:Часть 1
- Проблемы при выборе подходящего поставщика разработки для Интернета вещей
- Требования IPC для сложного управления
- Каковы ключевые движущие силы успешной разработки корпоративного Интернета вещей?