1. HAL-Entitätsnamen

Alle HAL-Entitäten sind über ihre Namen zugänglich und manipulierbar, daher ist die Dokumentation der Namen von Pins, Signalen, Parametern usw. sehr wichtig. Namen in HAL haben eine maximale Länge von 41 Zeichen (wie durch HAL_NAME_LEN in hal.h definiert). Viele Namen werden in der allgemeinen Form dargestellt, mit formatiertem Text <wie-dies>, der Felder mit verschiedenen Werten darstellt.

Wenn Pins, Signale oder Parameter zum ersten Mal beschrieben werden, wird ihrem Namen der Typ in Klammern vorangestellt (float), gefolgt von einer kurzen Beschreibung. Typische Pin-Definitionen sehen wie diese Beispiele aus:

(bit) parport.<portnum>.pin-<pinnum>-in

Der HAL-Pin, der mit dem physischen Eingangspin <pinnum> des db25-Anschlusses verbunden ist.

(float) pid.<loopnum>.output

Der PID-Regelkreis Ausgang

Gelegentlich kann eine abgekürzte Version des Namens verwendet werden, z. B. könnte der zweite Pin oben einfach mit .output aufgerufen werden, wenn dies möglich ist, ohne dass es zu Verwechslungen kommt.

2. Allgemeine HAL-Namenskonventionen

Einheitliche Namenskonventionen würden die Verwendung von HAL wesentlich erleichtern. Wenn zum Beispiel jeder Encoder-Treiber den gleichen Satz von Pins zur Verfügung stellen und diese auch gleich benennen würde, dann wäre es einfach, von einem Encoder-Treiber zu einem anderen zu wechseln. Leider ist HAL, wie viele Open-Source-Projekte, eine Kombination aus Dingen, die entworfen wurden, und Dingen, die sich einfach entwickelt haben. Infolgedessen gibt es viele Inkonsistenzen. Dieser Abschnitt versucht, dieses Problem zu lösen, indem er einige Konventionen definiert, aber es wird wahrscheinlich noch eine Weile dauern, bis alle Module so konvertiert sind, dass sie ihnen folgen.

Halcmd und andere Low-Level-HAL-Utilities behandeln HAL-Namen als einzelne Einheiten ohne interne Struktur. Die meisten Module haben jedoch eine implizite Struktur. Ein Board bietet beispielsweise mehrere Funktionsblöcke, jeder Block kann mehrere Kanäle haben, und jeder Kanal hat einen oder mehrere Pins. Dies führt zu einer Struktur, die einem Verzeichnisbaum ähnelt. Auch wenn halcmd die Baumstruktur nicht erkennt, kann es durch die richtige Wahl der Namenskonventionen verwandte Elemente zusammenfassen (da es die Namen sortiert). Darüber hinaus können Werkzeuge auf höherer Ebene so gestaltet werden, dass sie eine solche Struktur erkennen, wenn die Namen die notwendigen Informationen liefern. Um dies zu erreichen, sollten alle HAL-Komponenten diese Regeln befolgen:

  • Punkte (".") trennen die einzelnen Ebenen der Hierarchie. Dies ist vergleichbar mit dem Schrägstrich ("/") in einem Dateinamen.

  • Bindestriche („-“) trennen Wörter oder Felder auf derselben Hierarchieebene.

  • HAL-Komponenten sollten keine Unterstriche oder "MixedCase" verwenden.
    [Die unterstrichenen Zeichen wurden entfernt, aber es gibt immer noch einige Fälle, in denen die Mischung nicht stimmt, zum Beispiel pid.0.Pgain anstelle von pid.0.p-gain.]

  • Verwenden Sie in Namen nur Kleinbuchstaben und Zahlen.

3. Namenskonventionen für Hardwaretreiber

Anmerkung

Die meisten Treiber folgen diesen Konventionen in Version 2.0 nicht. Dieses Kapitel ist eher ein Leitfaden für zukünftige Entwicklungen.

3.1. Pins/Parameter-Namen

Hardwaretreiber sollten fünf Felder (auf drei Ebenen) verwenden, um einen PIN- oder Parameternamen wie folgt zu bilden:

<Gerätename>.<Gerätenummer>.<E/A-Typ>.<Kanal-Nummer>.<Spezifischer Name>
(engl. <device-name>.<device-num>.<io-type>.<chan-num>.<specific-name>)

Die einzelnen Felder sind:

_<Gerätename> _ (engl. device-name)

Das Gerät, mit dem der Treiber arbeiten soll. In den meisten Fällen handelt es sich dabei um eine Schnittstellenkarte, aber es gibt auch andere Möglichkeiten.

<Gerät-Nr.> (engl. device-num)

Es ist möglich, mehr als eine Servokarte, eine parallele Schnittstelle oder ein anderes Hardwaregerät in einem Computer zu installieren. Die Gerätenummer identifiziert ein bestimmtes Gerät. Die Gerätenummern beginnen bei 0 und werden inkrementiert.

<E/A-Typ> (engl. io-type)

Die meisten Geräte bieten mehr als eine Art von E/A. Selbst der einfache Parallelport hat sowohl digitale Eingänge als auch digitale Ausgänge. Komplexere Karten können digitale Ein- und Ausgänge, Encoderzähler, PWM- oder Schrittimpulsgeneratoren, Analog-Digital-Wandler, Digital-Analog-Wandler oder andere einzigartige Funktionen haben. Der E/A-Typ wird verwendet, um die Art der E/A zu identifizieren, mit der ein Pin oder Parameter verbunden ist. Idealerweise sollten Treiber, die denselben E/A-Typ implementieren, auch wenn sie für sehr unterschiedliche Geräte bestimmt sind, einen konsistenten Satz von Pins und Parametern und ein identisches Verhalten aufweisen. Beispielsweise sollten sich alle digitalen Eingänge von der HAL aus gesehen gleich verhalten, unabhängig vom Gerät.

