www.mikrocontroller.net

Ct Lab Client Library

Die Ct Lab Client Library ist eine Klassenbibliothek für das c´t-Lab der Zeitschrift c´t im Allgemeinen und für das darauf basierende FPGA Lab im Speziellen. Damit können unter Windows Anwendungen erstellt werden, welche das c´t-Lab oder das FPGA Lab steuern können. Falls andere c´t-Lab-Geräte (d.h. Module wie z.B. DCG, DDS oder DIV) oder andere Anwendungen auf dem FPGA-Modul gesteuert werden sollen, sind Anpassungen vorzunehmen, die Komponente für das FPGA Lab kann dabei als Beispiel genutzt werden. Die Ct Lab Client Library kann aus allen .NET-fähigen Programmierumgebungen genutzt werden. Sie benötigt die Laufzeitumgebung des Microsoft .NET Framework 3.5.

Inhaltsverzeichnis

[Bearbeiten] Codebeispiele

Zu Beginn sollen hier einige Codeauszüge gezeigt werden, um die Verwendung der Bibliothek zu demonstrieren.

[Bearbeiten] Anwendungen auf Geräteebene mit dem FPGA Lab

Diese Beispiele beziehen sich zwar auf das FPGA Lab, es lassen sich aber mit wenig Aufwand ähnliche Programmierschnittstellen für andere c´t-Lab-Geräte (Module) schaffen. Die Basisfunktionalität ist vorhanden, die Implementierung für das FPGA Lab kann als Beispiel für eigene Erweiterungen dienen.

Das folgende Beispiel erzeugt ein amplitudenmoduliertes Signal:

// Configure DDS channel 0 (carrier, modulated by DDS channel 1).
fpgaLab.DdsGenerators[0].Waveform = Waveforms.Sine;
fpgaLab.DdsGenerators[0].Frequency = 1000;
fpgaLab.DdsGenerators[0].Amplitude = (short)(fpgaLab.DdsGenerators[0].MaximumAmplitude * 1 / 2);
fpgaLab.DdsGenerators[0].AmplitudeModulationSource = ModulationAndSynchronizationSources.DdsGenerator1;
 
// Configure DDS channel 1 (modulator).
fpgaLab.DdsGenerators[1].Waveform = Waveforms.Sine;
fpgaLab.DdsGenerators[1].Frequency = 100;
fpgaLab.DdsGenerators[1].Amplitude = (short)(fpgaLab.DdsGenerators[1].MaximumAmplitude * 1 / 4);
 
// Flush all modifications, i.e. send all set commands that have modified values.
appliance.SendSetCommandsForModifiedValues();

Und so lässt sich der Universalzähler auf eine Frequenzmessung mit 100 ms Torzeit einstellen. Die Abfragekommandos für die Messwerte werden regelmäßig gesendet, bei einer Änderung des Messwertes wird das Ereignis ValueChanged ausgelöst.

// Configure the universal counter.
fpgaLab.UniversalCounter.PrescalerMode = PrescalerModes.GatePeriod_100ms;
 
// Flush all modifications, i.e. send all set commands that have modified values.
appliance.SendSetCommandsForModifiedValues();
 
// Listen to counter changes and display them.
fpgaLab.UniversalCounter.ValueChanged +=
    (sender, e) => Console.WriteLine("Counter reported a new frequency: {0}", e.Value);
 
// Send the cached query commands periodically.
appliance.StartSendingQueryCommands(_queryCommandSendPeriod);

[Bearbeiten] Anwendungen auf der Ebene der Kommandos und Nachrichten

So lässt sich ein Kommando direkt erstellen und absenden. Diese Zeilen senden den Wert 128 an den Subkanal 1.

// Send a command.
var setCommand = new SetCommand(_channel, 1);
setCommandCache.Add(setCommand);
setCommand.SetValue(128);
setCommandCache.SendCommandsForModifiedValues();

Und so kann man per Ereignisbehandlung empfangene Nachrichten verarbeiten. Hier wird auf Nachrichten von Subkanal 255 reagiert.

// Prepare to receive messages.
var messageContainer = messageCache.Register(_channel, 255);
messageContainer.MessageUpdated +=
    (sender, e) => Console.WriteLine("Message received, channel {0}/{1}, raw value {2}",
                                     messageContainer.Message.Channel,
                                     messageContainer.Message.Subchannel,
                                     messageContainer.Message.RawValue);

[Bearbeiten] Logische Struktur

Struktur der Bibliothek

Die Ct Lab Client Library ist in mehrere Ebenen gegliedert, die über Schnittstellen miteinander verbunden sind. Implementierungen lassen sich mit geringen Änderungen austauschen, auch zur Laufzeit. Diese Ebenen spiegeln sich in den Komponenten und Namensräumen der Bibliothek wider.

