Dipl. Phys. Helmut Weber





Achtung:

Alle Beiträge sind Copyright (C) 2018 Dipl. Phys. Helmut Weber

Jedes Kopieren - egal, in welcher Form - bedarf der schriftlichen Erlaubnis.



Beispiel 2



Echtzeit – auf die Spitze getriebem


Einer der neuesten Microcontroller ist der ESP32 von Espressif. Er verfügt über 2 Kerne und in der Firmware über freeRTOS. Für einen Endpreis von ca. 5€.

Mit einer Taktfrequenz von 240MHz ist er einer der leistungsfähigsten Microcontroller überhaupt.

Damit eröffnen sich bisher ungeahnte Möglichkeiten.


Um das zu demonstrieren, habe ich ein „Template-Programm“ für zukünftige Entwicklungen erstellt, das diese Fähigkeiten demonstriert:


Core 0

In Core 0 läuft ein vollständiger Webserver, der sich automatisch in bestehende WLANs integriert.

Er kann per Browser Ergebnisse darstellen und der ESP32 kann über Eingaben gesteuert werden.

Bild im Browser:


Bild4

Der Web-Server kann natürlich auch per Handy benutzt werden oder ggf. über das Internet erreichbar sein.

Eine APP ist nicht erforderlich!

Eine Reihe verschiedener Web-Seiten kann detailierte Ausgaben bzw. Steuerungen ermöglichen.

Ein-/Ausgaben an einen MQTT-Broker oder in die (firmeneigene) Cloud wären genauso möglich.


Core 0 übernimmt auch den Input über eine serielle Leitung von einem einem Benutzer oder einem übergeordneten Rechner, die über den Command-Prozessor ebenfalls beliebige Steuerungen des Systems ermöglichen.


Kommandos über die serielle Schnittstelle erlauben die Steuerung des Systems. In diesem Beispiel kann die LED mit den Befehlen „on“ und „off“ gesteuert werden.

FirstTask gestoppt und wieder gestartet werden.

Die serielle Steuerung erlaubt damit auch GUI-Programmen auf externen Rechner die sehr schnelle Steuerung. Langsamere Vorgänge können über das WLAN gesteuert werden.


Core 0 läuft unter freeRTOS

Struktur der Template- Applikation


Echtzeit mit RTOS, CoopOS, Interrupts:


 Bild5


Core 1­


Core 1 ist für alle zeitkritischen Aufgaben zuständig.


1. Interrupts

Interrupts unterbrechen sofort alle laufenden Programme. Sie können durch Signale von außen oder typischer Weise auch von internen Timern ausgelöst werden.


Während im Core 0 das RTOS von einem Timer gesteuert wird, der alle 1000µs einen Taskswitch auslöst, läuft in Core 1 ein Task zur Echtzeitsteuerung per IRQ..

Der ermöglicht auf die Mikrosekunde genaue Messungen oder Ausgaben.

Weiterhin kann er Signale an den CoopOS-Scheduler (s.u.) senden, der Tasks entsprechend startet.


Im Beispiel feuert ein Timer alle 25µs, also mit einer Frequenz von 40kHz.


2. CoopOS

Ausserdem läuft in Core 1 der CoopOS-Scheduler.

CoopOS ist mit einem RTOS durchaus vergleichbar: Signale, Delays, Prioritäten usw.

Allerdings wird der Scheduler nicht per Timer-Interrupt aufgerufen (obwohl auch das möglich ist),

sondern jeder Task gibt innerhalb seines Ablaufs freiwillig (kooperativ) die Rechenzeit an den Scheduler wieder ab.

Die wesentlichste – oft bemängelte – Randbedingung ist, dass das auch in jedem Fall schnell genug passiert und es liegt in der Aufgabe des Programmierers, dies zu garantieren.

Aber diese Methode hat auch wesentliche Vorteile:

