Vor eineinhalb Jahren stellte ARM seine neue Architektur ARMv8-M für Mikrocontroller vor. Die ersten beiden CPUs heißen Cortex-M23 und -M33 und implementieren die TrustZone-Technik für sicherheitssensitive (Medizin-)Anwendungen.
Der größte Fortschritt bei ARMv8-M ist zweifelsohne die Implementierung der TrustZone-Technik, die Speicher, Register, Code, Interrupts, Stacks und Peripherie in sichere und unsichere Bereiche unterteilt, ohne – anders als bei Cortex-A – Determinismus und Latenzzeiten (bis auf wenige Ausnahmen) in Mitleidenschaft zu ziehen. Damit kann man z. B. Firmware und Middleware von Drittherstellern gegen Zugriffe von außen isolieren und sichere Verschlüsselungsmechanismen für Medizin-Anwendungen implementieren. Die ARMv8-M-Architektur haben wir im Detail beleuchtet [1], so dass sich dieser Beitrag voll auf die neuen CPUs konzentrieren kann.
Cortex-M23: der bessere Cortex-M0+
Nachdem es bei ARM-CPUs künftig zwei Sub-Profile »aus einem Guss« geben wird (»Baseline« und »Mainline«), implementiert der Cortex-M23 das Baselineprofil, das einige Verbesserungen gegenüber ARMv6-M bringt, etwa einen Hardwaredividierer (bislang gab es nur einen Hardwaremultiplizierer). Heute sieht man noch viele MCUs mit einem proprietären Hardwaredividierer, der an den Bus angehängt wird. Der Nachteil ist die eingeschränkte Softwarekompatibilität.
Weitere neue Instruktionen betreffen Verzweigungen über den gesamten 32-bit-Adressraum oder einen Vergleich-mit-Null-und-Sprung. Bislang musste der Compiler beim ARMv6-M bei weiten Sprüngen mehrere kleine 16-bit-Sprünge hintereinander erzeugen.
Die »Wide immediate Moves« MOVT und MOV.W können in der Instruktion abgelegte 16-bit-Werte in die oberen oder die unteren 16 bit eines Registers laden. Ein Fetch ist damit nicht notwendig. Interessant ist das, wenn ein Kunde im Speicher einen Bereich als »Execute Only« definiert hat, um z. B. das Auslesen einer Firmware zu verhindern. Konstanten musste man außerhalb dieses Speicherbereiches ablegen, da ja ein Lesezugriff in einem Execute-Only-Bereich verboten ist und zu einer Exception führt. Damit sind diese Konstanten aber auch potentiell von Hackern angreifbar. Mit den neuen Befehlen MOVT und MOV.W können die Konstanten nun in einem Execute-Only-Speicherbereich versteckt werden: Dort sind sie gegen Auslesen geschützt.
Wichtig für Multicore-Chips ist die Möglichkeit, Exklusivzugriffe auf Daten mittels Semaphoren zu erreichen. Dies war bislang nur in ARMv7-M möglich, nicht jedoch in ARMv6-M. Das Baselineprofil erschließt diese Eigenschaft nunmehr auch den kleinen CPU-Cores.
Last, but not least lässt jetzt der Status aller Interrupts individuell tracken. Jeder Interrupt kann mit einer Priorität versehen werden. Angenommen, es sind vier Interrupts anhängig, während ein höher priorisierter Interrupt abgearbeitet wird. Man könnte somit die Priorität der vier anhängigen dynamisch verändern, um festzulegen, welcher Interrupt als nächstes abgearbeitet wird.
Die zweistufige Pipeline hat der Cortex-M23 vom Cortex-M0+ geerbt. Die Folge ist, dass Sprünge nur zwei Taktzyklen benötigen und damit auch die Interruptlatenz bei 15 Zyklen verbleibt. Lediglich beim Auftreten eines Interrupts und einem Wechsel vom sicheren in den unsicheren Bereich oder umgekehrt steigt diese Latenz auf 24 Taktzyklen, da der vollständige Registersatz gesichert werden muss. Diese Werte enthalten die Prioritätserkennung, die Verschachtelung, die Sicherung der Register auf dem Stack, die Verzweigung in die Interruptroutine und den Beginn der Ausführung der ersten Anweisung in der Interrupt-Routine. Der Cortex-NVIC führt alle diese Operationen in Hardware aus. Andere Hersteller geben teilweise geringere Latenzen in Hardware an, die Prozessoren müssen jedoch gegebenenfalls einige der genannten Funktionen in Software ausführen, was die Gesamtlatenz erhöht.
Der M23 ist wie der M0+ extrem einfach aufgebaut. Er enthält eine von-Neumann-Architektur (einheitlicher I/O-Bus für Daten und Befehle) und unterstützt kein TCM. Daten und Anweisungen holt er direkt über eine einzige AMBA-AHB5-Schnittstelle (Cortex-M3/M4 und M33 haben zwei AHB5-Schnittstellen). Der konfigurierbare Nested-Interrupt-Controller (NVIC) ist eng mit dem Core verbunden und unterstützt bis zu 240 Interrupts in vier Ebenen und damit erheblich mehr als der Cortex-M0+ (32 Interrupts in vier Ebenen). Sicherer und unsicherer Status teilen sich beim M23 die 240 Interrupts. In Keils Tool-Chain können die Interrupts per Anklicken eines Auswahlfeldes als sicher oder unsicher klassifiziert werden.