Heterogene Multiprozessorsysteme Umsetzung von Asymmetric Multiprocessing mit OpenAMP

Von David Kauschke*

Heterogene Multiprozessorsysteme bieten einige praktische technische Vorteile, stellen aber besondere Herausforderungen an den Software-Entwickler, wenn es um Kommunikation, Taskverteilung und Lifecycle-Management geht. Das Framework OpenAMP kann bei der Umsetzung helfen, wie dieser Beitrag am praktischen Beispiel auf einem i.MX8 zeigt.

Anbieter zum Thema

Asymmetrisches Multiprocessing auf heterogenen MPSoCs stellt Entwickler von echtzeitkritischen Anwendungen oft vor gewaltige Herausvorderungen.
Asymmetrisches Multiprocessing auf heterogenen MPSoCs stellt Entwickler von echtzeitkritischen Anwendungen oft vor gewaltige Herausvorderungen.
(Bild: Clipdealer)

Heterogene Multiprozessorsysteme (MPSoC) sind in den letzten Jahren immer beliebter für industrielle Anwendungen aufgrund der hohen Performance, den niedrigeren Kosten und der Energieeffienz geworden. Besonders die vielfältigen unterschiedlichen integrierten Prozessoren, auf denen unterschiedliche Betriebssysteme laufen, auch als Asymmetric Multiprocessing (AMP) bezeichnet, bringen viele Herausforderungen mit sich. Die zwei größten Herausforderungen sind das Lifecycle-Management (LCM) und die Interprozessorkommunikation (IPC). Dieser Beitrag stellt den Aufbau von heterogenen MPSoCs mit dem Einsatz von unterschiedlichen Betriebssystemen vor.

Für die beiden Herausforderungen wird das Framework OpenAMP vorgestellt. Dieses Framework wurde auf den MPSoC i.MX8X von NXP mit einem Embedded Linux auf dem ARM Cortex-A35 und einem FreeRTOS auf dem ARM Cortex-M4 portiert. Zur Evaluierung des umgesetzten Systems werden auf dem i.MX8X die Latenzzeiten gemessen. Die Ergebnisse zeigen unter anderem, dass die maximale Latenzzeit vom Linux-Userspace zum FreeRTOS mit dem Einsatz vom RT-Patch bei 628 µs liegt. Aus den Ergebnissen lässt sich ableiten, dass die IPC zwischen den Prozessoren für weiche Echtzeit geeignet ist.

Heterogene MPSoCs bestehen aus mehreren Prozessoren mit unterschiedlichen Befehlssatzarchitekturen, die für gezielte Anwendungen wie aufwendige Grafikanwendungen oder echtzeitkritische Anwendungen geeignet sind. Durch die Aufteilung der Aufgaben auf verschiedene Prozessoren wird eine höhere Bandbreite von Anforderungen abgedeckt wie ein Trade-Off zwischen Energieeffizienz und Performance, Systemsicherheit, Reduzierung der Stückliste oder die Reduzierung von EMV-Störungen [1-3].

Mehrere laufende Betriebssysteme auf heterogenen MPSoCs

Auf heterogenen MPSoCs können Betriebssysteme in Kombination eingesetzt werden. Sie werden unterteilt in Symmetric Multiprocessing (SMP) und Asymmetric Multiprocessing (AMP).

Symmetric Multiprocessing (SMP): Bei SMP wird genau ein Betriebssystem auf allen vorhandenen Cores eines Prozessors ausgeführt. Alle Cores unterliegen der gleichen Prozessorarchitektur sowie der gleichen Instruction Set Architecture (ISA), teilen sich alle denselben Speicherbereich und teilweise die gleichen Cache-Level und haben gemeinsamen Zugriff auf I/O-Geräte. Das Betriebssystem verwaltet alle Ressourcen und verteilt die auszuführenden Prozesse auf die zur Verfügung stehenden Cores, die alle gleich behandelt werden.

