So speichern Sie Variablen im FLASH-Speicher

7

Ich arbeite mit einer STM32-Evaluierungskarte von STMicro, die einen ARM Cortex-M4-Prozessor enthält. Ich benötige eine LUT für Cosinus und Sinus (schreibgeschützte Variablen). Ich muss meinen RAM-Speicher verwalten, daher möchte ich diese LUT im Flash-Speicher speichern.

Erstens: Ist es besser, eine Interpolationsberechnung für Cosinus / Sinus zu erstellen, oder ist der FLASH-Messwert schnell genug?

Zweitens, wie man die Variablen in den FLASH-Speicher legt. ST bietet einige Beispiele, aber vielleicht muss ich für mein Problem nur die LUT-Variablen als statische Konstante deklarieren und es wird wie Code sein?

user2412542
quelle

Antworten:

12

Die kurze Antwort besteht darin, Ihre Variable mit dem constSchlüsselwort zu deklarieren . Wenn sich Ihre MCU tatsächlich an den Wert Ihrer constVariablen erinnert (dh Ihre Sinusberechnung funktioniert tatsächlich), muss sie so ziemlich im Flash-Speicher gespeichert werden, da sie sonst beim ersten Neustart nach der Programmierung verloren geht.

Die lange Antwort hat mit Linker-Skript zu tun. Diese Skripte sind MCU-abhängig und teilen dem Linker mit, wo was abgelegt werden soll. Normalerweise wird dieses Skript von der IDE bereitgestellt, aber Sie können Ihr eigenes schreiben. In meinem STM32F4-Setup beginnt mein Linker-Skript mit einer solchen Anweisung:

MEMORY
{
    FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 1024K
    RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 128K
    CCMRAM (xrw)    : ORIGIN = 0x10000000, LENGTH = 64K
    MEMORY_B1 (rx)  : ORIGIN = 0x60000000, LENGTH = 0K
}

Es heißt, dass der Flash an der Adresse 0x08000000und der RAM an der Adresse beginnt 0x20000000. Diese Adressen finden Sie im Datenblatt, in dem die Speicherzuordnung beschrieben ist. Der Rest des Skripts kann sich beteiligen, aber irgendwann wird etwas in dieser Richtung vorhanden sein:

.text :
{
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
} >FLASH

Dies besagt, dass alle .textAbschnitte (so ruft der Compiler den Codeabschnitt auf) und .rodataAbschnitte (so ruft der Compiler constVariablen auf) in den Flash-Abschnitt eingefügt werden sollen.

Wie oben vorgeschlagen, ist die .mapDatei die primäre Methode, mit der Sie überprüfen können, was der Linker wo ablegt. Sie weisen den Linker an, ihn mit dieser Option zu generieren:

arm-eabi-gcc -Wl,-Map=my_program.map ...

Sie können in dieser Zuordnungsdatei nach Ihrer Symbole suchen, sehen, an welcher Adresse sie gespeichert wurde, und dies anhand der im MCU-Datenblatt angegebenen Speicherzuordnung überprüfen.

abey
quelle
4

Nein, Sie können keine Variablen in den Nur-Lese-Speicher einfügen. Sie können dort jedoch Konstanten einfügen, was alles ist, was Sie benötigen, da Sie nach einer Sinus / Cosinus-Nachschlagetabelle fragen. Diese Werte werden durch Mathematik festgelegt und müssen nicht im laufenden Betrieb geändert werden.

Sicherlich beschreibt die Sprachdokumentation, wie ein Array von Konstanten in den Programmspeicher gezwungen wird. Dies erfolgt normalerweise mit einem Schlüsselwort oder durch Angabe von Attributen für einen Linkerabschnitt oder möglicherweise durch zusätzliche Informationen, die separat an den Linker übergeben werden.

Informationen zum Implementieren einer Sinus- und Cosinus-Suche finden Sie in den vorherigen Antworten:

https://electronics.stackexchange.com/a/60819/4512
https://electronics.stackexchange.com/a/16516/4512

Olin Lathrop
quelle
Die Verwendung des Schlüsselworts const mit der Sprache C scheint die Daten in den Flash- / Programmspeicher zu stellen. Wie kann ich mit der IDE (ich verwende CooCox mit ARM GNU gcc compiler) überprüfen, ob diese Variablen wirklich dem FLASH-Speicher zugeordnet sind? Thks.
user2412542
@user: Wahrscheinlich, obwohl dies theoretisch nur dem Compiler mitteilt, dass Sie nicht beabsichtigen, den Wert zu ändern. Es gibt keine Möglichkeit, sicher zu wissen, ob es sich um ein Compiler / Linker-Toolset handelt. Sie müssen noch die Dokumentation lesen, die Sie natürlich trotzdem sollten. Denken Sie daran, dass das OP nie gesagt hat, welche Sprache er verwendet.
Olin Lathrop
@ user2412542 Sie können dem Befehl gcc eine Option hinzufügen und eine Speicherzuordnungsdatei generieren lassen, oder Sie können den Befehl objdump verwenden, um zu sehen, wo verschiedene Dinge im Speicher abgelegt werden.
Joe Hass
Bei vielen Compilern werden Variablen mit einem constModifikator in einem anderen Linkerabschnitt als ohne Variablen zugewiesen. In der Regel besteht die Möglichkeit, einige Linkerabschnitte in den Codebereich zu zwingen. In vielen Fällen werden die Abschnitte, in denen constVariablen gespeichert werden, automatisch dort platziert. Ich glaube, dass ARM-Compiler normalerweise ein solches Standardverhalten haben, daher sollte eine constDirektive für das ausreichen, was Sie benötigen.
Supercat
Sie können Ihren FLASH-Speicher zum Speichern von Variablen verwenden. Nicht sofort einsatzbereit, es handelt sich jedoch um Code. Hier ist ein gutes Beispiel, eine andere MCU, aber dieselbe Cortex-Familie. os.mbed.com/users/olympux/code/eeprom_flash
Barmaley
4

Um Daten in Flash zu speichern, deklarieren Sie sie als const

const unsigned int lut [] = {0x1234, 0xab, 0xcd, 0xefa1123, 0x1122334, ...

Ihr Linker-Skript muss möglicherweise einen Eintrag haben. Dies hängt vom Geschmack und Alter Ihrer Toolchain ab. Je nach Toolchain kann es auch in .text oder .rodata oder anderen Formaten enthalten sein. und Sie würden dann diesen Abschnitt in Flash setzen.

Oldtimer
quelle