<Kanal-Nummer> (engl. channel-number, kurz chan-num)

Praktisch jedes E/A-Gerät verfügt über mehrere Kanäle, und die Kanalnummer identifiziert einen dieser Kanäle. Wie die Gerätenummern beginnen auch die Kanalnummern bei Null und erhöhen sich. Fußnote:[Eine Ausnahme von der Regel "Kanalnummern beginnen bei Null" ist der Parallelport. Seine HAL-Pins sind mit der entsprechenden Pin-Nummer auf dem DB-25-Stecker nummeriert. Dies ist praktisch für die Verdrahtung, aber inkonsistent mit anderen Treibern. Es ist umstritten, ob dies ein Fehler oder eine Funktion ist]. Wenn mehr als ein Gerät installiert ist, beginnen die Kanalnummern auf zusätzlichen Geräten wieder bei Null. Wenn es möglich ist, eine Kanalnummer größer als 9 zu haben, dann sollten die Kanalnummern zweistellig sein, mit einer führenden Null bei Nummern kleiner als 10, um die Sortierreihenfolge zu erhalten. Einige Module haben Pins und/oder Parameter, die mehr als einen Kanal betreffen. Ein PWM-Generator kann z. B. vier Kanäle mit vier unabhängigen "Tastverhältnis"-Eingängen haben, aber einen "Frequenz"-Parameter, der alle vier Kanäle steuert (aufgrund von Hardwarebeschränkungen). Der Frequenzparameter sollte "0-3" als Kanalnummer verwenden.

<Spezifischer-Name>

Einem einzelnen E/A-Kanal kann nur ein einziger HAL-Pin zugeordnet sein, aber die meisten haben mehr als einen. Ein digitaler Eingang hat beispielsweise zwei Pins, von denen einer den Zustand des physischen Pins und der andere den gleichen Zustand invertiert darstellt. So kann der Konfigurator zwischen aktiven High und aktiven Low-Eingängen wählen. Für die meisten E/A-Typen gibt es einen Standardsatz von Pins und Parametern (die so genannte "kanonische Schnittstelle"), die der Treiber implementieren sollte. Die kanonischen Schnittstellen sind im Kapitel Kanonische Geräte-Schnittstellen beschrieben.

Beispiele
motenc.0.encoder.2.position

Der Positionsausgang des dritten Encoderkanals auf der ersten Motenc-Platine.

stg.0.din.03.in

Der Zustand des vierten digitalen Eingangs auf der ersten Servo-to-Go-Karte.

ppmc.0.pwm.00-03.frequency

Die für die PWM-Kanäle 0 bis 3 auf der ersten Pico Systems ppmc-Karte verwendete Trägerfrequenz.

3.2. Funktionsnamen

Hardwaretreiber haben in der Regel nur zwei Arten von HAL-Funktionen: solche, die aus der Hardware lesen und HAL-Pins aktualisieren, und solche, die mit Daten von HAL-Pins in die Hardware schreiben. Sie sollten wie folgt benannt werden:

<device-name>-<device-num>.<io-type>-<chan-num-range>.read|write
<Gerätename> (engl. device-name)

Das gleiche wie für Pins und Parameter.

<Gerät-Nr.> (engl. device-num)

Das spezifische Gerät, auf das die Funktion zugreift.

<E/A-Typ> (engl. io-type)

Optional. Eine Funktion kann auf alle E/A auf einer Karte zugreifen oder nur auf einen bestimmten Typ. So kann es beispielsweise unabhängige Funktionen zum Lesen von Encoderzählern und zum Lesen von digitalen E/A geben. Für solche unabhängigen Funktionen gibt das Feld <io-type> die Art der E/A an, auf die sie zugreifen. Wenn eine einzige Funktion alle von der Karte bereitgestellten E/A liest, wird <io-type> nicht verwendet.
[Hinweis für Treiberprogrammierer: Implementieren Sie KEINE separaten Funktionen für verschiedene E/A-Typen, es sei denn, sie sind unterbrechbar und können in unabhängigen Threads arbeiten. Wenn die Unterbrechung eines Encoder-Lesevorgangs, das Lesen digitaler Eingänge und die anschließende Wiederaufnahme des Encoder-Lesevorgangs zu Problemen führen, dann implementieren Sie eine einzige Funktion, die alles erledigt.]

<chan-num-range>

Optional. Wird nur verwendet, wenn die <io-type> E/A in Gruppen unterteilt ist und verschiedene Funktionen darauf zugreifen.

read|write

Gibt an, ob die Funktion die Hardware liest (engl. read) oder in sie schreibt (engl. write).

Beispiele
motenc.0.encoder.read

Liest alle Encoder auf der ersten Motenc-Platine aus.

generic8255.0.din.09-15.read

Liest den zweiten 8-Bit-Port auf der ersten generischen 8255-basierten digitalen E/A-Karte.

ppmc.0.write

Schreibt alle Ausgänge (Schrittgeneratoren, PWM, DACs und Digital) auf die erste Pico Systems ppmc-Karte.