
ARM-Training
Der Name ARM steht für eine scheinbar endlose Reihe an Prozessoren, doch welchen davon will man für welche Anwendung benutzen? Mit der richtigen Anleitung in der Hand sind sie leicht zu bedienen und bieten eine schier unendliche Vielfalt an Möglichkeiten. Damit man den Wald vor lauter Bäumen noch findet, führen wir hier in die Grundbegriffe ein.
Was haben Autos, Waschmaschinen und Handys gemeinsam? Richtig, bei vielen Modellen kann man irgendwo im Inneren einen ARM-Chip verbaut finden. Die Popularität der ARM-Architektur ist in der Industrie ungeschlagen, im Hobbybereich hinkt sie etwas hinterher. Dafür gibt es vor allem einen Grund: ARM bietet die breiteste Palette an Prozessoren, es gibt sehr viele Hersteller, die Tausende Varianten von ARM-Systemen herstellen, von sehr kleinen achtbeinigen Mikrocontrollern mit wenigen MHz Taktfrequenz bis zu sehr leistungsstarken mit Hunderten Beinen (Anschlüssen) und Taktfrequenzen im Gigahertzbereich. Außerdem gibt es viele unterschiedliche Entwicklungsumgebungen und Werkzeuge, sodass man damit jede denkbare Anwendung realisieren kann. Doch die Vielfalt hat ihren Preis: Als Anfänger, auf sich allein gestellt, kann man kaum entscheiden, was man braucht und welche Dokumentation man lesen sollte. Hier helfen wir mit unserem Einstieg, damit ist ARM auch nicht komplizierter als andere Mikrocontroller. Dem Basteln und Programmieren stellen wir diesmal die Theorie voran.
Kern und Familiengeschichte
ARM steht für Advanced Risc Machines als Name für die Prozessorkerne und die Firma, die sie entwickelt. Die Firma wurde als Tochter von Acorn Computers gegründet, einem Hersteller von Desktop-Computern. Acorn entwickelte Mitte der 1980er Jahre einen eigenen Prozessor für seine Computer und ließ diesen von den Herstellern fertigen, von denen Acorn auch sonst beliefert wurde. Das hat sich bis heute gehalten und so stellt ARM selbst keine Hardware her, sondern lizenziert seine Kerne, damit andere Hersteller sie in ihren Mikrocontrollern und System-on-Chips (SoCs) verwenden können. Einer dieser Lizenznehmer ist zum Beispiel Broadcom, dessen SoCs in dem populären Einplatinenrechner Raspberry Pi verbaut werden. Bis auf einige wenige Ausnahmen handelt es sich bei ARM um 32-Bit-Prozessoren, nur die neuesten Hochleistungsmodelle arbeiten mit 64 Bit.
Die Menge von Befehlen, die ein Prozessor versteht, nennt man Befehlssatz. ARM-Prozessoren unterstützen mehrere Befehlssätze, teilweise mit Dopplungen. Der klassische Befehlssatz besteht aus 32 Bit breiten Befehlen. Um Programmspeicher zu sparen, wurde zusätzlich ein 16 Bit breiter Befehlssatz eingeführt, der Thumb genannt wird. Damit spart man zwar eine Menge Speicher ein, aber die Leistung schneidet etwas schlechter ab, als beim klassischen Befehlssatz. Die moderne Variante namens Thumb 2 enthält 16 und 32 Bit breite Befehle und soll in Code-Dichte dem Thumb-Befehlssatz und in der Leistung dem klassischen Befehlssatz nahe kommen. Es ist möglich ARM und Thumb Code zu mischen .