Jeder Prozess kann auf einem beliebigen Core ohne jegliche Änderungen oder Einschränkungen ausgeführt werden. Wenn das Betriebssystem überlastet ist, sind alle auszuführenden Prozesse gleichermaßen davon betroffen, wodurch auf SMP-Systemen kein Determinismus erreicht werden kann. SMP-Systeme nutzen alle Cores der gegebenen Multicore-Architektur, um eine maximale Performance zu erreichen. In der Regel wird ein General Purpose Operating System (GPOS) wie Linux eingesetzt, das SMP-fähig ist [4].

Asymmetric Multiprocessing (AMP): Bei AMP läuft mehr als ein Betriebssystem auf einem oder auf mehreren Prozessoren mit unterschiedlicher ISA unabhängig voneinander. Genau hierfür wird der Einsatz von heterogenen MPSoCs interessant, da sie mehrere unterschiedliche Prozessoren für spezielle Aufgaben wie Multimedia, Echtzeit oder Bildverarbeitung bereitstellen. So kann auf der Application Processing Unit (APU) auf allen Cores Linux verwendet werden, während auf dem ARM Cortex-M4 ein Real Time Operating System (RTOS) läuft (Abb. 1). Alle Betriebssysteme teilen sich den öffentlich zugänglichen Speicher, aber haben zugleich in der Regel noch einen privaten Speicher.

Abb. 1: Aufbau eines möglichen AMP-Systems. Ein Linux verwaltet alle Cores der APU (grauer Bereich), in der ein ARM Cortex-A53 integriert ist. Ein RTOS läuft auf der RPU, in der ein ARM Cortex-M4 integriert ist (blauer Bereich).
Abb. 1: Aufbau eines möglichen AMP-Systems. Ein Linux verwaltet alle Cores der APU (grauer Bereich), in der ein ARM Cortex-A53 integriert ist. Ein RTOS läuft auf der RPU, in der ein ARM Cortex-M4 integriert ist (blauer Bereich).
(Bild: Mixed Mode)

Auch den Zugang auf die Ressourcen wie I/O-Geräte teilen sich alle Betriebssysteme. Durch Mechanismen wie IPC, Message-Passing und Shared-Memory, können die Betriebssysteme miteinander kommunizieren und Daten untereinander austauschen. Der Zugriff und die Synchronisation muss hierbei geregelt werden. In der Praxis werden SMP und AMP häufig miteinander auf einem MPSoC kombiniert, um den Energieverbrauch zu optimieren und eine bessere Performance zu erreichen [4].

Herausforderungen auf AMP-Systemen

Auf heterogenen MPSoCs führt die Verwendung von mehreren Betriebssystemen auf unterschiedlichen Prozessoren und der hierdurch entstehende Synchronisationsaufwand zu einer nicht zu unterschätzenden Komplexität. Die dadurch entstehenden Heraus-forderungen werden in den folgenden Abschnitten näher betrachtet.

Jetzt Newsletter abonnieren

Verpassen Sie nicht unsere besten Inhalte

Mit Klick auf „Newsletter abonnieren“ erkläre ich mich mit der Verarbeitung und Nutzung meiner Daten gemäß Einwilligungserklärung (bitte aufklappen für Details) einverstanden und akzeptiere die Nutzungsbedingungen. Weitere Informationen finde ich in unserer Datenschutzerklärung.

Aufklappen für Details zu Ihrer Einwilligung

Speichermanagement: Das Speichermanagement, also die Bereitstellung, Zuteilung und Trennung von Speicherbereichen für Subsysteme (APU, RPU) muss berücksichtigt werden. Es muss gewährleistet werden, dass die einzelnen Subsysteme keinen Zugriff auf die Speicher-bereiche von den anderen Subsystemen haben. Dies könnte ansonsten instabile Systemzustände verursachen oder im schlimmsten Fall das gesamte System zu Absturz bringen.

Ressourcenmanagement: Außerdem muss das Ressourcenmanagement geregelt werden, um zu definieren, welche Subsysteme auf welche Ressourcen Zugriff haben. Wenn beide Subsysteme gleichzeitig auf dasselbe IO-Gerät zugreifen, entsteht ein undefiniertes Verhalten.

