MicroPython: Parallele Verarbeitung

Ein Mikrocontroller verarbeitet den Programmcode Zeile für Zeile nacheinander ab. Abweichungen in der Reihenfolge ergeben sich nur bei Verzweigungen, Wiederholungen durch Schleifen und Sprünge beim Aufrufen von Funktionen.
Dabei ist es grundsätzlich nicht vorgesehen, dass die Recheneinheit im Mikrocontroller Programmcode parallel verarbeitet oder ausführt. Selbst in modernen Prozessoren ist die parallele Verarbeitung nur teilweise oder begrenzt möglich.

Grundlagen zur parallelen Verarbeitung

Der Benutzer eines modernen Computers geht davon aus, dass er auf seinem Computer mehrere Programme gleichzeitig ausführen kann. Tatsächlich ist es oft so, dass bei der normalen Nutzung selten eine parallele Verarbeitung stattfindet. Der Grund ist, dass die Rechenleistung so groß ist und die Verwaltung und Zuteilung der Rechenleistung durch das Betriebssystem so geschickt erfolgt, dass sich der Eindruck einer parallelen Verarbeitung aufdrängt.

Dank der hohen Verarbeitungsgeschwindigkeit der Hardware und der zeitlichen Verschachtelung der Verarbeitung von unabhängigen Programmcodes eine Quasiparallelität erreichen.
Tatsächlich ist echte Parallelität nur dann gegeben, wenn es mehrere parallelverarbeitende Recheneinheiten gibt und diese auch gleichzeitig genutzt werden.

  • Multi-Threading
  • Multi-Core
  • Multi-CPU

Der Zugriff auf die parallelverarbeitenden Recheneinheiten müssen softwareseitig möglich sein. Moderne Betriebssysteme bringen das mit und kümmern sich auch um die Verwaltung und ggf. Verteilung des Programmcodes.

Bei Mikrocontrollern muss man berücksichtigen, dass es in der Regel kein Betriebssystem gibt, dass dem Programmierer mit einem vollwertigen Prozessmodell lästige Aufgaben abnehmen kann. Hier erfolgt die Programmierung so nah an der Hardware, dass sich der Programmierer über die Art und Weise der parallelen Verarbeitung selber Gedanken machen muss. Eventuell kann er auf fertige Konzepte oder Best Practices zurückgreifen. Programmieren muss er nach diesen Gesichtspunkten seinen Programmcode dann doch noch selber.

Ein Hauptproblem bei der parallelen Verarbeitung ist die Abhängigkeit von Programmteilen oder Funktionen. Dazu gehört auch der Zugriff auf gemeinsame Zustände, Werte und Speicherinhalte. Nicht alle parallelen Verarbeitungskonzepte ermöglichen einfach so den Zugriff auf globale Variablen. Als Programmierer muss man dann auch noch den parallelen und somit kollisionsfreien Zugriff auf den Speicher im Auge behalten.

MicroPython: Parallele Verarbeitung und Ausführung von Programmcode

MicroPython ist eine spezielle Python-Version für Mikrocontroller. Wie Python ermöglicht auch MicroPython die parallele Verarbeitung von mehreren Programmteilen. Das heißt, es gibt ein Hauptprogramm und nebenbei kann der Mikrocontroller noch andere Dinge tun.
Was nicht geht ist, dass man zwei eigenständige Programmcodes startet. Das wäre nur mit einem Betriebssystem mit Prozessmodell möglich. MicroPython ist aber nur ein Interpreter für einen auszuführenden Programmcode.
Möchte man mehrere Programmcodes ausführen, dann muss man diese Programmcodes in einen Programmcode zusammenführen und ein dazu passendes Konzept für die parallele Verarbeitung wählen.

  • MicroPython-Modul „uasyncio“
  • MicroPython-Modul „_thread“
  • PIO-State-Machines

MicroPython-Modul „uasyncio“

Das Asyncio-Konzept ist kooperatives Multitasking. Diese Technik ist in eingebetteten Systemen und Mikrocontrollern weit verbreitet. Es ermöglicht Multitasking auf einem vergleichsweise niedrigem Niveau. Der Anwendungsentwickler muss auf einem Mikrocontroller, wie zum Beispiel dem Raspberry Pi Pico, gewisse konzeptionelle Vorbereitungen treffen, damit sein Programmcode quasi parallel arbeiten kann. Das heißt, dass hier nichts parallel, sondern immer noch streng nacheinander ausgeführt wird. Das Asyncio-Konzept sieht vor, dass der Programmierer innerhalb des Programmcodes Warte-Kommandos setzt, in deren Zeit ein anderer Programmteil ausgeführt werden kann, wodurch der Eindruck einer parallelen Verarbeitung entsteht.

  • MicroPython: uasyncio / async

MicroPython-Modul „_thread“

Das MicroPython-Modul „_thread“ basiert auf simultanem Multithreading, bei dem mehrere Rechenkerne mit unabhängigen Rechenaufgaben beauftragt werden.
Eine Idee könnte sein, dass ein nebenläufiger Programmcode das Hauptprogramm nicht unterbrechen soll und dessen Ausführung im Mikrocontroller auf einen zweiten Rechenkern ausgelagert wird. Dafür muss mindestens ein zweiter Rechenkern vorhanden sein.
Die Nutzung eines weiteren Rechenkerns ist mit Unterstützung des MicroPython-Moduls „_thread“ möglich. Allerdings gilt das MicroPython-Modul als fehlerhaft. Der produktive Einsatz ist also nur begrenzt möglich.

  • MicroPython: _thread

PIO-State-Machines