ARM teilt seine Prozessorkerne heutzutage in drei Familien ein. Die leistungsstärkste davon ist der ARM Cortex-A. Der Buchstabe A steht für Applications (Anwendungen), womit angedeutet werden soll, dass diese Familie für die Ausführung von Betriebssystemen wie Linux oder Windows 10 geeignet ist. Einen oder mehrere dieser Kerne findet man fast in jedem aktuellen Smartphone. Der ARM Cortex-R ist besonders für Echtzeitanwendungen geeignet (R steht für Realtime). Er findet vorzugsweise in Festplatten-Controllern und Fahrzeugen Verwendung, wo schnelle und zuverlässige Reaktionen entscheidend sind. Der Cortex-M ist für Mikrocontroller spezialisiert, wo man Wert auf einen niedrigen Stromverbrauch und einen günstigen Preis legt.
Cortex-A
In Smartphones und Einplatinenrechnern ist ARMs Cortex-A-Familie besonders populär. Ab und zu findet man auch noch ARM-Klassiker in diesen Geräten, wie den ARM11 oder seltener den noch älteren ARM9, die jedoch auch eine wesentlich geringere Leistung aufweisen als ihre jüngeren Cortex-A-Brüder. Die Cortex-A Prozessoren unterstützen den klassischen 32-Bit-ARM-Befehlssatz, sowie Thumb und Thumb 2. Die feinen Unterschiede der einzelnen Prozessoren betreffen vor allem die Erweiterungen des Befehlssatzes und einige spezielle Extras, wie zum Beispiel die direkte Ausführung von Java Bytecode auf der Hardware-Ebene, oder die Unterstützung von Multicores. Damit kann ein vermeintlich schwächerer Prozessor aufgrund seiner Erweiterungen für spezielle Aufgaben manchmal besser geeignet sein als ein zahlenmäßig überlegeneres Modell.

Das wohl entscheidendste Merkmal eines Cortex-A-Prozessors ist seine Wortbreite, die bei den neuesten Modellen 64 Bit beträgt. Hinter dem Namen NEON steckt eine Erweiterung des Befehlssatzes um SIMD-Instruktionen (Single Instruction Multiple Data), die speziell für Multimedia-Anwendungen optimiert sind. Damit können mehrere Daten gleichzeitig verarbeitet werden, zum Beispiel kann man in nur einem Taktzyklus vier Additionen ausführen lassen. Das ist vor allem für solche Aufgaben wie MP3-Dekodierung vorteilhaft, denn diese könnte von einem ARM mit NEON-Erweiterung bei nur 10 MHz Taktfrequenz ausgeführt werden, bei höherer Taktfrequenz bleibt entsprechend Rechenzeit für andere Aufgaben übrig.

Die meisten Cortex-A-Prozessoren und einige Modelle der Cortex-M-Familie haben eine Fließkommaeinheit, genannt FPU (Floating Point Unit). Bei ARM hat sich aber der Name VFP (Vector Floating Point) gehalten, da diese Erweiterung in ihrer ersten Version auch Instruktionen für Vektorrechnung enthielt, was später durch NEON ersetzt wurde. Ist diese Einheit nicht vorhanden, kann es vor allem bei Berechnungen von 3D-Grafiken oder Audiodaten zu erheblichen Leistungseinbußen kommen. Wie NEON und die FPU ist die DSP-Erweiterung vor allem für Multimedia-Anwendungen leistungssteigernd, allerdings nicht für Fließkomma-Arithmetik, sondern auf Festkomma basierenden Berechnungen.
Systeme, auf denen viele Java-Anwendungen laufen sollen, profitieren von der Jazelle-Erweiterung. Dabei muss man zwischen DBX (Direct Bytecode eXecution) und RCT (Realtime Compilation Target) unterscheiden. Bei DBX kann der Java Bytecode direkt auf der Hardware ausgeführt werden, bei RCT muss der Bytecode noch interpretiert werden, aber dazu sind besonders optimierte Instruktionen vorhanden. Nachfolger von Jazelle RCT ist ThumbEE, aber die Erweiterung wurde inzwischen eingestellt und ist in neueren ARM-Kernen nicht mehr zu finden, da moderne Just-In-Time-Compiler ähnlich leistungsstark sind.

Mit Hilfe von ARMs big.LITTLE-Technologie lassen sich zwei verschiedene Prozessorkerne kombinieren, ein kleiner, um Strom zu sparen, und ein großer, um Leistungsspitzen zu bewältigen, der in weniger aufwändigen Rechenphasen abgeschaltet werden kann. Die Stromersparnis mit dieser Technik soll noch besser sein, als einfach nur die Taktfrequenz des Prozessors zu drosseln. Fast alle Modelle sind Multicore-fähig und können in der konkreten Implementierung in einem SoC als Single- bis Quadcore aufgebaut werden. In Kombination mit big.LITTLE können bis zu acht Kerne in einem Cortex-A-System verbaut sein, also maximal vier big-Kerne, zum Beispiel der A15 und maximal vier LITTLE-Kerne, wie der A7. Hierüber besteht einige Verwirrung, denn ursprünglich konnten von keinem Betriebssystem alle acht Kerne gleichzeitig genutzt werden, sondern maximal vier. Für Linux gibt es Patches um acht Kerne gleichzeitig zu betreiben, die zum Beispiel in dem Kernel verwendet werden, der für den ODROID-XU3-Einplatinenrechner angeboten wird. Wer also alle acht Cores nutzen möchte, muss sichergehen, dass das verwendete Betriebssystem dies auch unterstützt. Die Bezeichnung dafür kann entweder GTS (Global Task Scheduling) oder HMP (Heterogeneous Multi-Processing) heißen, beides bedeutet aber das Gleiche. Für aktuelle Linux-Kernel ist das nicht ohne Patches möglich. Aktuell im ungepatchten Kernel enthalten ist der IKS (In-Kernel Switcher), der maximal vier Cores gleichzeitig unterstützt, wobei für jeden Core je nach Last entweder der LITTLE- oder der big-Kern aktiviert wird.