Wesentlich schnellere Taskwechsel. Es gibt keine Stack-Umschaltungen mit den bekannten Problemen: Zeitaufwändig, Platzbedarf, Probleme wenn die Stackgröße eines Tasks falsch eingeschätzt wurde usw.

Hier wird der Scheduler von CoopOS im Mittel alle 9 µs aufgerufen, das heißt:


Mehr als 100000 Scheduler-Calls pro Sekunde.

(statt 1000 bei RTOS = Faktor 100!)


Wichtig ist in diesem Zusammenhang auch, wie lange es maximal dauert, bis der Scheduler einen Task aufruft, der von einem Interrupt ein Signal bekommen hat.


In dem Beispielprogramm dauert es


7-20 µs , bis ein zu einem Interrupt-Signal gehörendes Programm vom CoopOS-Scheduler gestartet wird – im Mittel nach 10-12µs


Um diese Größenordnung zu veranschaulichen: eine Luftgewehrkugel mit V0=166m/s fliegt in 10 µs 1,6 mm.

Geeignete Präzision vorrausgesetzt könnte ein durch einen vom Abschuss von Gewehr 1 ausgelöster Interrupt ein Signal setzen und über den CoopOS-Scheduler einen Task starten, der die von Gewehr 1 abgegebene Kugel von einem quer angebrachten Gewehr 2 abgeschießt. Nicht durch entsprechende Funktionen im Interrupt-Handler, sondern durch Start eines passenden Tasks durch den CoopOS Scheduler, während alle sonstigen Funktionen des Systems ungestört weiterlaufen.

Ein Task „Output“ ist zuständig für die Ausgabe von Daten auf der seriellen Schnittstelle. Durch Zwischenpufferung wird dafür gesorgt, dass Zeichen entsprechend der Geschwindigkeit von 115200 Baud (ca. 10000 Zeichen/s) alle 100 µs ausgegeben werden und so keine Wartezeiten bei der Ausgabe entstehen.

Für weitere Tasks gilt: Ein Delay wird nicht in Ticks vom RTOS angegeben, sonder in Mikrosekunden. Dies bedeutet – ohne jede Interrupt-Steuerung! -, dass Tasks bis auf wenige Mikrosekunden genau gestartet werden:


2097755052 First Task 4182 Loops, diff=500010, offs=133

2097755052 Scheduler Calls/s 106706 9.371544 µs per call

2098255041 First Task 4183 Loops, diff=499989, offs=134

2098255041 Scheduler Calls/s 107024 9.343699 µs per call

2098337114 ThirdTask 999990 µs DeltaTime min:999985 max:1000117

2098496163 Second Task 100000 Loops - Duration[µs] for 100.000: 947914 µs, Average (µs) 9

2098755043 First Task 4184 Loops, diff=500002, offs=133

2098755043 Scheduler Calls/s 106720 9.370315 µs per call

2099255039 First Task 4185 Loops, diff=499996, offs=134

2099255039 Scheduler Calls/s 107036 9.342651 µs per call

2099337159 ThirdTask 999994 µs DeltaTime min:999985 max:1000117

2099444050 Second Task 100000 Loops - Duration[µs] for 100.000: 947842 µs, Average (µs) 9

2099755047 First Task 4186 Loops, diff=500008, offs=133


Für Tasks 1 wurde ein Delay von 500000µs (-Offset) vorgegeben. Der Offset wird von FirstTask selbst optimiert.


Task1 wird vom Scheduler – völlig unabhängig von Timer-Interrupts - auf wenige µs genau deterministisch gestartet.



Zusammenfassung:

Störungsfreie Ein-/ Ausgabe per WLAN-Web-Server

Störungsfreie Ein-/ Ausgabe per serieller Schnittstelle

40000 Interrupts/s

100000 Scheduler-Calls / s

7-20 µs Latenz vom IRQ-Signal bis zum passenden Taskaufruf durch Scheduler

Auf wenige µs genaue Task-Starts

Auf wenige µs genaue Synchronisation von Tasks