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
Quitund 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.