Programmable Input Output, kurz PIO, ist im Prinzip eine Assembler-Programmiersprache auf der niedrigsten Hardware-Ebene. Wenn man von PIO spricht, dann meint man damit integrierte State Machines oder Zustandsmaschinen an den GPIOs eines Mikrocontrollers. Das ist im Prinzip ein Steuerungskonzept in dem Zustände, der Übergang zwischen den Zuständen und Abhängigkeiten bestimmter Aktionen definiert sind. Das kann man natürlich auch mit C/C++ oder MicroPython programmieren. Allerdings ist eine mit PIO geschriebene State Machine viel effizienter und schneller. Ein weiterer Vorteil ist die parallele Ausführung unabhängig vom Hauptprogramm.

Alternativen zur parallelen Ausführung von Programmcode

Neben den üblichen Verdächtigen „uasyncio“ und „_thread“, die beide ihre Vor- und Nachteile haben, lohnt sich ein Blick auf alternative Lösungen, die nur eine indirekte parallele Verarbeitung ermöglichen, sich aber einfacher realisieren lassen.
Wenn es um zeitabhängiges Ausführen von Funktionen geht, dann sollte man sich die Timer-Lösung ansehen.
Wenn es darum geht, dass eine Funktion auf eine Zustandsänderung eines GPIOs oder Sensors reagiert, dann kommt vielleicht die Interrupt-Lösung in Frage.

  • MicroPython: Timer
  • MicroPython: Interrupt

MicroPython: Timer

Ein Timer ist eine logische Instanz für einen Zeitgeber, der einen Befehl oder eine Funktion zeitabhängig ausführen kann. Einmalig oder periodisch wiederholend mit Angabe einer Frequenz in Hertz (Anzahl in der Sekunde) oder einer ablaufenden Zeit in Millisekunden.
Wenn in einem Programmcode etwas laufend wiederholt werden soll, dann löst man das in der Regel mit einer Endlos-Schleife. Das ist oft eine gute Lösung. Wenn aber mehrere Funktionen unabhängig voneinander ausgeführt werden sollen, dann funktioniert das in einer Schleife nicht so gut.
Wenn man also eigentlich eine zweite Endlos-Schleife braucht, dann wäre ein Timer die Lösung. Mit einem Timer kann man eine beliebige Funktion zeitgesteuert aufrufen. Das ist vergleichbar mit einer Endlos-Schleife.
Eine echte parallele Verarbeitung ist das natürlich nicht, weil der Timer-Aufruf den laufenden Programmcode unterbricht. Aber es fühlt sich ein bisschen wie eine parallele Verarbeitung an.

MicroPython: Interrupt

Jedes Computersystem, dazu gehören auch Mikrocontroller wie der Raspberry Pi Pico, besteht aus einer Recheneinheit, die den Programmcode nacheinander ausführt. Gelegentlich kommt es innerhalb des Systems zu Ereignissen, bei denen der geplante Programmablauf unterbrochen und an einer anderen Stelle weitergemacht werden muss.
Mit Hilfe von Interrupts kann der Mikrocontroller auf definierte Weise den laufenden Programmcode unterbrechen und an einer definierten Stelle im Programmcode weitermachen.
Auch hier findet keine parallele Verarbeitung statt. Allerdings kann man im Programmcode auf äußere Zustandsänderungen unabhängig vom laufenden Programmcode reagieren.

Weitere verwandte Themen:

  • ...

Teilen:

Hardware-nahes Programmieren mit dem Raspberry Pi Pico und MicroPython

Elektronik-Set Pico Edition

Das Elektronik-Set Pico Edition ist ein Bauteile-Sortiment mit Anleitung zum Experimentieren und Programmieren mit MicroPython.

  • LED: Einschalten, ausschalten, blinken und Helligkeit steuern
  • Taster: Entprellen und Zustände anzeigen
  • LED mit Taster einschalten und ausschalten
  • Ampel- und Lauflicht-Steuerung
  • Elektronischer Würfel
  • Eigene Steuerungen programmieren

Elektronik-Set jetzt bestellen Online-Workshop buchen

Programmieren mit dem Raspberry Pi Pico
Online-Workshop

Hardware-nahes Programmieren mit dem Raspberry Pi Pico

Gemeinsam mit anderen und unter Anleitung experimentieren? Wir bieten unterschiedliche Online-Workshops zum Raspberry Pi Pico und MicroPython an. Einführung in die Programmierung, Sensoren programmieren und kalibrieren, sowie Internet of Things und Smart Home über WLAN und MQTT.

Online-Workshop buchen

Für Ihre Fragen zu unseren Online-Workshops mit dem Raspberry Pi Pico besuchen Sie unseren PicoTalk (Online-Meeting). (Headset empfohlen)

Zum PicoTalk

 

Elektronik-Set Pico Edition
Elektronik-Set Pico Edition

Raspberry Pi Pico: Hardware-nahes Programmieren mit MicroPython

Leichter Einstieg mit All-in-one-Set zum sofort Loslegen, um eigene Steuerungen programmieren.

Elektronik-Set jetzt bestellen

 

Elektronik-Set Pico WLAN Edition
Elektronik-Set Pico WLAN Edition

Raspberry Pi Pico W: IoT und Smart Home mit WLAN und MQTT

Betreibe Deinen Raspberry Pi Pico W als drahtloser Sensor in Deinem WLAN, versende E-Mails mit Daten und kommuniziere per MQTT im Internet of Things oder Smart Home.

Elektronik-Set jetzt bestellen

 

Elektronik-Set Sensor Edition
Elektronik-Set Sensor Edition

Erweiterung zu den Elektronik-Sets Pico Edition und Pico WLAN Edition

Elektronik-Set mit den beliebtesten Sensoren zum Messen von Temperatur, Helligkeit, Bewegung, Lautstärke und Entfernung.

Elektronik-Set jetzt bestellen