Cache auf einem Mikrocontroller – Was es zu beachten gibt

Björn Schmitz

10/11/2017

Wir haben vor kurzem für einen Kunden eine Firmwareerweiterung programmiert, welche der Anwendung ermöglicht Daten auf dem Mikrocontrollerflash zu speichern und zu lesen. Die Firmware läuft auf einem PIC32MZ, welcher mit einem Daten- und einem Instruktionscache ausgestattet ist. Wer schon mal versucht hat Software für einen PC mit Multi-Core CPU zu parallelisieren weiß, dass die Caches hierbei eine wichtige Rolle spielen. Greifen – z.B. in einer Schleife – alle Kerne gleichzeitig auf denselben Cache zu, wird der Code hierdurch langsamer anstatt schneller. Paradoxerweise je langsamer, je mehr Kerne man einsetzt. Der PIC32MZ hat allerdings nur eine Single-Core CPU. Man sollte also erwarten, dass diese Probleme hier nicht auftreten.

Tatsächlich kann der Einsatz eines Cache die Ausführungszeit bei Mikrocontrollern deutlich beschleunigen, da Zugriffszeiten auf den RAM und vor allem auf den Flash deutlich höher sind als die Zugriffszeiten auf den Cache. Der Instruktionscache des PIC32MZ ist 16kB groß. Theoretisch könnte bei kleineren Programmen der gesamte Programmflash gecached werden. Da sich die CPU so Instruktionen fast ausschließlich aus dem Cache holt, kann ein Programm   dementsprechend schneller ablaufen. Ein Ausführen des Codes aus dem RAM ist demnach kaum nötig.

Trotz aller Vorteile gibt es jedoch bei Einsatz eines Caches einiges zu beachten. Vor allem wenn Daten am Cache vorbei geschrieben und gelesen werden. Dies passiert immer dann, wenn nicht die CPU den Vorgang ausführt, sondern eine Hardwareinstanz. Hierbei kann es sich zum Beispiel um den DMA- oder den Flashcontroller handeln. Stellen wir uns als Beispiel folgendes Szenario vor: Eine Anwendung, welche auf einem PIC32MZ läuft, soll regelmäßig Daten auf dem Flash abspeichern. Um die Lebenszeit des Flashs zu verlängern, werden alte Daten nicht bei jedem Schreibvorgang gelöscht, sondern stattdessen solange auf einen freien Speicherbereich geschrieben, bis der gesamte Speicher voll ist. Die Anwendung muss also bevor neue Daten geschrieben werden können, zuerst den Speicher auslesen um einen freie Stelle zu finden. Die Daten beinhalten eine CRC (cyclic redundancy check) welche über den kompletten Datensatz (mit Ausnahme der CRC selber) gerechnet wurde. Berechnet nun die Anwendung die CRC über den gerade geschriebenen Speicherbereich und vergleicht diese mit der geschriebenen CRC auf dem Flash, wird die Anwendung feststellen, dass die CRCs nicht identisch sind.

Bei der Berechnung der CRC ergibt sich in diesem Beispiel folgendes Problem: Bei der Suche nach einem freien Speicherplatz wurde der Mikrocontrollerflash zunächst gelesen. Die Daten wurden dafür zunächst in den Cache übertragen. Da die Adressen, an denen die Daten gespeichert wurden, nun zumindest teilweise im Cache vorhanden sind, wird die CPU versuchen bei der Berechnung der CRC möglichst viele Daten aus dem Cache zu lesen. Die Daten im Cache sind allerdings zu diesem Zeitpunkt nicht mehr aktuell, da der Flashcontroller bereits die entsprechenden Adressen beschrieben hat. Aus diesem Grund kann die Anwendung die korrekte CRC nicht berechnen.

Ihr Ansprechpartner:

M.Sc. Björn Schmitz, Software Entwickler
E-Mail: schmitz@medtech-ingenieur.de
Tel.:  +49 9131 691 240
 

Benötigen Sie Unterstützung bei der Entwicklung Ihres Medizingeräts? Wir helfen gerne! Die MEDtech Ingenieur GmbH bietet Hardware-Entwicklung, Software-Entwicklung, Systems Engineering, Mechanik-Entwicklung und Beratung aus einer Hand. Nehmen Sie Kontakt mit uns auf.

