Die kurze Antwort besteht darin, Ihre Variable mit dem const
Schlüsselwort zu deklarieren . Wenn sich Ihre MCU tatsächlich an den Wert Ihrer const
Variablen 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 0x08000000
und 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 .text
Abschnitte (so ruft der Compiler den Codeabschnitt auf) und .rodata
Abschnitte (so ruft der Compiler const
Variablen auf) in den Flash-Abschnitt eingefügt werden sollen.
Wie oben vorgeschlagen, ist die .map
Datei 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.
const
Modifikator 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 denenconst
Variablen gespeichert werden, automatisch dort platziert. Ich glaube, dass ARM-Compiler normalerweise ein solches Standardverhalten haben, daher sollte eineconst
Direktive für das ausreichen, was Sie benötigen.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.
quelle