Pin Control Subsystem für Linux Device Driver meistern
Editor's Note: Embedded Linux wird zum Rückgrat des Internet of Things, und Device Driver sind die Brücke zwischen Applikationen und Hardware. In „Linux Device Drivers Development“ bietet Autor John Madieu einen detaillierten, code-reichen Leitfaden zum Bau dieser Treiber.
Dieser Auszug – Kapitel 14 des Buches – taucht in Pin Control und GPIOs ein, ein kritischer Bereich für Entwickler, die benutzerdefinierte Hardware mit dem Kernel interfacen müssen. Der erste Teil führt das Pin Control Subsystem ein.
Adaptiert aus Linux Device Drivers Development, von John Madieu.
Kapitel 14. Pin Control und GPIO Subsystem
Von John Madieu
In Embedded Linux interagieren Treiber fast immer mit GPIOs oder konfigurieren Pin Multiplexing. Ein „Pin“ ist die physische Ausgabeleitung eines Components, und viele SoCs nutzen denselben Pin für mehrere Funktionen. Beispielsweise kann der i.MX6QDL Pin MX6QDL_PAD_SD3_DAT1 als SD-Datenleitung, UART RTS/CTS-Leitung, FlexCAN Rx-Leitung oder generischer GPIO dienen.
Der Prozess der Auswahl einer Pin-Funktion heißt Pin Muxing, und die Kernel-Komponente, die dies orchestriert, ist der Pin Controller. Im zweiten Teil dieses Kapitels werden wir das General Purpose Input/Output (GPIO) Subsystem erkunden, eine gängige Pin-Funktion.
In diesem Kapitel werden Sie:
- Durch das Pin Control Subsystem gehen und lernen, wie man Pin-Control-Nodes im Device Tree deklariert.
- Das legacy Integer-basierte GPIO API mit dem neueren Descriptor-basierten Interface vergleichen.
- GPIOs handhaben, die auch als Interrupts genutzt werden.
- Sysfs-Interfaces dedicated zu GPIO-Management erkunden.
Pin Control Subsystem
Das pinctrl Subsystem verwaltet Pin Multiplexing und Konfiguration. Geräte, die eine spezifische Pin-Anordnung benötigen, müssen diese im Device Tree beschreiben. Der Pin-Controller-Treiber parst diese Beschreibungen und programmiert den SoC's I/O Controller entsprechend.
Das Subsystem bietet:
- Pin Multiplexing – Wiederverwendung eines einzelnen Pins für mehrere Rollen (UART TX, GPIO, HSI, etc.) auf Per-Group- oder Per-Pin-Basis.
- Pin Konfiguration – Einstellung elektrischer Eigenschaften wie Pull-up/Pull-down, Drive Strength, Debounce und mehr.
Beachten Sie, dass dieses Buch die Nutzung der Pin-Controller-API fokussiert; es deckt nicht das Schreiben eines Pin-Controller-Treibers ab.
Pinctrl und der Device Tree
Im Device Tree beschreibt ein Pin-Controller-Node alle verfügbaren Pin-Gruppen und Funktionen. Jeder Gruppe wird eine Integer-ID zugewiesen, optional begleitet von einem pinctrl-name, der menschenlesbare Namen auf IDs abbildet.
Ein Device Binding spezifiziert die Pin-States, die es benötigt. Zwei Properties verlinken ein Device zu Pin-States:
pinctrl-<ID>– eine Liste von Phandles, die auf Pin-Konfigurations-Nodes zeigen. Mehrere Einträge erlauben einem Device, von mehreren Pin-Controllern konfiguriert zu werden oder mehrere Nodes für einen einzelnen Controller zu kombinieren.pinctrl-name– eine parallele Liste, die Namen jedem State-ID zuweist. State 0 wird meistdefaultgenannt und folgt der Standardliste, definiert ininclude/linux/pinctrl/pinctrl-state.h.
Unten ist ein typischer Device-Tree-Auszug, der Pin-Konfiguration für zwei Geräte zeigt:

Jede Zeile folgt dem Format <PIN_FUNCTION> <PIN_SETTING>:
MX6QDL_PAD_DISP0_DAT15__GPIO5_IO09 0x80000000 MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
Der erste Token (MX6QDL_PAD_DISP0_DAT15__GPIO5_IO09) identifiziert die Pin-Funktion; der zweite Token (0x80000000) kodiert Konfigurationsbits (Pull-up/down, Drive Strength, etc.). Diese Makros sind in architekturspezifischen Header-Dateien definiert wie arch/arm/boot/dts/imx6q-pinfunc.h.
Um einen Pin-State in Treibercode zu programmieren, folgen Sie diesen Schritten während der Initialisierung (typischerweise in 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");
Der Helper pinctrl_get_select_default() ruft automatisch den default State ab und wendet ihn an. Wenn ein Device einen init State bereitstellt, wendet der Core diesen State vor probe() an und kehrt dann zu default zurück, es sei denn, der Treiber ändert ihn.
Wenn fertig, geben Sie den Controller mit pinctrl_put(pinctrl) frei oder nutzen die Resource-Managed-Variante devm_pinctrl_put(pinctrl).
Hier ist ein konkretes Beispiel aus der am335x-evm.dts Datei:
dcan1: d_can@481d0000 { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&d_can1_pins>; };
Im passenden Treiber:
pinctrl = devm_pinctrl_get_select_default(&pdev->dev); if (IS_ERR(pinctrl)) dev_warn(&pdev->dev, "pins are not configured from the driver");
Wenn der Treiber's probe() läuft, ist die default Pin-Konfiguration bereits in Platz.
Der nächste Teil wird das GPIO Subsystem im Detail abdecken.
Reprinted with permission from Packt Publishing. Copyright © 2017 Packt Publishing
John Madieu ist Embedded Linux und Kernel Engineer basiert in Paris. Er entwickelt Treiber und BSPs für Kunden in Automation, Transport, Healthcare, Energie und Defense. John arbeitet bei EXPEMB, einem Pionier in Computer-on-Module Design, und ist ein aktiver Open-Source-Advokat, der glaubt, dass Wissensaustausch Innovation beschleunigt.
Internet der Dinge-Technologie
- Warum Industrial-IoT-Systeme Hauptziele für Cyberangriffe sind – und wie man sie sichert
- Von Elfenbein zu Bakelit: Die Entwicklung moderner Kunststoffe nachzeichnen
- Zukunftsausblick: Industrial IoT für Production Excellence vorantreiben
- Wer hat das Sagen im vernetzten Auto? Einblicke aus Fahrersicht
- Sechs bewährte Schritte zur Absicherung eingebetteter IoT-Systeme
- SaaS-Adoption in Produktentwicklung: Schlüssel-Hürden & Chancen – Teil 2
- SaaS-Adoption in der Produktentwicklung erreicht Wendepunkt – Einblicke von PTC
- Den idealen IoT-Entwicklungspartner wählen: Kernherausforderungen & Lösungen
- Industrial PCs: Das Rückgrat komplexer Steuerung in der IIoT-Revolution
- Schlüsselfaktoren für erfolgreiche Enterprise-IoT-Entwicklung: Einblicke von Nokia-Experten