Kontakt aufnehmen


Die Abbildung unten zeigt (vereinfacht) die Implementierung der Caches beim PIC32MZ. Die Abbildung wurde dem Microchip Application Note AN1600 entnommen. DMA- und Flashcontroller wurden nachträglich farbig markiert. Wie in der Abbildung zu erkennen ist, schreiben diese völlig unabhängig vom Cache Daten auf den Flash. So kann es passieren, dass Daten im RAM oder im Flash aktueller sind als Daten im Cache. Außerdem könnte es prinzipiell passieren, das Daten welche mit DMA auf den RAM geschrieben wurden, anschließend bei einem Cache flush überschrieben werden.

Cache Implementierung beim PIC32MZ. Quelle: Microchip Applicaiton Note AN1600 – Using L1 Cache on PIC32MZ Devices

 

Um dies zu verhindern, hat der Programmierer mehrere Möglichkeiten. Eine Möglichkeit wäre es ein Softwarereset nach jedem Schreibvorgang durchzuführen. Nach einem Neustart ist der Cache leer und muss daher neu geladen werden. Diese Möglichkeit ist in der Regel natürlich nicht praktikabel.

Sinnvoller wäre es nach jedem Schreibvorgang auf dem Flash eine Cache invalidation durchzuführen, die geschriebenen Adressen also als „ungültig“ zu erklären. So müssen die entsprechenden Adressen beim nächsten Lesevorgang neu gecached werden. Vor jedem DMA Transfer sollte ein Cache flush durchgeführt werden. Hierbei wird der Cache geleert und die gegenwärtig gecachten Daten werden auf den RAM zurückgeschrieben. So kann sichergestellt werden, dass wirklich nur aktuelle Daten durch den DMA übertragen werden. Mit Cache flush und Cache invalidation lassen sich schon die meisten Probleme lösen. Wichtig ist allerdings, dass beides vor dem Schreibvorgang passiert. Würde die Anwendung auf das Ende eines Flashzugriffs warten und anschließend eine Cache invalidation ausführen, könnten bei einem Kontextwechsel veraltete Daten aus dem Cache gelesen werden. So ein Kontextwechsel könnte zum Beispiel durch einen Interrupt erfolgen.

Eine Möglichkeit grundsätzlich zu verhindern, und gleichzeitig Cache invalidation und Cache flush – welche ggf. überflüssig seien können – zu vermeiden, ist es Daten direkt in einem Bereich abzulegen, welche nicht gecached werden. Der PIC32MZ bietet hierfür zwei virtuell getrennte Adressräume an, von denen einer gecached und einer nicht gecached wird. Dies ist im Bild weiter unten dargestellt, welches dem PIC32MZ Datenblatt entnommen wurde. Wie zu erkennen ist, teilen sich die Adressbereiche KSEG0 und KSEG1 den gleichen physikalischen Adressraum und decken jeweils den kompletten Flash und den kompletten RAM ab. Während Daten in KSEG0 jedoch gecached werden, werden Daten in KSEG1 nicht gecached. Es ist also möglich, durch geeignete Adressierung, ein Cachen von Daten zu verhindern. Um den Code lesbarer zu gestalten, ist es möglich Daten direkt im KSEG1 Bereich anzulegen (standardmäßig werden Daten auf dem RAM in KSEG0 angelegt). Schreibt man:

uint32_t _attribute__((coherent)) dataBuffer[100];

wird das Array “dataBuffer“ in KSEG1 angelegt. DMA Transfers aus oder in das Array können demnach gefahrlos durchgeführt werden. Werden Daten vom Flash gelesen kann deren physikalische Adresse einfach in eine KSEG1 Adresse konvertiert werden, um zu verhindern, dass die Daten aus dem Cache gelesen werden.

Speicherorganisation des PIC32MZ. Quelle: Datenblatt des PIC32 MZ, PIC32MZ Embedded Connectivity with Floating Point Unit (EF) Family (DS60001320D)

 

 

Fazit

Caches auf Mikrocontrollern stellen heute keine Seltenheit mehr da. Neben Mikrocontrollern der PIC32MZ Serie verwenden diese auch Mikrocontroller, welche auf dem ARM Cortex-M7 basieren. Aus diesem Grund sollten sich heutzutage auch (oder vielleicht sogar vor allem) Embedded Entwickler mit der Funktionsweise von Caches auseinandersetzen. Trotz möglicher Fehlerquellen bieten Caches auf einem Mikrocontroller viele Vorteile, da die Zugriffszeiten auf Daten und Programmspeicher deutlich reduziert werden kann.

