0
\$\begingroup\$

I am working on an STM32F103RBT6 program and at some point I need to store values in the FLASH.

Writing in Flash is working as a charm, if I parse through the memory of my microcontroller, I see that the data has been written at the expected spot.

However, if I try to read the data I stored on a word (uint32_t), I read 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); 

For example here, I want to get the low byte of the value stored in nb_Frames_Flash (0x01 for example), but CAN_nb_Frames_Tx_cc stays = 0.

I am sure that nb_Frames_Flash != 0 because If I go through these lines step by step thanks to the debugger, I can see that nb_Frames_Flash = 0x00010101 (which is the value I wrote in the Flash). The assignement just feels like it's not going through ...

I have tried to change the assignement : CAN_nb_Frames_Tx_cc = (nb_Frames_Flash & 0x000000FF); by adding casts, changing the definition of CAN_nb_Frames_Tx_cc (uint32_t for instance), going through an intermediate variable ... But it just won't work ...

I am really stuck here and I don't know why it is not properly working.

The thing that makes me go nuts is that reading in Flash is completely working for structures. I stored structures in Flash, and I have no issue to read them and store them in a RAM variable ...

In advance, thank you for your help !

EDIT : Here is my linker script :

{
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
\$\endgroup\$
  • \$\begingroup\$ Publish your linker script. The section .nb_Frames can be placed at a wrong address, eg. RAM, bss or in a black-hole. You could also generate a map file to see the exact placement. \$\endgroup\$ – filo Jul 25 '18 at 8:51
  • \$\begingroup\$ I added it, but I am pretty confident about it being correct since I can write in flash without any issue. But feel free to say if anything is wrong ! \$\endgroup\$ – B.Clergue Jul 25 '18 at 9:39
3
\$\begingroup\$

You need to make nb_Frames_Flash volatile.

The compiler sees no change to nb_Frames_Flash anywhere in the code. Thus it implies it is 0. Resulting no code will be inserted for the assignement of CAN_nb_Frames_Tx_cc. (check the assembler, it will be missing)

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

The volatile keyword explicitly instructs to compiler to perform a read for every use of nb_Frames_Flash.

\$\endgroup\$
  • \$\begingroup\$ It is working ! Thank you so much, I cannot upvote your answer but it is perfect ! However, I am still interested in understanding why not putting volatile in front of the structure declaration doesn't prevent the compiler from reading it ? \$\endgroup\$ – B.Clergue Jul 25 '18 at 9:44
  • \$\begingroup\$ @B.Clergue The compiler optimizations. Try it without -O0. \$\endgroup\$ – Jeroen3 Jul 25 '18 at 19:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.