Systembootmanagement: Durch die vielen Subsysteme auf heterogenen MPSoCs gibt es eine große Anzahl von Boot-Stages, die zu einer höheren Systemkomplexität führt. So muss geklärt werden, welches Subsystem die Bestromung und Konfiguration der notwendigen Subsysteme einschließlich der Clocks, übernimmt. Außerdem wird ein Boot-Image benötigt, das alle notwendigen Firmwares beinhaltet, um alle gewünschten Subsysteme beim Systemstart in der gewünschten Bootreihenfolge zu starten. In der Regel wird hierfür ein dediziertes Subsystem vom jeweiligen MPSoC bereitgestellt, welches die Verantwortung für die Extraktion des Boot-Images, das Laden der Firmwares und das Starten der Prozessoren übernimmt. Innerhalb der Subsysteme, wie zum Beispiel der APU, muss geklärt werden, welche Bootloader-Stages verwendet werden. Auch das Laden des Device-Tree oder Linux-Kernel muss durchgeführt werden. Weiterhin muss beim Systemboot sichergestellt werden, dass die parallellaufenden Bootprozesse der einzelnen Subsysteme sich nicht gegenseitig blockieren.

Lifecyclemanagement (LCM): Neben dem Systembootmanagement zur Systemstartzeit ist auch das LCM zur Laufzeit ein wichtiges Thema. Es ermöglicht sichere Updates zur Laufzeit auf einzelnen Subsystemen wie der RPU, ohne das gesamte System updaten zu müssen. Wichtig ist hierbei, dass unterschiedliche Firmwares auf die Subsysteme bzw. Coprozessoren geladen werden können, ohne andere Subsysteme durch diesen Prozess zu beeinflussen. So muss der Coprozessor zuerst gestoppt werden können, bevor er mit einer neuen Firmware erneut gestartet werden kann. Es muss definiert werden, welcher Prozessor der Master und welcher Prozessor die Rolle des Coprozessors übernimmt.

Interprozessorkommunikation (IPC): Sobald mehrere Prozessoren innerhalb eines MPSoCs laufen, ist eine IPC unausweichlich, um Daten zwischen ihnen auszutauschen. Dies geschieht in der Regel über Shared-Memory sowie Interprozessor-Interrupts (IPI). Über eine IPI kann ein Prozessor einen anderen Prozessor über neue Informationen im Shared-Memory benachrichtigen. Auf einem MPSoC werden dazu Messaging Units (MU) verwendet. Der eingesetzte IPI muss bei dem geteilten Interrupt-Controller, welcher als Hardware-komponente auf dem MPSoC integriert ist, registriert und freigeschalten werden.

Auswahl eines Frameworks für LCM und IPC

Abb. 2: Darstellung des OpenAMP-Frameworks auf Linux, RTOS und BareMetal. Die illustrierten Kästchen sind von oben nach unten in die Layer Applikation (hellgrau), Middleware und Betriebssysteme (blau) und Hardware (dunkelgrau) unterteilt. In der linken Hälfte ist der hierarchische Aufbau von OpenAMP auf einem RTOS/Bare-Metal illustriert. In der rechten Hälfte ist der Aufbau für Linux abgebildet (umgezeichnet nach [7]).
Abb. 2: Darstellung des OpenAMP-Frameworks auf Linux, RTOS und BareMetal. Die illustrierten Kästchen sind von oben nach unten in die Layer Applikation (hellgrau), Middleware und Betriebssysteme (blau) und Hardware (dunkelgrau) unterteilt. In der linken Hälfte ist der hierarchische Aufbau von OpenAMP auf einem RTOS/Bare-Metal illustriert. In der rechten Hälfte ist der Aufbau für Linux abgebildet (umgezeichnet nach [7]).
(Bild: Mixed Mode)

OpenAMP: Das Open Asymmetric Multi Processing (OpenAMP) Framework ist durch die Multicore Association standardisiert und wird durch viele Firmen (Xilinx, Mentor Graphics) unterstützt. Es bietet Funktionalitäten für das LCM und für die IPC auf AMP-Systemen an und ist auf unterschiedlichen Betriebssystemen wie Linux, RTOS oder auf Bare-Metal verwendbar. Auf der Linux-Seite werden die bereits existierenden Kernel-Komponenten Remote Processor Framework (RemoteProc) und Remote Processor Messaging (RPMsg) eingesetzt, die seit Version 3.4.x im Mainline-Kernel enthalten sind. RemoteProc übernimmt die Aufgaben des LCM und RPMsg ist für die IPC zuständig. Auf RTOS und Bare-Metal besteht das Framework aus einer hardware-abhängigen Portierungsebene (Libmetal), welche die notwendigen Hardware-schnittstellen und Betriebssystemumgebungen bereitstellt (Abb. 2) [5–7].