Die hier erklärten Methoden beziehen sich zwar alle auf den PIC32MZ, sind aber zum größten Teil auch auf andere Mikrocontroller mit Cache zu übertragen. In der Regel stellen die Hersteller der Mikrocontroller Informationen darüber zur Verfügung, was bei Verwendung des Caches zu beachten ist. Analog zum oben bereits erwähnten Application Note von Microchip, bietet zum Beispiel ST ein ähnliches Dokument an (AN4839, Level 1 cache on STM32F7 Series).

Natürlich gibt es zum Thema Cache viel mehr Theorie als in diesen Blogeintrag passen würde. Aus diesem Grund sind einige Punkte sehr vereinfacht dargestellt. Neben Kommentaren freue ich mich daher auch über Ergänzungen zu meinem Text.


Geschrieben von Björn Schmitz

Seit Juli 2017 gehöre ich zum MEDtech-Ingenieur Team und bin hier vor allem als Firmwareentwickler tätig. Schon in kürzester Zeit konnte ich an vielen spannenden Projekten aus dem Bereich Medizintechnik, aber auch aus anderen Bereichen mitwirken.


Weitere Beiträge

  • 29/01/2025
  • Allgemein, Hardware, Testen

EinleitungUm bei der EMV Prüfung für die Zulassung neuer medizintechnischer Geräte das Risiko zu reduzieren machen wir gerne Vortests mit den Geräten in der Prototypen Phase. Aktuell unterstützen wir ...

Weiterlesen
  • 12/11/2024
  • Allgemein, Software, Testen, Tools

In sicherheitskritischen Softwareprojekten steht die Qualität der Software an erster Stelle. Besonders bei Klasse-C-Software, die nach strengen Normen wie IEC 62304 (Medizintechnik) zertifiziert werden muss, ist es essenziell, dass ...

Weiterlesen
  • 12/09/2024
  • Allgemein, Fertigung, Hardware, Qualität

Die Schnellen fressen die Langsamen – die Bedeutung der schnellen Prototypenfertigung in der Elektronikentwicklung Unsere Bestückungsmaschine erlaubt uns kleinere Chargen manuell und wesentlich schneller zu bestücken. In der Elektronikbranche ...

Weiterlesen
Cookie-Übersicht

Die Internetseiten der MEDtech Ingenieur GmbH verwenden Cookies. Cookies sind Textdateien, welche über einen Internetbrowser auf einem Computersystem abgelegt und gespeichert werden.

Zahlreiche Internetseiten und Server verwenden Cookies. Viele Cookies enthalten eine sogenannte Cookie-ID. Eine Cookie-ID ist eine eindeutige Kennung des Cookies. Sie besteht aus einer Zeichenfolge, durch welche Internetseiten und Server dem konkreten Internetbrowser zugeordnet werden können, in dem das Cookie gespeichert wurde. Dies ermöglicht es den besuchten Internetseiten und Servern, den individuellen Browser der betroffenen Person von anderen Internetbrowsern, die andere Cookies enthalten, zu unterscheiden. Ein bestimmter Internetbrowser kann über die eindeutige Cookie-ID wiedererkannt und identifiziert werden.

Durch den Einsatz von Cookies kann die MEDtech Ingenieur GmbH den Nutzern dieser Internetseite nutzerfreundlichere Services bereitstellen, die ohne die Cookie-Setzung nicht möglich wären.

Mittels eines Cookies können die Informationen und Angebote auf unserer Internetseite im Sinne des Benutzers optimiert werden. Cookies ermöglichen uns, wie bereits erwähnt, die Benutzer unserer Internetseite wiederzuerkennen. Zweck dieser Wiedererkennung ist es, den Nutzern die Verwendung unserer Internetseite zu erleichtern. Der Benutzer einer Internetseite, die Cookies verwendet, muss beispielsweise nicht bei jedem Besuch der Internetseite erneut seine Zugangsdaten eingeben, weil dies von der Internetseite und dem auf dem Computersystem des Benutzers abgelegten Cookie übernommen wird.

