Continuous Integration

Schneller Testen mit MicroPython

15. April 2018, 9:00 Uhr | Von Michael Dümig und Hans-Christian Wild
Diesen Artikel anhören

Fortsetzung des Artikels von Teil 1

Einfach drauflostesten

Die Eigenschaft der Interpretierung ist für den Einsatz in CI entscheidend und hebt MicroPython gegenüber der Implementierung in C hervor. Eine durch den Build-Server durchgeführte Kompilation und Laden einer in C geschriebenen Testfunktion ist hochgradig abhängig von der Ziel-Hardware. Durch den Einsatz von MicroPython entfällt das Kompilieren und Laden der Test-Software komplett (Bild 1). Die Testbeschreibung kann als String über die serielle Schnittstelle an die Testgeräte geschickt werden und wird auf dem Testgerät selbst interpretiert. Dadurch sind die Testfunktionen dem Testgerät bekannt und können beliebig über die gleiche Schnittstelle ausgeführt werden. Der Build-Server muss also selbst keinerlei Kenntnisse über die angeschlossenen Testgeräte haben. Das zeitaufwendige Einrichten von Toolchains auf dem Build-Server wird eingespart und gleichzeitig ein hohes Maß an Flexibilität gewonnen. Dabei entsteht jedoch keine Veränderung des Gesamtprozesses. Die Testbeschreibung wird wie bisher in der Codebasis abgelegt und bei Erkennen einer Änderung in der Anwendung der Test automatisiert initiiert.

Die Abstraktion und die daraus entstehenden Vorteile sind jedoch nicht nur an der Schnittstelle zwischen dem Build-Server und den Testgeräten von Bedeutung. Auch die Implementierung der Tests durch den (Test-)Entwickler wird vereinfacht. Das Entwickeln und Anpassen einer in C geschriebenen Testfunktion setzt umfassende Kenntnisse der darunterliegenden Hardware voraus. Der Testentwickler muss die verwendeten Treiber, die angebotenen Schnittstellen und den vorhandenen Board-Support kennen und bedienen können. Durch die Entstehung der Abhängigkeit zwischen Testentwickler und Testgerät geht somit Flexibilität verloren.
Bei der Verwendung von MicroPython ist der Mikrocontroller und damit das zu bedienende Testgerät durch einen Hardware Abstraction Layer (HAL), den Python-Interpreter und die verschiedenen (Micro-)Python-Bibliotheken vom Anwendungscode getrennt. Die Abstraktion hat als Folge, dass aus Sicht des Testentwicklers der Mikrocontroller in erster Linie unsichtbar bleibt und somit kein umfassendes Wissen darüber notwendig ist. Es müssen neben Kenntnissen in Python lediglich die vorhandenen Bibliotheken und damit die vorhandenen Schnittstellen bekannt sein, um das Testgerät steuern zu können. Aufgrund der Hardware-Abstraktion erhöht sich außerdem die Wiederverwendbarkeit der Tests.

Bei Continuous Integration ermöglicht die Steuerung der Testgeräte durch Python und gleichzeitig deren Verbreitung die vollständige Aufhebung der bisherigen Trennung zwischen den Testfunktionen einerseits, die bis dato typischerweise in C geschrieben wurden, und den eigentlichen Testroutinen andererseits, die in Python vorliegen. Durch die vorhandenen Python-Bibliotheken wie math, entsteht bei gleichzeitiger Benutzung von Schnittstellen wie UART, SPI, I2C und USB in wenigen Zeilen Quellcode eine zentrale Testbeschreibung, die von komplexen Berechnungsvorschriften bis zur Low-Level-Schnittstelle und Interrupts alles Notwendige enthält.

passend zum Thema

Test-Performance steuerbar

Eine zentrale Frage und berechtigter Zweifel: Hat MicroPython bei dem angebotenen Komfort und daraus entstehenden Gewinn an Flexibilität, Portierbarkeit und Entwicklungsgeschwindigkeit Einbußen in der Performance und Echtzeitfähigkeit?