RPMsgLite: Der von NXP entwickelte RPMsgLite-Ansatz legt seinen Schwerpunkt auf die IPC und setzt dabei wie OpenAMP RPMsg ein. Das LCM wird mit diesem Ansatz nicht unterstützt. Die Besonderheit ist, dass die umfangreiche API von RPMsg vereinfacht wurde, um den benötigten Speicherplatz und die Komplexität zu reduzieren. So setzt RPMsglite seinen Schwerpunkt vor allem auf Prozessoren, die wenig Speicher integriert haben, wie den Cortex M0+.

Zusätzlich hat der Anwender die Möglichkeit, RPMsgLite als statische oder dynamische Bibliothek einzusetzen und einen Zero-Copy Mechanismus für das Kopieren der Daten zwischen Applikation und RPMsg-Device zu verwenden. Er minimiert die auftretenden Latenzzeiten für das Kopieren der Nachrichten. Der notwendige Flash-Speicher mit RPMsglite liegt beim Einsatz der statischen Bibliothek bei 2926 Bytes, der notwendige RAM-Speicher bei 352 Bytes. Im Vergleich benötigt OpenAMP 5547 Bytes im Flash und 456 Bytes im RAM, plus zusätzlicher Allokation im dynamischen Speicher [8].

RPMsgLite oder OpenAMP? RPMsgLite hat den Vorteil, dass es bereits auf dem eingesetzten MPSoC i.MX8X einsatzbereit ist und keinen erhöhten Implementierungsaufwand mit sich bringt. NXP bietet auf Linux bereits die notwendigen Komponenten an, um über RPMsg mit dem M4, der RPMsglite einsetzt, zu kommunizieren. Auf M4-Seite sind ebenso Demo-Applikationen zu finden, die den RPMsglite-Ansatz beinhalten. Der Nachteil dieser Lösung ist die bereits oben erwähnte fehlende Komponente für das LCM. Außerdem fehlen Funktionalitäten für die Bereitstellung einer Proxy-Infrastruktur. Aus diesen Gründen wird OpenAMP eingesetzt.

Evaluierung von Latenzzeiten

Nach dem OpenAMP auf den i.MX8X portiert wurde [9], erfolgt als Nächstes die Beschreibung des Systemüberblicks für das Messsystem mit dem die Latenzzeiten auf dem i.MX8X zwischen den Prozessoren Cortex-A35 und Cortex-M4 gemessen wurden.

Systemüberblick Messsystem: Die durchgeführten Versuche beziehen sich auf die im Systemüberblick dargestellten Messabschnitte 1-4 (Abb. 3):

  • IPI-Latenzzeit vom A35 (i.MX RPMsg Platform Driver) zur aufgerufenen ISR im M4 (Messabschnitt 3 bis 4).
  • IPI-Latenzzeit vom M4 zum A35 (i.MX RPMsg Platform Driver) zur aufgerufenen ISR (Messabschnitt 4 bis 3).
  • Latenzzeit von der MeasureMan-Anwendung im Userspace bis zum Auslösen des IPI 3 i.MX RPMsg Platform Driver über die TTY-Write Schnittstelle (Messabschnitt 1 bis 3).
  • Latenzzeit vom i.MX RPMsg Platform Driver bis zur MeasureMan-Anwendung über die TTY-Read Schnittstelle (Messabschnitt 3 bis 1). Besonders wichtig ist hierbei zu erwähnen, dass bei dieser Messung die M4-Verarbeitungszeit und die IPI-Latenzzeit beinhaltet sind.

Die durch den OpenAMP verursachte Verarbeitungszeit auf dem M4 (Messabschnitt 4)

