lectura desde uint32_t en flash es cero STM32F1

0

Estoy trabajando en un programa STM32F103RBT6 y en algún momento necesito almacenar valores en el FLASH.

Escribir en Flash funciona como un encanto, si analizo a través de la memoria de mi microcontrolador, veo que los datos se han escrito en el lugar esperado.

Sin embargo, si intento leer los datos que almacené en una palabra (uint32_t), leo 0.

__attribute__((__section__(".nb_Frames"))) const uint32_t nb_Frames_Flash;
uint8_t CAN_nb_Frames_Tx_cc = 0;

[...]

CAN_nb_Frames_Tx_cc = (nb_Frames_Flash & 0x000000FF); 

Por ejemplo, aquí quiero obtener el byte bajo del valor almacenado en nb_Frames_Flash (0x01 por ejemplo), pero CAN_nb_Frames_Tx_cc permanece = 0.

Estoy seguro de que nb_Frames_Flash! = 0 porque si paso por estas líneas paso a paso gracias al depurador, puedo ver que nb_Frames_Flash = 0x00010101 (que es el valor que escribí en Flash). La asignación se siente como si no estuviera pasando ...

He intentado cambiar la asignación: CAN_nb_Frames_Tx_cc = (nb_Frames_Flash & 0x000000FF); agregando conversiones, cambiando la definición de CAN_nb_Frames_Tx_cc (uint32_t por ejemplo), pasando por una variable intermedia ... Pero simplemente no funcionará ...

Estoy realmente atascado aquí y no sé por qué no funciona correctamente.

Lo que me vuelve loco es que leer en Flash funciona completamente para las estructuras. Almacené estructuras en Flash, y no tengo ningún problema para leerlas y almacenarlas en una variable de RAM ...

De antemano, ¡gracias por su ayuda!

EDITAR: Aquí está mi script de vinculador:

{
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 20K
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 128K - 5K
Erases (RW)     : ORIGIN = 0x801EC00, LENGTH = 4
Frames (RW)     : ORIGIN = 0x801EC04, LENGTH = 4
TRAMESTx (RW)   : ORIGIN = 0x801EC08, LENGTH = 1400
TRAMESRx (RW)   : ORIGIN = 0x801F180, LENGTH = 1800
TRAMESADC(RW)   : ORIGIN = 0x801F888, LENGTH = 800
TRAMESOP (RW)   : ORIGIN = 0x801FBA8, LENGTH = 800
}

/* Define output sections */
SECTIONS
{
  /* The startup code goes first into FLASH */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH

 .nb_Erases : 
 {
    . = ALIGN(4);

    *(.nb_Erases)

    . = ALIGN(4);
    } > Erases

 .nb_Frames : 
 {
    . = ALIGN(4);

    *(.nb_Frames)

    . = ALIGN(4);
    } > Frames

 .user_TramesTx : 
 {
    . = ALIGN(4);

    *(.user_TramesTx)

    . = ALIGN(4);
    } > TRAMESTx

 .user_TramesRx : 
 {
    . = ALIGN(4);

    *(.user_TramesRx)

    . = ALIGN(4);
    } > TRAMESRx

 .user_TramesADC : 
 {
    . = ALIGN(4);

    *(.user_TramesADC)

    . = ALIGN(4);
    } > TRAMESADC

 .user_TramesOp : 
 {
    . = ALIGN(4);

    *(.user_TramesOp)

    . = ALIGN(4);
    } > TRAMESOP
    
pregunta B.Clergue

1 respuesta

3

Necesitas hacer nb_Frames_Flash volatile.

El compilador no ve cambios en nb_Frames_Flash en ningún lugar del código. Por lo tanto, implica que es 0. Como resultado, no se insertará ningún código para la asignación de CAN_nb_Frames_Tx_cc . (verifique el ensamblador, faltará)

__attribute__((__section__(".nb_Frames"))) volatile const uint32_t nb_Frames_Flash;

La palabra clave volatile indica explícitamente al compilador que realice una lectura por cada uso de nb_Frames_Flash .

    
respondido por el Jeroen3

Lea otras preguntas en las etiquetas