Es handelt sich um interpretierten Quellcode, der naturgemäß nicht mit der Performance eines bereits kompilierten, sich im Speicher befindlichen Binärcodes mithalten kann. Dies fällt jedoch für Testgeräte weniger stark ins Gewicht. Notwendige Testdaten werden nicht aufwendig berechnet, sondern werden meist durch statische Testdaten abstrahiert. Außerdem kann Performance durch leistungsfähigere Hardware erzielt werden, was aufgrund der geringen Anzahl an benötigten Testgeräten nicht kostenkritisch ist. Sollte sich das Testgerät im Einzelfall dennoch als zu langsam herausstellen, bietet MicroPython Stellschrauben in Form von Emittern an. Diese Emitter können direkt im Quellcode für jede Funktion angegeben werden und erlauben die Steuerung der Interpretation und Ausführung.

Als Grundeinstellung wird der Emitter Byte Code verwendet. Er übersetzt den Python-Quellcode in entsprechenden Byte Code und bedient damit die darunterliegende Virtual Machine. Bei Auswahl des Emitters Native wird der Byte Code weiter in Maschinencode übersetzt und direkt die C-Runtime-Funktionen im HAL aufgerufen. Im Vergleich zu Byte Code wird auf Kosten von Speicherplatz Ausführungsgeschwindigkeit gewonnen. Der Emitter Viper agiert ähnlich wie Native, allerdings mit dem Unterschied, dass er den Maschinencode weiter auf Geschwindigkeit optimiert und native Datentypen verwendet. Dadurch wird die Ausführungsgeschwindigkeit nochmals erhöht. Jedoch wird dabei nicht der komplette Sprachumfang unterstützt.

 Interrupt-Latenz

SPI-Latenz

GPIO-
Latenz

FreeRTOS 0,6 µs 48,0 µs 0,5 µs
MicroPython 9,0 µs 87,0 µs 10,0 µs

 

Tabelle 2: Performance von MicroPython imVergleich zu FreeRTOS (Hardware-Umgebung: STM32F4 Discovery, 32-bit ARM Cortex-M4, 168MHz).


Im Vergleich zur Performance nehmen die Reaktionszeiten von Schnittstellen eine höhere Priorität in der Testanwendung ein. Sie definieren die Grenzen der Kommunikationsgeschwindigkeit und damit gleichzeitig die Grenzen der Echtzeitfähigkeit des Testgerätes. Für den praktischen Vergleich wurden mit einem Benchmark Messreihen von verschiedenen Reaktionszeiten aufgenommen, ausgewertet und gegen die Ergebnisse einer Implementierung mit FreeRTOS verglichen (Tabelle 2). Die Messungen basieren auf identischen Hardware-Umgebungen, um den Einfluss von Hardware-Abhängigkeiten auf die Messergebnisse ausschließen zu können. Somit ist eine identische Umgebung geschaffen, die einen aussagekräftigen Vergleich zulässt.

Hohe Interrupt-Latenz

Es zeichnet sich klar ab, dass MicroPython im Vergleich zu FreeRTOS zeitliche Nachteile mit sich bringt. Insbesondere konnte eine vergleichbar hohe Interrupt-Latenz festgestellt werden. Diese Einschränkung darf nicht außer Acht gelassen werden und muss je nach Anwendung geprüft werden. Peripherie-Schnittstellen wie SPI können allerdings zufriedenstellend bedient werden.
Weiterhin muss berücksichtigt werden, dass MicroPython eine dynamische Speicherverwaltung verwendet, die Garbage Collection erforderlich macht. Sie wird benötigt, um vorher genutzten Speicher während der Laufzeit freizugeben. Die Garbage Collection kann jederzeit auftreten, wobei die CPU für mehrere Millisekunden blockiert wird. Für zeitkritische Anwendungen wäre das Blockieren fatal, da sich das System nicht mehr deterministisch verhält. Es ist jedoch grundsätzlich möglich, die Garbage Collection proaktiv zwischen den einzelnen Tests aufzurufen. Dadurch ist gewährleistet, dass das System in einen definierten Zustand zurückgesetzt wird und ein deterministisches Verhalten garantiert.

