Die hier gezeigten Schritte lassen sich nicht nur für Poky anwenden, sondern auch auf eigene Images übertragen – etwa für SoC-Plattformen wie i.MX. Der Ablauf zum Bauen, Booten und Testen bleibt im Wesentlichen gleich, lediglich die Zielmaschine und zusätzliche Layers unterscheiden sich.
Durch diese Eigenschaften eignet sich Poky besonders gut, um erste Erfahrungen mit Emulatoren zu sammeln und automatisierte Tests in den Entwicklungsprozess einzubinden. Dieser Artikel zeigt den gesamten Ablauf: vom Herunterladen der Quellen über den Image-Build bis hin zum Start in QEMU und der Ausführung von Tests.
Voraussetzungen
git clone git://git.yoctoproject.org/poky
cd poky
Optional: einen stabilen Branch verwenden, z.B. scarthgap:
git checkout scarthgap
source oe-init-build-env
Dadurch wird das Verzeichnis build/ angelegt. In conf/local.conf lassen sich Einstellungen anpassen, etwa die Anzahl paralleler Jobs:
BB_NUMBER_THREADS = "8"
PARALLEL_MAKE = "-j 8"
Ein minimales Image:
bitbake core-image-minimal
Der Build-Prozess dauert je nach Hardware bis zu mehreren Stunden. Das Ergebnis liegt in:
build/tmp/deploy/images/qemux86-64/
Poky bringt ein Startskript mit:
runqemu qemux86-64
Damit wird ein virtuelles System auf Basis von QEMU hochgefahren. Es erscheint eine Login-Shell (Standard-Benutzer: root, kein Passwort).
Das Yocto-Projekt unterstützt die Testinfrastruktur (oeqa). Beispiel: einfache Sanity-Tests.
Für eigene Tests lassen sich Python-Tests in meta/lib/oeqa/runtime/ ergänzen. Ein Beispiel für einen Ping-Test:
from oeqa.runtime.case import OERuntimeTestCase
from oeqa.core.decorator.oetimeout import OETimeout
class PingTest(OERuntimeTestCase):
@OETimeout(60)
def test_ping(self):
status, output = self.target.run("ping -c 3 8.8.8.8")
self.assertEqual(status, 0, msg="Ping fehlgeschlagen:\n%s" % output)
Falls Tests fehlschlagen:
build/tmp/log/oeqa/ prüfenrunqemu interaktiv startenbuild/tmp/work/.../temp/log.do_* analysierenQEMU bietet eine flexible Möglichkeit, Embedded-Linux-Images schnell und unabhängig von echter Hardware zu starten. Entwickler können damit Bootprozesse nachvollziehen, Funktionen prüfen und automatisierte Tests ausführen. Poky dient hier nur als Beispiel zur Image-Erstellung, der Ablauf lässt sich aber ebenso auf eigene oder boardspezifische Builds – etwa für i.MX – übertragen.
Damit wird QEMU zu einem wichtigen Werkzeug in der Embedded-Entwicklung: für frühes Prototyping, kontinuierliche Tests und stabile Release-Prozesse.
]]>Egal ob Sie eine Insulinpumpe oder einen Druckregler für ein Kernkraftwerk entwickeln: Das Schreiben von Softwareanforderungen für sicherheitskritische Anwendungen erfordert eine disziplinierte Vorgehensweise. Dieser Artikel zeigt, wie man präzise, eindeutige und überprüfbare Anforderungen formuliert, die Industriestandards erfüllen und die Zertifizierung unterstützen.
Die meisten Anforderungen werden noch in natürlicher Sprache (NL) formuliert. NL ist flexibel und leicht verständlich, aber anfällig für Mehrdeutigkeit. Schon eine Formulierung wie „bei Bedarf“ kann mehrere Interpretationen zulassen – und damit kritische Fehler verursachen. Deshalb braucht sicherheitsrelevante Entwicklung auch in NL Regeln und Struktur. Eine gute Softwareanforderung ist:
Beispielstruktur:
Der Bediener soll in der Lage sein, [Aktion] am [Objekt] durchzuführen, um [gewünschten Zustand] zu erreichen.
Jede Anforderung sollte definieren:
Eine gut formulierte Anforderung folgt typischerweise einem Subjekt–Prädikat–Objekt (S-P-O)-Muster:
| Subjekt | Prädikat | Objekt |
|---|---|---|
| Das System | soll anzeigen | die aktuelle Herzfrequenz. |
ISO/IEC/IEEE 29148:2018 beschreibt, wie man klare und testbare Anforderungen schreibt und standardisiert die Verwendung modaler Verben:
Best Practice: Verwenden Sie „shall“ nur einmal pro Anforderung. Vermeiden Sie zusammengesetzte Anforderungen ohne „und“, „oder“ oder „mit“. Das Kombinieren von Aktionen macht die Anforderung untestbar und erzeugt mehrere Anforderungen in einer. Wörter wie „ist“, „sind“, „war“ oder „muss“ sind für beschreibende oder einleitende Abschnitte geeignet.
Jede Anforderung sollte beschreiben, was das System tun muss, nicht wie es implementiert wird. Das ist entscheidend für Testbarkeit und Rückverfolgbarkeit. Beispiel:
Das System soll eine MySQL-Datenbank zur Speicherung von EKG-Daten verwenden.
Das beschreibt das Wie, nicht das Was. Die Wahl der Datenbank ist eine Designentscheidung, die in nachgelagerten Dokumenten wie dem Software Architecture Document (SAD) oder Detailed Design Document (DDD) festgelegt wird.
Eine Möglichkeit, Mehrdeutigkeit zu reduzieren, ist die Einführung einer kontrollierten Sprache – einer vereinfachten Teilmenge des Englischen für technische Dokumentation. In der Luft- und Raumfahrt wird z. B. ASD-STE100 (Simplified Technical English) eingesetzt.
Kontrollierte Sprache erzwingt:
Mit einem Styleguide für kontrollierte Sprache lassen sich konsistente und leicht überprüfbare Anforderungen über mehrere Dokumente und Rollen hinweg erstellen.
Mehrdeutigkeit kann entstehen durch lexikalische, syntaktische oder semantische Probleme:
Mehrdeutigkeit schleicht sich oft durch vage Begriffe, Passivkonstruktionen oder unklare Referenzen ein. Beispiel:
„Das System soll das Warnsignal kurz nach Fehlererkennung aktivieren.“
Was bedeutet „kurz“? Wer aktiviert das Signal? Solche Fragen sind in einem sicherheitskritischen Kontext rote Flaggen.
Vermeiden Sie:
Jede Anforderung muss atomar, verifizierbar und eindeutig sein.
Für höhere Sicherheitsstufen ist es notwendig, Anforderungen zu formalisieren. Das bedeutet, sie in eine formale Sprache wie PSL (Property Specification Language) oder LTL (Linear Temporal Logic) zu übersetzen, die Tools prüfen und simulieren können.
Formalisiertes Vorgehen ermöglicht:
„Das System sollte die richtige Dosis mit der richtigen Geschwindigkeit abgeben.“
Probleme: Vage Begriffe wie „richtige Dosis“ und „richtige Geschwindigkeit“. Kein Subjekt definiert. Nicht testbar.
„Wenn das Infusionsprogramm gestartet wird, soll die Steuereinheit das programmierte Medikamentenvolumen mit einer Flussrate zwischen 0,1 und 10,0 ml/h mit einer Genauigkeit von ±5 % abgeben.“
„Das System muss einen Alarm auslösen, wenn die Herzfrequenz abnormal ist.“
Probleme: Was bedeutet „abnormal“? Wie laut oder schnell ist der Alarm? Wann genau soll er auslösen?
„Wenn die Herzfrequenz des Patienten unter 40 bpm fällt oder 180 bpm überschreitet und dies länger als 3 Sekunden anhält, soll der Alarm-Controller innerhalb von 1 Sekunde einen 90-dB-Alarm auslösen.“
„Das System soll den Strahl aktivieren, wenn der Bediener die Behandlung startet.“
Probleme:
„Das System soll den Strahlenbündel nur aktivieren, wenn der Ganty in der richtigen Position ist, der Hardware-Interlock geschlossen ist und die Behandlungskonsole einen gültigen ‚Start‘-Befehl vom Bediener erhält.“
Die Entwicklung eines sicherheitskritischen Produkts ist selten Aufgabe einer Einzelperson. Bevor die nächsten Schritte im V-Modell begonnen werden, müssen die Softwareanforderungen überprüft werden. Aber das ist Thema für das nächste Mal.
Als Ingenieure und Softwareentwickler sind wir darauf trainiert, in Strukturen, Zuverlässigkeit und Nachvollziehbarkeit zu denken. Diese Denkweise deckt sich eng mit der Philosophie der IEC 62304.
Funktionale Sicherheit stellt sicher, dass ein System korrekt auf seine Eingaben reagiert, insbesondere unter Fehlersituationen. Im medizinischen Bereich bedeutet das: Die Software darf weder Patienten noch Anwender gefährden, selbst im Falle vorhersehbarer Fehler.
Beispielsweise muss eine softwaregesteuerte Infusionspumpe, die Medikamente verabreicht, Sensorfehler, Kommunikationsausfälle und Anwenderfehler so behandeln, dass keine gefährlichen Ereignisse entstehen. Hier greift die funktionale Sicherheit.
Die IEC 62304 definiert drei Software-Sicherheitsklassen:
Abhängig von der Klassifizierung steigt der Umfang an Test- und Verifikationsaktivitäten erheblich. Für Software der Klasse C müssen umfassende Teststrategien umgesetzt werden, darunter Unit-Tests, Integrationstests und Systemverifikation mit Nachverfolgbarkeit bis hin zu den Risikokontrollen.
Testen im Kontext der IEC 62304 bedeutet nicht nur, Fehler zu finden – es geht darum, nachzuweisen, dass die Software ihre Sicherheitsanforderungen unter allen vorhersehbaren Bedingungen erfüllt. Testen muss daher sein:
Typische Testaktivitäten sind:
Wir sind bekannt für unsere Präzision und Dokumentationsstrenge – und in diesem Fall ist das von Vorteil. Die IEC 62304 fordert Nachvollziehbarkeit über den gesamten Software-Lebenszyklus. Jede Anforderung muss verknüpft sein mit:
Werkzeuge wie Polarion, Codebeamer oder auch Open-Source-Alternativen wie ReqView und Robot Framework können diese Strenge unterstützen.
Testen auf funktionale Sicherheit darf nicht isoliert erfolgen. Es muss mit weiteren Normen abgestimmt sein, wie etwa:
Beispielsweise könnte eine Software der Klasse C einen softwarebasierten Failsafe enthalten, der aktiviert wird, wenn ein Hardware-Sensor inkonsistente Daten meldet. Dieses Verhalten muss sowohl in der Software (simulierter Sensorfehler) als auch im Systemtest (tatsächliche Fehler-Injektion) geprüft werden.
Testen auf funktionale Sicherheit nach IEC 62304 ist nicht nur ein regulatorisches Pflichtfeld – es ist eine Denkweise. Sie erfordert ein tiefes Verständnis sowohl der Softwarearchitektur als auch der klinischen Risiken.
Wir sind hier gut aufgestellt. Unser Fokus auf Prozessdisziplin, Risikomanagement und technische Integrität bietet eine solide Basis für die Entwicklung sicherer und zuverlässiger Medizintechnik-Software.
Am Ende geht es beim guten Testen nicht darum, jede Codezeile abzudecken – sondern darum, mit dem Wissen schlafen zu können, dass die Software niemanden gefährden wird.
]]>Ein guter Unit Test erfüllt mindestens eine dieser Bedingungen:
Trivial:
TEST(UserTest, GetNameReturnsName) {
User u("Alice");
EXPECT_EQ("Alice", u.getName());
}
Kein echter Mehrwert, bestätigt nur, dass getName() zurückgibt, was im Konstruktor gesetzt wurde.
Mehrwert:
TEST(PasswordTest, RejectsShortPasswords) {
User u("Alice");
EXPECT_THROW(u.setPassword("123"), std::invalid_argument);
}
Dieser Test prüft eine Geschäftsregel: Passwörter müssen Mindestanforderungen erfüllen.
Unit Tests mit Mehrwert konzentrieren sich auf Verhalten, Regeln und Robustheit. Sie sollen nicht die Implementierung abbilden, sondern Vertrauen schaffen und Wissen konservieren. Schlechte Tests sind Ballast, gute Tests sind Investitionen in Qualität und Wartbarkeit.
]]>