Die LPAE (Large Physical Address Extension) Erweiterung betrifft nur die 32-Bit-Kerne, denn mit 32 Bit kann maximal 4 Gigabyte RAM-Speicher adressiert werden. LPAE erweitert deshalb die Adressierung auf 40 Bit, womit theoretisch 1000 Gigabyte ansprechbar werden. Die Ausstattung mit Cache-Speicher verbessert vor allem die Zugriffszeiten auf Daten, dabei sind für die verschiedenen Cortex-A-Modelle unterschiedliche Größen vorgesehen. Wie viel Cache-Speicher tatsächlich in einem SoC verbaut werden, kann der Hersteller in Grenzen entscheiden. Ein L2-Cache ist für viele Modelle optional.
Cortex-R
Die Cortex-R-Prozessoren sind das schwarze Schaf unter den ARM-Familien. Sie sind auf sicherheitskritische Echtzeitanwendungen spezialisiert und man findet sie deshalb vorwiegend in Sicherheitssystemen, zum Beispiel bei Fahrzeugen. Da sie so speziell sind, gibt es auch nur wenige Hersteller, die eine Cortex-R-Lizenz erworben haben. Die meisten der wenigen Modelle, die auf dem Markt erhältlich sind, stammen von Texas Instruments. Im Vergleich zu den anderen ARM-Familien ist die Cortex-R-Familie die teuerste. Dafür haben sie wesentlich präzisere Timer als die Cortex-A- und -M-Modelle, ein vorhersagbares Interrupt Timing und sie können im Lockstep-Betrieb laufen. Das heißt, es laufen zwei Kerne parallel, die den gleichen Programmcode ausführen, wobei jeder Schritt verglichen wird. Tritt ein Fehler in einem Prozessorkern auf, kann dieser korrigiert werden. So ein fehlertolerantes System ist in der Programmierung allerdings sehr kompliziert und schon gar nicht für Einsteiger geeignet.
Cortex-M
Der für Hardware-Bastler interessanteste ARM ist der Cortex-M, M steht für Mikrocontroller. Er unterstützt nur die Thumb- und Thumb-2-Befehlssätze. Den besonders stromsparenden Cortex-M gibt es in verschieden komplexen Varianten, wobei die einfachsten als M0, M0+ und M1 bezeichnet werden und nur einen eingeschränkten Befehlssatz unterstützen. Die M3-, M4- und M7-Kerne bieten erweiterte Befehlssätze und optional eine Gleitkommaeinheit. Auf den drei letztgenannten Kernen basierende Mikrocontroller sind meistens sehr leistungsstark und unterstützen eine breite Palette an Peripherie, bis hin zu externem SDRAM-Speicher, den man auch in handelsüblichen Computern findet. Für Betriebssysteme wie Linux eignen sich die Cortex-M-Modelle trotzdem nicht, da sie nicht über eine MMU (Speicherverwaltungseinheit) verfügen. Dennoch gibt es eine Linux-Portierung für den Cortex-M3 und -M4, diese unterliegt einigen Einschränkungen: Zum Beispiel gibt es ohne MMU das Problem, dass Anwendungen den Speicher anderer Anwendungen überschreiben können, wodurch es leichter zu Fehlern kommen kann, und das Auslagern von RAM-Speicher auf der Festplatte in einer Swap-Partition ist nicht möglich.
Babylonische Sprachverwirrung?
Die Cortex-M-Familie beherbergt sehr kleine achtfüßige Mikrocontroller und daneben auch Modelle mit über 200 Anschlüssen. Die verschiedenen Hersteller verwenden ebenfalls unterschiedliche Peripherie, das heißt, dass zum Beispiel zwei ARM-Mikrocontroller mit dem gleichen Kern jeweils eine andere serielle UART-Schnittstelle besitzen. Diese erfüllt zwar exakt den gleichen Zweck, aber intern ist sie anders umgesetzt, sodass sie im Programm auch anders konfiguriert werden müsste, aber nicht muss! Im Idealfall sieht der Programmcode in der Programmiersprache C sogar exakt gleich aus, obwohl sich die daraus erzeugten Assemblercodes beziehungsweise Maschinencodes vollkommen voneinander unterscheiden.
Möglich macht das die Hardware-Abstraktions-Ebene CMSIS (Cortex Microcontroller Software Interface Standard), die direkt von ARM beziehungsweise KEIL entwickelt wird. Das als deutsche GbR 1982 gestartete Unternehmen Keil Elektronik wurde 2005 von ARM gekauft. KEIL entwickelt vor allem Compiler, Assembler, Debugger und Simulatoren für viele verschiedene Mikrocontroller, unter anderem für ARM. CMSIS funktioniert zwar unabhängig vom Hersteller, allerdings nur für die Cortex-M-Familie – ein weiterer Grund, warum die Cortex-M-Prozessoren für Bastler zugänglicher sind.