[Bearbeiten] Verbindungen

Auf der Verbindungsebene wird das Versenden und Empfangen von Zeichenketten über die jeweils genutzte Schnittstelle gesteuert. Diese Zeichenketten entsprechen auf den höheren Ebenen Befehlen und Nachrichten. Die darüberliegenden Ebenen arbeiten mit dieser Verbindungsebene, ohne sich um die konkrete physikalische Ausprägung (z.B. seriell, USB, LAN) kümmern zu müssen.

Es wird eine Implementierung für (physikalische oder emulierte) serielle Ports sowie eine für eine simulierte Verbindung mitgeliefert. Letztere ist für Tests ohne c´t-Hardware nützlich, sie kann gesendete Zeichenketten protokollieren sowie den Empfang von Zeichenketten simulieren.

[Bearbeiten] Kommandos und Nachrichten

Auf dieser Ebene werden die Zeichenketten der Verbindungsebene gekapselt und als gesendete Kommandos beziehungsweise empfangene Nachrichten abstrahiert. Das Assemblieren der zu sendenden Zeichenketten und das Parsen der empfangenen Zeichenketten findet hier statt. Ein Cache verhindert das unnötige Mehrfachabsenden von Kommandos. Es kann außerdem ein Scheduler genutzt werden, welcher vorher registrierte Kommandos (z.B. zur Messwertabfrage) regelmäßig abschickt. Eintreffende Nachrichten lösen Ereignisse aus, die abonniert werden können.

Diese Ebene ist generisch realisiert und muss in der Regel nicht angepasst werden. Diese Standardimplementierung wird natürlich mitgeliefert.

[Bearbeiten] Geräte

Auf dieser Ebene werden wiederum die Befehle und Nachrichten gekapselt und als Gerätemanipulationen beziehungsweise Wertänderungen abgebildet. Gerätemanipulationen, z.B. das Verändern von Einstellungen, werden hier auf die entsprechenden Kommandos umgesetzt, empfangene Nachrichten auf Änderungen der zugeordneten Werte. Solche Wertänderungen lösen dann auf dieser Ebene wiederum Ereignisse aus, die abonniert werden können.

Diese Ebene bildet die einzelnen vorhandenen Geräte (d.h. die c´t-Lab-Module) ab. Die Basisimplementierung wird mitgeliefert, ebenso eine konkrete Implementierung für ein als FPGA Lab konfiguriertes FPGA-Modul. Mit letzterer kann man die auf dem FPGA Lab vorhandenen DDS- und Pulsgeneratoren sowie den Universalzähler intuitiv steuern.

[Bearbeiten] Umgebung

Diese Ebene repräsentiert die als Hardware vorhandene Arbeitsumgebung, d.h. die konkrete Bestückung des c´t-Lab mit Geräten (Modulen). Hier werden die verwendeten c´t-Lab-Module und deren Zuordnung zu den verfügbaren Kanälen berücksichtigt. Diese Ebene stellt auch den zentralen Einstiegspunkt der Bibliothek zur Verfügung.

[Bearbeiten] Technische Realisierung

Die Klassenbibliothek wurde in C# und basierend auf dem Microsoft .NET Framework 3.5 entwickelt und kann daher aus allen .NET-fähigen Programmierumgebungen genutzt werden. Es werden einige Fremdkomponenten eingebunden und gängige Designprinzipien angewendet. Diese werden hier kurz erwähnt, mehr würde den Rahmen sprengen. Wer die Bibliothek ohnehin nur anwenden will, muss sich um diese Details auch nicht kümmern.

[Bearbeiten] Dependency Injection mit StructureMap

Zur besseren Modularisierung wird Dependency Injection angewendet und dafür der Dependency-Injection-Container StructureMap eingesetzt. Auf diese Weise werden die einzelnen Ebenen streng getrennt und nur über Schnittstellen verbunden. Die konkrete Implementierung einer Schnittstelle wird sehr spät festgelegt und kann auch mit wenig Aufwand geändert werden. Das hat nicht zuletzt Vorteile bei den automatisierten Tests und wird dort intensiv genutzt.

[Bearbeiten] Automatisierte Unit-Tests mit xUnit.net und Rhino Mocks

Die gesamte Entwicklung erfolgte testgetrieben unter intensivem Einsatz automatisierter Unit-Tests nach den Prinzipien des Test-Driven Development (TDD) beziehungsweise des Behaviour-Driven Development (BDD). Für die Unit-Tests wurde xUnit.net eingesetzt, für die Erstellung der dafür nötigen simulierten Objekte (Mocks) Rhino Mocks. Mit Hilfe der xUnit.BDDExtensions wurden relativ knappe, kurze Tests erstellt, die gleichzeitig als Spezifikation dienen. Wie bei BDD üblich, wurde die Namensgebung der Testklassen und -methoden so gewählt, dass sich mehr oder weniger natürlichsprachige Anforderungen ergeben, deren Einhaltung der jeweilige Test dann überprüft.

