So weisen Sie automatisch eine Flash-Seite zum Speichern von Einstellungen in der Anwendung zu

Ich habe die LPC8xx-Reihe von Cortex-M0+ MCUs ziemlich erfolgreich verwendet. Eine Schwäche: Diese haben kein eingebautes EEPROM (um die Einstellungen über Einschaltzyklen hinweg beizubehalten usw.). Es gibt jedoch eine Problemumgehung: Mit dem Flash-Programmierer in der Anwendung kann eine Seite (64 Byte) des Flash-Speichers gelöscht und neu geschrieben werden.

Ich habe dieses Beispiel verwendet: http://www.lpcware.com/content/forum/eeprom-emulation , das funktioniert.

Meine Frage: In diesem Beispiel ist die Adresse des Flash fest codiert, an die geschrieben werden soll. Das erscheint mir sehr gefährlich. Gibt es eine Möglichkeit, einen 64-Byte-ausgerichteten Block von 64 Bytes im Flash-Speicherplatz zuzuweisen, damit ich sicher sein kann, dass es sicher ist, darauf zu schreiben?

(Ich verwende LPCXpresso / GCC)

Vielen Dank für Ihre Hilfe dabei. Ich habe eine Demo für den LPC812 (der mit allen LPC8xx-Geräten funktionieren sollte) und einen Blogbeitrag geschrieben, der auf dem basiert, was ich hier gelernt habe: jdesbonnet.blogspot.ie/2015/02/nxp-lpc8xx-eeprom-emulation.html

Antworten (2)

Schließen Sie einfach die oberste Flash-Seite aus dem verfügbaren Programmspeicher in Ihrer Linker-Map aus, und das Erstellen sollte mit einem Fehler in der Linkphase fehlschlagen, wenn Programmcode darin überläuft. Sie können, wenn Sie möchten, einen Datenabschnitt auf der reservierten Seite erstellen und ein Pragma verwenden, um dort eine Datenstruktur zu platzieren, wenn Sie die Adresse nur in der Linker-Map und nirgendwo anders fest codieren möchten.

Wenn Sie ein Upgrade oder Downgrade auf ein Teil mit einer anderen Flash-Größe in Betracht ziehen, müssen Sie es natürlich verschieben.

Eine andere Möglichkeit könnte sein, die zweitniedrigste Flash-Seite zu verwenden - Sie brauchen wahrscheinlich die niedrigste für einen Einstiegspunkt (und möglicherweise die Vektortabelle, wenn das unflexibel ist?). Aber das könnte ein Linker-Abschnitt sein, dann eine Lücke für eine Datenseite, und dann ein weiterer Linker-Abschnitt für gewöhnlichen Programmcode, der sich bis zur Grenze dessen erstreckt, was der aktuelle Chip hat.

Beachten Sie, dass Standard-Uploads Ihren Speicherplatz löschen können, indem Sie mit einer vollständigen Flash-Löschung beginnen.

Sie könnten ein konstantes Array deklarieren, das der Compiler Flash zuweisen sollte, und Compiler-Einschränkungen verwenden, um es auf eine 64-Byte-Grenze zu zwingen. In GCC wäre dies:

const char flashpage[64] __attribute__ ((aligned (64)));

Beachten Sie, dass die Syntax je nach Compiler variieren kann.

Der Compiler erkennt dieses Symbol dann an einer anderen Stelle als normalerweise, und Sie können es flashpageals Zeiger auf den Ort verwenden (weil es natürlich flashpagenur ein ist const char *).

Beachten Sie, dass dies nicht garantiert, dass sich das Objekt über mehrere Builds hinweg am selben Ort befindet. Das spielt wahrscheinlich keine Rolle, da der gesamte Flash normalerweise jedes Mal gelöscht wird, wenn Sie die MCU neu programmieren, aber abhängig von den Besonderheiten Ihrer Implementierung könnte dies der Fall sein.

Ich habe gerade einen schnellen Test durchgeführt und festgestellt (mit einem STM32F4 Disco, Coocox, GCC), dass es dem RAM zugewiesen wird, wenn ich keinen Anfangswert für das Array festlege, aber wenn ich einen Anfangswert festlege, weist es es zu Blitzen.
In der Praxis wird dies nicht funktionieren - sie benötigen eine ganze Erase-Unit-Seite, wenn sie sie zur Laufzeit neu schreiben wollen, ohne außergewöhnliche Maßnahmen zu ergreifen, um den umgebenden Programmcode zu erhalten.
@ChrisStratton Das ist haarspalterisch. Weisen Sie einfach einen größeren Platz zu.
Danke, ich habe das implementiert und es scheint gut zu funktionieren. Wie markt betonte, musste ich ihm eine Konstante zuweisen, damit es im Flash-Speicherplatz zugewiesen wurde (andernfalls ging es in den RAM). Auch zur Beobachtung von @ChrisStratton: Eine der LPC8xx-Funktionen besteht darin, 64-Byte-Flash-Blöcke lesen / schreiben zu können
@markt Danke für diesen Tipp. Ich habe eine weitere Frage in Bezug auf diesen Vorschlag. Das Speicherlayout dieses Raums wird durch eine Struktur definiert. Ich möchte mit Standardwerten initialisieren. Ich könnte die Struktur der Standardwerte manuell in Bytes serialisieren und verwenden, = {123,23,433....};aber ich würde es vorziehen, die Struktur irgendwie zu verwenden, um den Code lesbarer und wartbarer zu machen. Ich finde keine Möglichkeit, dies zu tun. Anscheinend können Arrays nur durch ein Zeichenfolgenliteral oder eine Folge von Zahlenliteralen in geschweiften Klammern initialisiert werden. Irgendwelche Vorschläge?
Ich habe eine Lösung gefunden: Verwenden Sie die Struktur anstelle des Byte-Arrays, um Speicherplatz im Flash zuzuweisen. Dies erfordert jedoch eine sorgfältige Erstellung des Stucts mit einer Länge von 64 Bytes. Ich habe das umgangen: die Struktur nicht direkt zu verwenden, sondern in eine Vereinigung mit einem 64-Byte-Array zu packen, um sicherzustellen, dass 64 Bytes zugewiesen werden. Ich denke, das sollte in Ordnung sein, solange meine Struktur 64 Bytes nicht überschreitet.
@jdesbonnet Die Verwendung einer Struktur innerhalb einer Union hätte ich auch getan. Abhängig vom Inhalt der Struktur müssen Sie möglicherweise auch den Qualifizierer __attribute__((packed)) verwenden.