Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Peripheriegeräte

Was sind Peripheriegeräte?

Die meisten Mikrocontroller verfügen über mehr als nur eine CPU, einen RAM oder einen Flash-Speicher – sie enthalten Siliziumabschnitte, die für die Interaktion mit Systemen außerhalb des Mikrocontrollers sowie für die direkte und indirekte Interaktion mit ihrer Umgebung in der Welt über Sensoren, Motorsteuerungen oder menschliche Schnittstellen wie ein Display oder eine Tastatur verwendet werden. Diese Komponenten werden zusammenfassend als Peripheriegeräte bezeichnet.

Diese Peripheriegeräte sind nützlich, weil sie es einem Entwickler ermöglichen, die Verarbeitung auf sie auszulagern, sodass er sich nicht um alles in der Software kümmern muss. Ähnlich wie ein Desktop-Entwickler die Grafikverarbeitung auf eine Grafikkarte verlagern würde, können Embedded-Entwickler einige Aufgaben auf Peripheriegeräte verlagern, sodass die CPU ihre Zeit mit anderen wichtigen Dingen verbringen oder gar nichts tun kann, um Strom zu sparen.

Wenn Sie sich die Hauptplatine eines altmodischen Heimcomputers aus den 1970er oder 1980er Jahren ansehen (und tatsächlich sind die Desktop-PCs von gestern nicht so weit von den eingebetteten Systemen von heute entfernt), würden Sie Folgendes erwarten:

  • Einen Prozessor
  • Einen RAM-Chip
  • Einen ROM-Chip
  • Einen Ein-/Ausgabe-Controller

Der RAM-Chip, der ROM-Chip und der I/O-Controller (das Peripheriegerät in diesem System) wären über eine Reihe paralleler Leiterbahnen, die als „Bus“ bekannt sind, mit dem Prozessor verbunden. Dieser Bus trägt Adressinformationen, die auswählen, mit welchem ​​Gerät auf dem Bus der Prozessor kommunizieren möchte, und einen Datenbus, der die eigentlichen Daten überträgt. In unseren eingebetteten Mikrocontrollern gelten die gleichen Prinzipien – nur dass alles auf einem einzigen Stück Silizium untergebracht ist.

Im Gegensatz zu Grafikkarten, die normalerweise über eine Software-API wie Vulkan, Metal oder OpenGL verfügen, werden Peripheriegeräte unserem Mikrocontroller über eine Hardwareschnittstelle zugänglich gemacht, die einem Teil des Speichers zugeordnet ist.

Linearer und realer Speicherraum

Bei einem Mikrocontroller kann auch das Schreiben von Daten an eine beliebige andere Adresse – etwa 0x4000_0000 oder 0x0000_0000 – ein völlig zulässiger Vorgang sein.

Auf einem Desktop-System wird der Speicherzugriff streng von der MMU (Memory Management Unit, Speicherverwaltungseinheit) kontrolliert. Diese Komponente hat zwei Hauptaufgaben: die Durchsetzung von Zugriffsberechtigungen für Speicherbereiche (um zu verhindern, dass ein Prozess den Speicher eines anderen Prozesses liest oder verändert) sowie die Abbildung von Segmenten des physischen Speichers auf virtuelle Speicherbereiche, die von der Software genutzt werden. Mikrocontroller verfügen in der Regel nicht über eine MMU; stattdessen verwendet die Software dort ausschließlich reale physische Adressen.

Obwohl 32-Bit-Mikrocontroller über einen echten, linearen Adressraum von 0x0000_0000 bis 0xFFFF_FFFF verfügen, nutzen sie für den eigentlichen Speicher meist nur einige hundert Kilobyte dieses Bereichs. Dadurch bleibt ein beträchtlicher Teil des Adressraums ungenutzt. In früheren Kapiteln war die Rede davon, dass sich der RAM an der Adresse 0x2000_0000 befindet. Wäre unser RAM 64 KiB groß (d. h. mit einer maximalen Adresse von 0xFFFF), so entsprächen die Adressen 0x2000_0000 bis 0x2000_FFFF diesem Speicherbereich. Wenn wir in eine Variable schreiben, die an der Adresse 0x2000_1234 liegt, geschieht intern Folgendes: Eine Logikeinheit erkennt den oberen Teil der Adresse (in diesem Beispiel 0x2000) und aktiviert den RAM, sodass dieser auf den unteren Teil der Adresse (in diesem Fall 0x1234) reagieren kann. Bei einem Cortex-M-System ist zudem das Flash-ROM eingeblendet – etwa im Bereich von 0x0000_0000 bis 0x0007_FFFF (bei einem 512-KiB-Flash-ROM). Anstatt den gesamten verbleibenden Raum zwischen diesen beiden Bereichen ungenutzt zu lassen, haben die Entwickler der Mikrocontroller die Schnittstellen für Peripheriegeräte bestimmten Speicheradressen zugeordnet. Das Ergebnis sieht dann ungefähr so ​​aus:

Nordic nRF52832 Datasheet (pdf)

Im Speicher abgebildete Peripheriegeräte

Die Interaktion mit diesen Peripheriegeräten ist auf den ersten Blick einfach: Schreiben Sie die richtigen Daten an die richtige Adresse. Beispielsweise könnte das Senden eines 32-Bit-Worts über eine serielle Schnittstelle genauso direkt sein wie das Schreiben dieses 32-Bit-Worts an eine bestimmte Speicheradresse. Das Serial-Port-Peripheriegerät würde dann übernehmen und die Daten automatisch versenden.

Die Konfiguration dieser Peripheriegeräte funktioniert ähnlich. Anstatt eine Funktion zum Konfigurieren eines Peripheriegeräts aufzurufen, wird ein Teil des Speichers verfügbar gemacht, der als Hardware-API dient. Schreiben Sie „0x8000_0000″ in ein SPI-Frequenzkonfigurationsregister, und der SPI-Port sendet Daten mit 8 Megabit pro Sekunde. Schreiben Sie „0x0200_0000″ an dieselbe Adresse und der SPI-Port sendet Daten mit 125 Kilobit pro Sekunde. Diese Konfigurationsregister sehen in etwa so aus:

Nordic nRF52832 Datasheet (pdf)

Über diese Schnittstelle erfolgen die Interaktionen mit der Hardware, unabhängig davon, welche Sprache verwendet wird – sei es Assembler, C oder Rust.