MicroPython unterstützt aktuell allerdings nur bedingt Nebenläufigkeit. Sollen eine Vielzahl von Schnittstellen gleichzeitig bedient werden können, empfiehlt sich der Einsatz mehrerer Testgeräte.

Viele Einsatzbereiche

Während die Leistung sicherlich nicht ausreicht, um komplexe Bussysteme mit harten Echtzeitanforderungen zu emulieren, so sind einfachere Peripherals wie z.B. I2C/SPI-Slaves schnell implementiert. Dies hilft bei der Einhaltung funktionaler Systemschnittstellen. Ebenso eignet sich MicroPython auch für statische Messungen, abhängig von der Präzision der darunterliegenden Hardware.

Obwohl MicroPython noch jung ist und Open Source entwickelt wird, kann das Framework mit mehr als 18.000 Unit-Tests als wohlgetestete Software angesehen werden. Aufgrund der MIT-Lizenz ist MicroPython problemlos kommerziell einsetzbar. Eine aktive Community trägt außerdem dazu bei, dass MicroPython auf einer steigenden Anzahl von Plattformen unterstützt wird. Schon heute läuft MicroPython auf Hardware, die ohne weiteres für Testgeräte geeignet wäre.

Die Erleichterung des Entwicklungsalltags beschränkt sich jedoch nicht nur auf dem Einsatz in der Continuous Integration. Sicher kennt jeder Entwickler die Not, eine Hauptkomponente entwickeln zu müssen, deren Gegenstelle zur Kommunikation aber noch fehlt. Mit MicroPython kann sich ein Entwickler in diesem Fall mit wenigen Zeilen Python-Code Abhilfe verschaffen.

Ein Tester, der versucht, das System zu penetrieren, will dabei gezielt bestimmte Konstellationen prüfen. Genauso wie der Build-Server oder der Entwickler kann der Tester bestehende Tests schnell abändern und beliebig verketten. Auch er muss dazu nur den Code auf seinem PC abändern, an das Testgerät schicken und die Tests starten.

Die leichte Bedienbarkeit bei gleichzeitiger Unabhängigkeit von speziellen Software Tools und Hardware macht Micropython für Entwickler und Tester zu einem starken und flexiblen Werkzeug, um schnell und komfortabel Testroutinen entwickeln und auf Anpassungen der Testfunktionalität reagieren zu können

 

Die Autoren

 

Hans-Christian-Wil von Mixed Mode
Hans-Christian-Wil von Mixed Mode.
© Mixed Mode

Hans-Christian Wild

ist ebenfalls Embedded Software Engineer bei Mixed Mode. Er setzt Continuous Integration in seinen Embedded-Projekten ein und ist immer auf der Suche nach neuen Werkzeugen, um die Integration von Embedded-Geräten zu erleichtern. Seinen Abschluss erhielt Hans-Christian 2013 von der Technischen Universität München.

 

Michael-Dümig von Mixed-Mode
Michael-Dümig von Mixed-Mode.
© Mixed Mode

Michael Dümig

ist Embedded Software Engineer bei Mixed Mode in Gräfelfing. Zuvor absolvierte er ein Masterstudium im Studiengang „Elektronische und Mechatronische Systeme“ an der Technischen Hochschule Nürnberg. Der Fokus seiner Master-Thesis lag im Untersuchen und Benchmarken des MicroPython-Frameworks.

 


  1. Schneller Testen mit MicroPython
  2. Einfach drauflostesten

Lesen Sie mehr zum Thema


Das könnte Sie auch interessieren

Jetzt kostenfreie Newsletter bestellen!

Weitere Artikel zu Mixed Mode GmbH

Weitere Artikel zu Industrie-Computer / Embedded PC