Cómo almacenar variables en la memoria FLASH

7

Estoy trabajando con una placa de evaluación STM32 de STMicro que incluye un procesador ARM Cortex-M4. Necesito una LUT para coseno y seno (variables de solo lectura). Necesito administrar mi memoria RAM, por lo tanto, quiero almacenar estos LUT en la memoria flash.

Primero: ¿es mejor crear un cálculo interpolado de coseno / seno o la lectura de FLASH es lo suficientemente rápida?

En segundo lugar, cómo colocar las variables en la memoria FLASH. ST proporciona algunos ejemplos, pero tal vez, para mi problema, solo necesito declarar las variables LUT como constantes estáticas y será como un código.

    
pregunta user2412542

3 respuestas

12

La respuesta corta es declarar su variable con la palabra clave const . Si su MCU realmente recuerda el valor de su variable const (es decir, su cálculo sinusoidal realmente funciona), debe almacenarse en la memoria flash, de lo contrario se perdería en el primer reinicio después de la programación.

La respuesta larga tiene que ver con el script del enlazador. Estos scripts son dependientes de MCU y le indican al vinculador dónde colocar qué. Por lo general, este script lo proporciona el IDE, pero puede escribir el suyo propio. En mi configuración STM32F4, mi script de vinculador comienza con una declaración de este tipo:

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
}

Dice que el flash comienza en la dirección 0x08000000 y la RAM en la dirección 0x20000000 . Estas direcciones se pueden encontrar en la hoja de datos donde se describe el mapa de memoria. El resto del guión puede involucrarse, pero en algún momento habrá algo en este sentido:

.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

Esto dice que todas las secciones .text (así es como el compilador llama a la sección de código) y las secciones .rodata (así es como el compilador llama a las variables const ) deben colocarse en la sección flash.

Como se sugirió anteriormente, el archivo .map es la forma principal en que puede verificar qué es lo que el vinculador coloca donde. Le dices al enlazador que lo genere usando esta opción:

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

Puede buscar su símbolo dentro de este archivo de mapa, ver en qué dirección se ha guardado y verificarlo con el mapa de memoria especificado en la hoja de datos de MCU.

    
respondido por el abey
4

No, no puede poner variables en la memoria de solo lectura. Sin embargo, puede poner constantes allí, que es todo lo que necesita, ya que está preguntando por una tabla de búsqueda de seno / coseno. Esos valores están fijados por matemáticas y no necesitan cambiarse sobre la marcha.

Sin duda, la documentación de idioma describe cómo forzar una matriz de constantes en la memoria del programa. Esto generalmente se hace con alguna palabra clave, o especificando atributos para una sección del vinculador, o posiblemente mediante información adicional que se pasa al vinculador por separado.

En cuanto a cómo implementar una búsqueda de seno y coseno, vea estas respuestas anteriores:

enlace
enlace

    
respondido por el Olin Lathrop
4

para que los datos se pongan en flash, declararlos como const

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

su script de vinculador puede necesitar una entrada, depende del sabor y la antigüedad de su cadena de herramientas, podría ir en .text o .rodata u otro dependiendo de su cadena de herramientas. y luego pondrías esa sección en flash.

    
respondido por el old_timer

Lea otras preguntas en las etiquetas