CMSIS wird ständig weiterentwickelt und für neuere Cortex-M-Mikrocontroller angepasst. Es besteht aus mehreren Komponenten: CMSIS-Core ist vor allem für den Prozessorkern verantwortlich und definiert unter anderem standardisierte Routinen für den Systemstart. CMSIS-Driver stellt ein einheitliches Interface für die Peripherie zur Verfügung. CMSIS-DSP enthält mathematische Funktionen für die digitale Signalverarbeitung. Daneben gibt es noch fünf weitere Komponenten, zum Beispiel für das Betriebssystem RTOS. KEIL beziehungsweise ARM legt bei CMSIS vor allem Wert auf Portabilität, also dass der gleiche Code auf unterschiedlichen Mikrocontrollern läuft. Außerdem ist es ein Ziel von KEIL mit CMSIS den Einstieg in die Programmierung von Cortex-M-Mikrocontrollern zu erleichtern und eine steile Lernkurve zu ermöglichen.
Cortex-M-Hersteller
Drei der bekanntesten Hersteller von Cortex-M-Mikrocontrollern sind STM, Atmel und NXP. Inzwischen ist Atmel von Microchip aufgekauft worden, wird aber seine Produktpalette weiter fortsetzen; und NXP hat Freescale gekauft, einen Hersteller der ebenfalls ARM-Prozessoren baut. Die LPC-Baureihe von NXP kann einige besonders anfängerfreundliche Merkmale vorweisen: Es gibt zwei Mikrocontroller im DIP-Gehäuse, den LPC810M021FN8 als DIP-8 und den LPC1114FN28 als DIP-28. Beide Modelle haben einen seriellen Bootloader in einem ROM-Speicher, wie es bei den meisten LPC-Modellen üblich ist. Damit ist es mit einem einfachen USB-Seriell-Adapter möglich, die LPCs zu programmieren. Der Adapter muss jedoch auch 3,3 Volt unterstützen. Weil der Bootloader in einem ROM gespeichert ist, kann er auch nicht versehentlich gelöscht werden; und damit kann man sich aus seinem LPC sozusagen nicht aussperren. STM kann dagegen vor allem mit vielen verschiedenen sehr preisgünstigen Entwicklungsboards punkten.
Entwicklungsumgebungen
Die IDEs (Entwicklungsumgebungen) kann man prinzipiell in zwei Klassen einteilen: herstellerspezifische und -übergreifende. Erstere sind auf einen Hersteller von ARM-Mikrocontrollern festgelegt und unterstützen keine anderen Produkte, Letztere unterstützen möglichst viele Marken und Modelle. Eine sehr einfache Entwicklungsumgebung ist zum Beispiel die Arduino IDE, mit der sich die Arduinos Due und Zero programmieren lassen, die beide einen ARM-Mikrocontroller enthalten. Diese Variante unterstützt jedoch nur sehr wenige Boards und hat außerdem den Nachteil, dass man dort größeren und weniger leistungsfähigen Code erzeugt, weil man in dem sehr abstrahierten Arduino eigenen Dialekt von C++ programmiert. Über die allgemeine Programmierung eines ARMs lernt man mit Arduino also so gut wie nichts und auch von dem komfortablen CMSIS sieht man nichts.