Abb. 3: Systemüberblick zu den durchzuführenden Versuchen, welcher für die Versuche die betroffenen Komponenten darstellt. Er unterteilt sich in vier Kompo-nenten, wovon der MeasureMan, der i.MX RPMsg TTY Driver und der i.MX RPMsg Platform Driver auf dem A35 laufen und die M4 Applikation auf dem M4 (grau). Beide Prozessoren kommunizieren über die zwei IPIs 2 und 3 miteinander (grün). Die grünen Pfeile stellen die Kommunikationsrichtung vom Linux, die sich in die Bereiche User- und Kernelspace (orange) unterteilen, bis zum FreeRTOS auf dem M4 (blau) dar. Die blauen Pfeile stellen die entgegengesetzte Kommunikationsrichtung dar.
Abb. 3: Systemüberblick zu den durchzuführenden Versuchen, welcher für die Versuche die betroffenen Komponenten darstellt. Er unterteilt sich in vier Kompo-nenten, wovon der MeasureMan, der i.MX RPMsg TTY Driver und der i.MX RPMsg Platform Driver auf dem A35 laufen und die M4 Applikation auf dem M4 (grau). Beide Prozessoren kommunizieren über die zwei IPIs 2 und 3 miteinander (grün). Die grünen Pfeile stellen die Kommunikationsrichtung vom Linux, die sich in die Bereiche User- und Kernelspace (orange) unterteilen, bis zum FreeRTOS auf dem M4 (blau) dar. Die blauen Pfeile stellen die entgegengesetzte Kommunikationsrichtung dar.
(Bild: Mixed Mode)

Die Messmethodik und die Durchführung der einzelnen Versuche sind aus [9] zu entnehmen.

Zusammenfassung der Messergebnisse – Echtzeit möglich?

Tab. 1: Zusammenfassung der Messergebnisse für die auftretenden Latenz- und Verarbeitungszeiten bei einer Nachrichtengröße von 496 Bytes
Tab. 1: Zusammenfassung der Messergebnisse für die auftretenden Latenz- und Verarbeitungszeiten bei einer Nachrichtengröße von 496 Bytes
(Bild: Mixed Mode)

In Tabelle 1 sind die wichtigsten Ergebnisse mit einer Nachrichtengröße von 496 Bytes (maximale Nachrichtengröße einer RPMsg) und einer Stichprobenanzahl von 4.000.000 Messpunkte zusammengefasst. Die durchgeführten Versuche zeigen einen Überblick über die Latenzzeiten zwischen den beiden Prozessoren. Hierbei wurde der eingesetzte Kernel bereits mit dem RT-Patch erweitert, da ohne RT-Patch Ausreißer von bis zu 125.472 µs bei der TTY-Read Latenzzeit aufgetreten sind. Durch den Einsatz des RT-Patches konnten die maximalen Latenzzeiten für die TTY-Read Messung auf 55.291 µs reduziert werden.

Die Ursache für die hohen Ausreißer ist auf das nicht deterministische Linux-System zurückzuführen. Der Cortex-M4 kann hierfür ausgeschlossen werden, da dieser eine maximale Interrupt-Latenzzeit von 12 Taktzyklen garantiert.

Eine andere Ursache für den hohen Ausreißer kann möglicherweise auf ein Hardwareproblem, wie durch den vorhandenen Systembus des MPSoCs, zurückgeführt werden. Eine zusätzliche Ursache kann die Speicherausrichtung sein, wodurch für einen Datenzugriff mehrere Speicherzugriffe notwendig sein können und daher kein konstanter Zugriff auf Speicher garantiert werden.

Um die Ursache für die Ausreißer zu finden, bietet sich eine Analyse mit den Werkzeugen von TraceCompass oder Traceshark an.

Für den Einsatz von harter Echtzeit ist die IPC zwischen den Prozessoren über OpenAMP nicht geeignet. Der Einsatz für weiche Echtzeit ist hingegen plausibel, wenn die aufgezeigten Ausreißer tolerierbar sind (Tabelle 1).

Fazit und Ausblick

Der Einsatz von OpenAMP auf dem ausgewählten heterogenen MPSoC ist im Hinblick auf den hohen Implementierungsaufwand ein Nachteil, da das eingesetzte Embedded-Linux für den MPSoC i.MX8X keinen plattformabhängigen RemoteProc-Driver zur Verfügung stellt.