Die betroffene Person kann die Setzung von Cookies durch unsere Internetseite jederzeit mittels einer entsprechenden Einstellung des genutzten Internetbrowsers verhindern und damit der Setzung von Cookies dauerhaft widersprechen. Ferner können bereits gesetzte Cookies jederzeit über einen Internetbrowser oder andere Softwareprogramme gelöscht werden. Dies ist in allen gängigen Internetbrowsern möglich. Deaktiviert die betroffene Person die Setzung von Cookies in dem genutzten Internetbrowser, sind unter Umständen nicht alle Funktionen unserer Internetseite vollumfänglich nutzbar.

Weitere Informationen erhalten Sie in unserer Datenschutzerklärung.

Unbedingt notwendige Cookies

Dieses Cookie wird benötigt, um Ihre Cookie-Einstellungen zu merken und weitere Hauptfunktionen zur Verfügung zu stellen

Um Ihnen eine Auskunft über Ihre gespeicherten personenbezogenen Daten hier (https://medtech-ingenieur.de/gespeicherte-daten-2/) geben zu können, benötigen wir einen Cookie, um Sie bei der Datenabfrage identifizieren zu können. Dieser Cookie muss aus Sicherheitsgründen deshalb aktiviert sein. Ein weiterer Cookie wird gesetzt, um diesen Banner nicht erneut anzeigen zu müssen.

Cookie-Name Beschreibung
PHPSESSID Name: PHP session
Anbieter:
Eigentümer der Webseite (MEDtech Ingenieur)
Zweck:
Wir benötigt, um Sie bei der Anfrage von personenbezogenen Daten identifizieren zu können. Das Cookie wird nur gesetzt, wenn Sie eine Anfrage hier (https://medtech-ingenieur.de/gespeicherte-daten-2/) stellen.
Laufzeit: Sitzungsende
Kategorie: Unbedingt notwendige Cookies
moove_gdpr_popup Name: Cookie-Box Einstellungen
Anbieter:
Eigentümer der Webseite (MEDtech Ingenieur)
Zweck:
Wird benötigt, um Ihre Cookie-Einstellungen zu speichern, um den Cookie-Banner nicht erneut anzeigen zu müssen.
Laufzeit: 1 Jahr
Kategorie: Unbedingt notwendige Cookies
comment_author_9c90e388e3e1be4a6c594fa6ac8a3eec
comment_author_email_9c90e388e3e1be4a6c594fa6ac8a3eec
comment_author_url_9c90e388e3e1be4a6c594fa6ac8a3eec
Name: Kommentar Einstellungen
Anbieter:
Eigentümer der Webseite (MEDtech Ingenieur)
Zweck:
Cookie wird angelegt, wenn Sie ein Kommentar auf MEDtech Ingenieur veröffentlichen wollen, um Sie als Autor identifizieren und den aktuellen Status Ihres Kommentars anzeigen zu können. Das Cookie enthält den angegebenen Namen. Das Cookie wird erst gesetzt, wenn Sie der Speicherung Ihrer personenbezogenen Daten zustimmen.
Laufzeit: 1 Jahr
Kategorie: Unbedingt notwendige Cookies
rmp-rate Name: RMP Rate
Anbieter: Eigentümer der Webseite (MEDtech Ingenieur)
Zweck: Cookie wird angelegt, wenn Sie eine Bewertung eines Blogbeitrags mithilfe des Sternebewertungssystems abgeben. Ihnen wird eine anonymisierte ID zugewiesen, um zu erkennen, ob Sie einen Artikel bereits bewertet haben oder nicht. Das Cookie wird nur verwendet, um zu verhindern, dass mehrfache Bewertung abgegeben werden und erst gesetzt, wenn Sie auf einen Stern klicken.
Laufzeit: 1 Jahr
Kategorie: Unbedingt notwendige Cookies
medtech-download-page Name: Download Page
Anbieter: Eigentümer der Webseite (MEDtech Ingenieur)
Zweck: Cookie wird angelegt, wenn Sie den Landing-Page Prozess erfolgreich durchlaufen haben. Dies geschieht nur, wenn Sie einen Content-Download von unserer Website anstreben.
Laufzeit: 1/2 Jahr
Kategorie: Unbedingt notwendige Cookies