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 FLASH es lo suficientemente rápida?
En segundo lugar, cómo poner 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.
La respuesta corta es declarar su variable con la const
palabra clave. Si su MCU realmente recuerda el valor de su const
variable (es decir, su cálculo de seno realmente funciona), tiene que 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 dependen de MCU y le dicen al enlazador dónde poner qué. Por lo general, este script lo proporciona el IDE, pero puede escribir el suyo propio. En mi configuración de STM32F4, mi secuencia de comandos del enlazador 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 estará presente algo similar a esto:
.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 .text
secciones (así es como el compilador llama a la sección de código) y .rodata
las secciones (así es como el compilador llama a las const
variables) deben colocarse en la sección flash.
Como se sugirió anteriormente, el .map
archivo es la forma principal en que puede verificar qué coloca el enlazador y dónde. 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 almacenado y compararlo con el mapa de memoria especificado en la hoja de datos de MCU.
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 sobre una tabla de búsqueda de seno/coseno. Esos valores están fijados por matemáticas y no necesitan cambiar sobre la marcha.
Seguramente la documentación del lenguaje 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 enlazador, o posiblemente pasando información adicional al enlazador por separado.
En cuanto a cómo implementar una búsqueda de seno y coseno, consulte estas respuestas anteriores:
https://electronics.stackexchange.com/a/60819/4512
https://electronics.stackexchange.com/a/16516/4512
para tener datos puestos en flash declararlo como const
const unsigned int lut[]= { 0x1234, 0xab, 0xcd, 0xefa1123, 0x1122334, ...
Es posible que su secuencia de comandos de vinculación deba tener una entrada, depende del estilo y la antigüedad de su cadena de herramientas, podría ir en .text o .rodata u otro dependiendo nuevamente de su cadena de herramientas. y luego pondrías esa sección en flash.
usuario2412542
olin lathrop
joe hass
Super gato
const
modificador se asignarán en una sección de enlace separada de las que no lo tienen; normalmente habrá una opción para obligar a algunas secciones del enlazador a codificar espacio y, en muchos casos, las secciones que almacenanconst
variables se colocarán allí automáticamente. Creo que los compiladores ARM suelen tener ese comportamiento predeterminado, por lo que unaconst
directiva debería ser suficiente para lo que necesita.Barmaley