cancel
Showing results for 
Search instead for 
Did you mean: 

Using STM32 FLASH memory

RrW1
Associate III

I am learning on using the STM32L431CC FLASH memory to store data after the microcontroller loses power. From compiling through Keil, I get:

Program Size: Code=34316 RO-data=1228 RW-data=364 ZI-data=1908

From the above, Is it correct that only 35Kbytes of FLASH are being used?

FLASH/ROM = Code + RO-data = 34316 + 1228 = 35544 bytes

Since the STM32L431CC uses Pages instead of Sectors for its FLASH, this is the code that I used to write into its FLASH memory:

HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR);
HAL_FLASHEx_Erase(&lFlashPage, &PageErrorStatus);
HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, 0x0803F800, *pData1);
HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, 0x0803F800 + 0x08, *pData2);
HAL_FLASH_Lock();

And the FLASH configuration that I used:

FLASH_EraseInitTypeDef lFlashPage;
lFlashPage.TypeErase = FLASH_TYPEERASE_PAGES;
lFlashPage.Banks = FLASH_BANK_1;
lFlashPage.Page = 127;
lFlashPage.NbPages = 1;

If the whole program only uses 35Kbytes of FLASH memory, does that also mean that the program only used FLASH Page 0 up to FLASH Page 17 (total of 36KBytes with 2KByte per page), and that it is safe to use FLASH page 127? The FLASH rewriting should not mess up the program itself would it? I should also note that I have not tried changing the Scatter File in Keil and don't know if I have to if the program won't touch Page 127 at all.

I also have a question regarding erasing the FLASH page. Would calling the function:

HAL_FLASHEx_Erase(&lFlashPage, &PageErrorStatus);

erase FLASH page 127 into all 0xFFFFFFFF? I did notice that at startup, if I did not write anything to FLASH, the data stored in the memory are 0xFFFFFFFF per block.

Any help would be appreciated. Thank you!

1 ACCEPTED SOLUTION

Accepted Solutions
Piranha
Chief II

The RW-data section takes the space in both - RAM and FLASH - because it has to be initialized to non-zero values and those initialization values are stored in FLASH memory. Therefore:

FLASH/ROM = Code + RO-data + RW-data = 34316 + 1228 + 364 = 35908 bytes

> Why do people usually change the linker/scatter file when playing with the FLASH memory?

Because then compiler will show "code/data doesn't fit in FLASH memory" error in case the code+data reaches the forbidden addresses.

View solution in original post

9 REPLIES 9
DDong.2
Associate II

From the above, Is it correct that only 35Kbytes of FLASH are being used?

YES

 the program only used FLASH Page 0 up to FLASH Page 17 (total of 36KBytes with 2KByte per page), and that it is safe to use FLASH page 127? 

YES. The keil only flash your code to the flash. It didn't know if you use page 127​. Your code did it. Unless your code size extend to page 127 otherwise you can use page 127 as you want. You can notice all this flash memory is using start from 127. It makes sure the memeory will not mess with your code.

Thanks for the answer! So, when is it required to change the Scatter file in Keil to allocate part of the FLASH for our own uses? Why do people usually change the linker/scatter file when playing with the FLASH memory?

I have no idea. I have never change the ​Scatter file.

Piranha
Chief II

The RW-data section takes the space in both - RAM and FLASH - because it has to be initialized to non-zero values and those initialization values are stored in FLASH memory. Therefore:

FLASH/ROM = Code + RO-data + RW-data = 34316 + 1228 + 364 = 35908 bytes

> Why do people usually change the linker/scatter file when playing with the FLASH memory?

Because then compiler will show "code/data doesn't fit in FLASH memory" error in case the code+data reaches the forbidden addresses.

Thanks for clarifying that the FLASH/ROM takes Code + RO-data + RW-data.

In the example you gave, if the code/data exceeds the amount of FLASH available, wouldn't the program crash regardless of the changes made in the scatter file?

In your case you have 128 * 2 KB = 256 KB flash. If you reserve the last sector for user data section, then it is wise to reduce the available flash for compiler to 254 KB, because otherwise (someday) the compiler will happily fill the firmware code/data up to that last sector. It still doesn't exceed 256 KB and technically everything is fine, but the firmware now collides with your user data section.

RrW1
Associate III

Thanks for the explanation! If that is the case, if I were to reduce the available FLASH for compiler in my case, would it be enough if I just leave the IROM1 'Start' to 0x0800_0000 and modify the IROM1 'Size' to 0x0003_F800 in Keil's Target Dialog configuration:

0693W000006EQFxQAO.pngand leaving 'Use Memory Layout from Target Dialog' option checked under Linker Settings?

0693W000006EQG7QAO.png 

Or would it still be better to just modify the scatter file immediately after unchecking the option above?

I'm not very familiar with uVision, but it looks like it is the right and sufficient thing to do in this case.

By the way, if you need that data to be resilient against power failures during rewrite, consider using two pages of flash and swapping those on save or when full. That way there will always be at least one correct page with data. You just have to sort out the latest valid page with some counter and checksum.

RrW1
Associate III

Thanks for the suggestion Piranha! I'll try to implement that.