Außerdem führt die hohe Komplexität des MPSoCs i.MX8X zu einer hohen Einarbeitungszeit durch die vielen unterschiedlichen integrierten Subsysteme. So bringt die integrierte System Controller Unit hardwareabhängige Funktionalitäten für die Steuerung des Systemboot-, Speicher- und Ressourcen-Management mit, die auf Ressourcen und Partitionen aufbauen. Dadurch wird auch unabhängig vom eingesetzten MPSoC eine hohe Einarbeitungszeit gefordert, da jede Plattform ihre Besonderheiten bereitstellt und die Hersteller keinen gemeinsamen Ansatz verfolgen.

Bei der Portierung von OpenAMP auf dem ARM Cortex-M4 hat sich durch die Trennung des plattformabhängigen Teil durch die hardwareabhängige Portierungsebene innerhalb der Libmetal-Bibliothek als großen Vorteil erwiesen. Allerdings wurde in dieser Arbeit nur ein Anwendungsfall umgesetzt und das gesamte Potential von OpenAMP nicht ausgenutzt. Daher hätte der Einsatz von RPMsgLite für die Evaluierung der IPC ausgereicht. Doch wegen der fehlenden Funktionalitäten für das LCM wurde OpenAMP dennoch eingesetzt und nicht RPMsglite. Für Anwendungen für die ausschließlich eine IPC zwischen Prozessoren ohne LCM gefordert ist, ist RPMsgLite die bessere Wahl. Jedoch muss dabei beachtet werden, dass diese Lösung ausschließlich für die von NXP zur Verfügung gestellten MPSoCs eingesetzt werden kann.

Die Ergebnisse der Evaluierung von OpenAMP auf dem i.MX8X zeigen hohe Ausreißer bei den Latenzzeiten, für die ausschließlich Hypothesen für die Ursachen abgeleitet wurden. Die Ursachen wurden im Rahmen dieses Beitrages nicht näher betrachtet und nur noch Ansätze für die Untersuchung vorgeschlagen. Hierfür sollten weitere Untersuchungen durchgeführt werden.

Literatur- und Quellenverzeichnis

[1] Michael Hübner und Jürgen Becker. Multiprocessor System-on-Chip. Springer Science &Business Media, 2011.
[2] Mpsoc Technology u. a. “Multiprocessor System-on-Chip”. In: IEEE Transactions on Multi-Scale Computing Systems 27.10 (2008), S. 1701–1713.
[3] Alexandra Fedorova u. a. “Maximizing power efficiency with asymmetric multicore systems”. In: Communications of the ACM 52.12 (2009), S. 48–57.
[4] Bryon Moyer. Real World Multicore Embedded Systems. Newnes, 2013
[5] OpenAMP/open-amp. url: https://github.com/OpenAMP/open-amp
[6] Linux 3.4 - Linux Kernel Newbies. url: https://kernelnewbies.org/Linux_3.4
[7] Warren Kurisu. Implementierung eines Multicore-Frameworks — All-Electronics. 2017. url: https://www.all-electronics.de/multicore-framework/
[8] NXP. NXPmicro/rpmsg-lite: RPMsg implementation for small MCUs. url: https://github.com/NXPmicro/rpmsg-lite
[9] David Kauschke, Masterarbeit. url: https://github.com/kauschked/ma_openamp

Dieser Beitrag stammt, mit freundlicher Genehmigung des Autors, aus dem Tagungsband des ESE Kongress 2021.

Der Autor

(Bild: Mixed Mode)

David Kauschke arbeitet als Softwareentwickler bei der Mixed Mode GmbH in Gräfelfing bei München. Er hat sein Masterstudium Informatik mit Schwerpunkt Embedded Systems an der Hochschule München abgeschlossen und seine Arbeitsschwerpunkte liegen im Bereich der Entwicklung und Implementierung von Applikationen auf heterogenen Multiprozessoren mit dem Schwerpunkt auf der Linux-Seite. Hierbei wurde unter anderem während seiner Masterarbeit bei Mixed Mode das OpenAMP Framework auf den heterogenen MpSoC i.MX8X von NXP portiert.

(ID:48108304)