Die gesamte Testsuite nutzt die simulierte Verbindung und kann daher ohne vorhandene c´t-Lab-Hardware durchlaufen werden. Sie enthält einerseits Tests, welche isolierte Klassen und Ebenen testen. Andere Tests überprüfen aber auch die Integration und die korrekte Zusammenschaltung über den Dependency-Injection-Container (StructureMap).

[Bearbeiten] Wichtige Dateien und Verzeichnisse

Alle Dateien einschließlich des Quellcodes stehen im SVN-Repository des FPGA Lab zur Verfügung. Auf dieses Repository kann auch mit einem SVN-Client unter svn://mikrocontroller.net/fpgalab zugegriffen werden.

[Bearbeiten] Ablauffähige Bibliothek

Unter ".\Binary\Windows\Ct Lab Client Library" ist die Ct Lab Client Library fertig kompiliert in zwei Versionen verfügbar.

  • FpgaLab.dll enthält den kompletten hier beschriebenen Funktionsumfang inklusive der für das FPGA Lab angepassten Geräte- und Umgebungsebene.
  • CtLab.dll ist allgemeiner gehalten und beinhaltet die Teile für das FPGA Lab nicht. Diese DLL eignet sich daher gut für eigene c´t-Lab-Anwendungen.

[Bearbeiten] Anwendungsbeispiele

Unter ".\Binary\Windows\Test Console" befindet sich der Quellcode für eine kleine Consolenanwendung, welche mehrere Beispiele enthält. Diese zeigen die Anwendung der Ct Lab Client Library für verschiedene Aufgaben. Einige dieser Beispiele funktionieren ohne vorhandene c´t-Lab-Hardware, andere setzen ein FPGA Lab voraus.

[Bearbeiten] Quellcode

Unter ".\Windows\Ct Lab Client Library" ist der C#-Quellcode in Form einer Projektmappe für Visual Studio verfügbar. Durch das verwendete Designprinzip bedingt gibt es recht viele Projekte und daraus resultierend auch Assemblies, die sich aber mit dem kostenlosen ILMerge von Microsoft nach dem Übersetzen zu einer einzigen DLL zusammenbinden lassen.

  • Ct Lab.sln ist die Projektmappendatei für Visual Studio 2008, es genügt die kostenlose Express-Variante.
  • Ct Lab.xunit ist die Projektdatei für den Testrunner von xUnit.net. Sie referenziert alle Testassemblies. Natürlich können die Tests aber auch in anderen Testrunnern (z.B. in ReSharper) ausgeführt werden.

[Bearbeiten] Externe Komponenten und Werkzeuge

Unter ".\Windows\Externals" befinden sich die eingebundenen Fremdkomponenten, die für eine erfolgreiche Übersetzung nötig sind. Die Visual-Studio-Projekte referenzieren diese Komponenten über relative Pfade genau in diesen Ordnern. Um die Testsuiten ablaufen zu lassen, ist aber noch ein installiertes xUnit.net nötig.

[Bearbeiten] Übersetzen des Quellcodes, Bauen der DLLs

Nach dem Übersetzen können die entstandenen Assemblies sofort in eigenen Anwendungen benutzt werden. Bequemer ist es allerdings, diese zuvor noch zu einer einzelnen kompakten DLL zusammenzubinden. Dazu gibt es von Microsoft das kostenlose Werkzeug ILMerge.

Die Batchdatei Merge.bat im Ordner ".\Windows\Ct Lab Client Library\Build" kann verwendet werden, um ILMerge mit den richtigen Parametern aufzurufen. Es werden die beiden Dateien FpgaLab.dll und CtLab.dll im selben Ordner erstellt. ILMerge befindet sich allerdings nicht im Repository sondern muss separat (z.B. vom Microsoft-Webauftritt) heruntergeladen werden. Die Batchdatei erwartet ILMerge im Ordner ".\Windows\Externals\ILMerge".

[Bearbeiten] Lizenz

Die Ct Lab Client Library ist quelloffen (Open Source) und wird unter der GNU General Public License (GPL) lizensiert. Die Bibliothek nutzt weitere Open-Source-Komponenten, insbesondere StructureMap, xUnit.net, Rhino Mocks und xUnit.BDDExtensions.

[Bearbeiten] Weitere Informationen

Das FPGA Lab basiert auf dem c´t-Lab. Näheres gibt es unter:

  • FPGA Lab: Ein FPGA-basiertes Signallabor

Das c´t-Lab ist ein Projekt von Carsten Meyer, c't magazin. Weitere Informationen gibt es hier:

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net