Gerätetreiber entwickeln

Ein Gerätetreiber übersetzt die öffentliche API einer Geräteklasse in das Protokoll eines konkreten Geräts. Kommunikationsdetails und fachliche Messabläufe bleiben außerhalb des spezifischen Treibers.

Die verbindlichen Laufzeitregeln für Statuscodes, Rückgabeformen, Initialisierung, Busstrategie, Quantities und Safety beschreibt Gemeinsames Gerätetreiber-Verhalten. Diese Seite konzentriert sich auf die Implementierung eines konkreten Treibers.

Die richtige Basisklasse

Ein Leistungsmesser erbt von POWERMETER, ein Empfänger von RECEIVER und ein Signalgenerator von SIGNALGENERATOR. Diese Basisklassen definieren Methodennamen, Einheitenkonvention, Konfigurationsschema und gemeinsame Fallbacks. Direktes Erben von DRIVER ist nur für eine neue Geräteklasse sinnvoll.

from mpylab.device.powermeter import POWERMETER as BasePowerMeter

class POWERMETER(BasePowerMeter):
    def __init__(self, SearchPaths=None):
        super().__init__(SearchPaths=SearchPaths)
        self._internal_unit = "dBm"

Rückgabeform und Signatur folgen immer der Basisklasse. Abfragen liefern meist (status, value); Aktionsmethoden können auch nur status liefern. Messwerte werden als SCUQ-Quantity in der angeforderten Kanaleinheit zurückgegeben.

Initialisierung

Alle gepflegten Treiber verwenden die Signatur Init(ini=None, channel=None, ignore_bus=None). None wählt den gerätespezifischen Standard: aktive Geräte öffnen normalerweise ihren Bus, rein passive und virtuelle Geräte setzen _default_ignore_bus = True. Explizites True oder False überschreibt diesen Standard.

super().Init(ini, channel, ignore_bus=ignore_bus) liest die INI-Datei, löst die Busstrategie auf und richtet gegebenenfalls die Kommunikationsklasse ein. Das Ergebnis steht anschließend in self.bus_ignored. Ein konkreter aktiver Treiber kehrt bei self.error oder self.bus_ignored zurück, bevor er Presets, Moduswechsel oder andere Gerätebefehle sendet. Ein Fehler beim Moduswechsel oder bei einer Bereichseinstellung darf nicht stillschweigend als Erfolg behandelt werden.

Kommunikation

DRIVER stellt write, read und query über eine Kommunikationsklasse bereit. GPIB, VISA, Prologix und Debug-/Virtualbetrieb werden dadurch vereinheitlicht. Direkter Zugriff auf self.dev ist nur begründet, wenn die gemeinsame Schnittstelle eine benötigte Funktion nicht abbildet.

Antworten werden vollständig konsumiert. Mehrzeilige oder zusätzlich terminierte Geräteantworten benötigen eine klar benannte Drain-Strategie, damit kein Rest die nächste Abfrage verfälscht.

Einheiten

_internal_unit ist die feste Einheit, in der das Gerät Werte liefert oder akzeptiert. Die Kanaleinheit aus der INI-Datei ist die vom Anwender angeforderte Einheit. Umrechnungen erfolgen über mpylab.tools.uconv und nicht über lokale dB-Formeln.

Virtueller Treiber und Tests

Für neue Geräteklassen oder komplexe APIs ist ein virtueller Treiber mit derselben öffentlichen API sinnvoll. Tests decken mindestens ab:

  • Initialisierung ohne Hardware;

  • Befehlsformat und Antwortparser;

  • Einheiten und Unsicherheit;

  • ungültige Parameter und Gerätestatus;

  • Mehrkanalinstanzen ohne gemeinsam veränderlichen Zustand;

  • Trigger-, Nonblocking- und Timeout-Verhalten;

  • sicheres Quit und RF-Off, falls vorhanden.

Inline-Smoke-Tests und Beispiel-INI-Dateien erleichtern den späteren Hardwaretest, ersetzen aber keine automatisierten Tests.

Treiber, die mehrere logische Graphknoten über ein physisches Gerät bereitstellen, müssen zusätzlich dem Mehrkanalmodell aus gemeinsamem Controller und Kanalinstanzen folgen.