In der Tabelle befinden sich einige der bekannteren Entwicklungsumgebungen, doch längst nicht alle, die es gibt. Für den Anfang empfiehlt es sich die herstellerspezifische Entwicklungsumgebung passend zu seinem ARM-Mikrocontroller oder -Board zu wählen, weil man davon ausgehen kann, dass man darin die einfachste Hardware-Unterstützung und passendste Konfiguration erhält. Die meisten dieser Entwicklungsumgebungen basieren auf Eclipse, was ebenfalls von Vorteil ist, denn selbst Eclipse kann sogar so konfiguriert werden, dass es herstellerübergreifend genutzt werden kann. Eclipse ist unter den kostenlosen Entwicklungsumgebungen eine der leistungsfähigsten. Dazu ist übrigens in einem späteren Heft ein extra Artikel geplant.
Werkzeuge für Cortex-M
Für die Programmierung von Cortex-M-Mikrocontrollern benötigt man neben der Entwicklungsumgebung einen Programmer, beziehungsweise einen Debugger, mit dem man seinen Code in den Chip bekommt. Der Debugger kann den Programmcode ebenfalls auf den Chip übertragen, aber ebenso den Betrieb überwachen und gegebenenfalls unterbrechen, um zum Beispiel den Wert eines Registers auszulesen. Wenn man auf ein Board zurückgreift, ist manchmal schon ein Debugger integriert. Beim Kauf eines Boards sollte man darauf achten. Das Standard Debug Interface bei den meisten ARMs ist JTAG. Nur die LPC-Modelle von NXP haben zusätzlich noch einen seriellen Bootloader, womit man die LPCs programmieren, aber nicht debuggen kann. Für die ersten Schritte genügt das jedoch und es hat den Vorteil, dass man auf einen sehr günstigen Programmer in Form eines USB-seriell-Wandlers mit 3,3 Volt Pegeln zurückgreifen kann.

Bei den Programmern beziehungsweise Debuggern ist es wichtig, sich vor dem Kauf zu informieren, ob das Gerät von der Entwicklungsumgebung seiner Wahl auch unterstützt wird. Die meisten IDEs unterstützen nur einige ausgewählte Modelle. Der am häufigsten genutzte und unterstützte Debugger ist der Segger J-Link, der allerdings auch nicht ganz billig ist (ab etwa 360 Euro). Es gibt ihn auch in einer EDU-Version (etwa 60 Euro), die für Studenten, Schulen und Hobbybastler erhältlich ist, die jedoch für den privaten Gebrauch oder für Bildungszwecke eingeschränkt ist. Eine sehr günstige Alternative dazu ist das ARM-USB-TINY von Olimex. Dieser wird von der Debugging-Software OpenOCD unterstützt und ist damit auch in Eclipse nutzbar.
Fazit

ARM bietet mit seiner breiten Palette an Mikrocontrollern individuelle Hardware-Gestaltungsmöglichkeiten, das kann je nach Bedarf zum Beispiel ein Chip mit über 100 GPIOs sein, über 30 Analog-Digital-Wandler-Kanäle, sehr viele PWM-Kanäle, Audioein- und -ausgänge, oder ein Port zum Anschluss eines großen dynamischen Speichers. Natürlich hat man aber auch die Möglichkeit, sich für eine sehr platz- und stromsparende Lösung zu entscheiden. Man wächst mit seinen Ansprüchen – die Plattform wächst mit und man wird nicht irgendwann stecken bleiben und muss in den seltensten Fällen auf eine andere Architektur ausweichen und damit noch mal neu lernen. Diese Vielfalt hat ebenso den Vorteil, dass man die externen Bauteile einer Mikrocontroller-Schaltung minimal halten kann, man braucht zum Beispiel seltener Shields, sondern nur den Prozessor mit den passenden Eigenschaften, was das System auch weniger fehleranfällig macht.
In diesem Heft befindet sich noch eine Bauanleitung für einen LoFi-Audio-Effekt auf einem LPC810-ARM-Mikrocontroller. Darüber hinaus sind Artikel für weitere ARM-Projekte geplant, ebenso wie eine Anleitung, in der Eclipse so installiert und konfiguriert wird, dass man damit ARM-Cortex-M-Mikrocontroller verschiedener Hersteller in einer Entwicklungsumgebung programmieren kann. —pff