1

I am making a code using CubeIDE for a STM32F302K8UX and I need a variable to be persistent across resets.

One way I have seen ppl doing it is by making a variable that is saved directly on flash memory (at least this is what I understood of it). I got it from @Stephan answer on this post: How to write/read to FLASH on STM32F4, Cortex M4

So I tried following it with a few modifications. On the MEMORY section of STM32F302K8UX_FLASH.ld:

/* Memories definition */
MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 16K
  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 63K // subtracted 1kb from original value (64K)
  DATA (rx)       : ORIGIN = 0x0800FC00,   LENGTH = 1K // created new section at the end of previous (0x8000000 + (63 * 1024))
}

Then on the SECTIONS section, I added this at the start:

SECTIONS
{
  .user_data (NOLOAD):
  {
    . = ALIGN(4);
    _user_data_start = .; /* create a global symbol at user_data start */
     KEEP(*(.user_data))
    . = ALIGN(4);
    _user_data_end = .;  /* create a global symbol at user_data end */
  } >DATA

...

Now on my main code I declared the variable as such:

uint8_t persistent_config __attribute__ ((section(".user_data")));

But I get a linker error that I cannot really understand:

14:03:41 **** Incremental Build of configuration Debug for project sonicPlayer ****
make -j12 all 
arm-none-eabi-gcc "../Core/Src/main.c" -mcpu=cortex-m4 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F302x8 -DDEBUG -c -I../Core/Inc -I../Drivers/STM32F3xx_HAL_Driver/Inc -I../Drivers/STM32F3xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F3xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Core/Src/main.d" -MT"Core/Src/main.o" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "Core/Src/main.o"
arm-none-eabi-gcc -o "sonicPlayer.elf" @"objects.list"   -mcpu=cortex-m4 -T"C:\Users\werne\OwnCloud\Documents\Arquivos\Drive\Projetos\SonicScrewDriver\sonicPlayer\STM32F302K8UX_FLASH.ld" --specs=nosys.specs -Wl,-Map="sonicPlayer.map" -Wl,--gc-sections -static --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -Wl,--start-group -lc -lm -Wl,--end-group
c:\st\stm32cubeide_1.4.0\stm32cubeide\plugins\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.4.0.202007081208\tools\arm-none-eabi\bin\ld.exe:C:\Users\werne\OwnCloud\Documents\Arquivos\Drive\Projetos\SonicScrewDriver\sonicPlayer\STM32F302K8UX_FLASH.ld:40: syntax error
collect2.exe: error: ld returned 1 exit status
make: *** [makefile:50: sonicPlayer.elf] Error 1
"make -j12 all" terminated with exit code 2. Build might be incomplete.

14:03:42 Build Failed. 2 errors, 0 warnings. (took 598ms)
Description Resource    Path    Location    Type
make: *** [makefile:50: sonicPlayer.elf] Error 1    sonicPlayer         C/C++ Problem
make: *** No rule to make target 'clean'.  Stop.    Firmware            C/C++ Problem
syntax error    sonicPlayer     line 40, external location: c:\st\stm32cubeide_1.4.0\stm32cubeide\plugins\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.4.0.202007081208\tools\arm-none-eabi\bin\ld.exe:C:\Users\werne\OwnCloud\Documents\Arquivos\Drive\Projetos\SonicScrewDriver\sonicPlayer\STM32F302K8UX_FLASH.ld C/C++ Problem

How do I fix this?

The error description is pretty cryptic to me and I could find anything on google.

If you could explain what is going on here it would be nice too, I'm. not very experienced in this sort of too specific thing.

edit I can see a syntax error, but no clue where or what.

edit 2: solution: To fix the error code, I replaced // comments by /* */ as suggested by @KamilCuk However the code was not complete

With a bit more research based on all the other answers, I got this link: https://os.mbed.com/users/olympux/code/eeprom_flash/ So I scrapped all the above, added both .h and .c to my project, replaced #include "mbed.h" for #include "stm32f3xx_hal.h"

then I changed eeprom_flash.c first function

#include "eeprom_flash.h"

FLASH_EraseInitTypeDef eraseInit = {
    FLASH_TYPEERASE_PAGES,
    EEPROM_START_ADDRESS,    // Memory location (beggining of page)
    1                        // Number of pages to erase
};
uint32_t pageError;

/*
 * Must call this first to enable writing
 */
void enableEEPROMWriting() {
    HAL_StatusTypeDef status = HAL_FLASH_Unlock();
    HAL_FLASHEx_Erase(&eraseInit, &pageError);
}

That was it! to write to flash memory:

                    enableEEPROMWriting();
                    writeEEPROMHalfWord(0x0, var);
                    disableEEPROMWriting();

and to read

uint16_t var = readEEPROMHalfWord(0x0);
  • 3
    Regardless of the reason for the error, are you sure that the flash allows you to erase from the same bank where the code is executing? That is usually not the case. So you'll need a part with multiple physical banks, or preferably, a part with dedicated eeprom/data flash. Some STM32L got that. – Lundin Mar 08 '21 at 14:38
  • 1
    `STM32F302K8UX_FLASH.ld:40: syntax error` – KamilCuk Mar 08 '21 at 14:43
  • The approach should be doable. There is an [application note](https://www.st.com/resource/en/application_note/dm00049071-eeprom-emulation-in-stm32f30xstm32f31xstm32f37xstm32f38x-microcontrollers-stmicroelectronics.pdf) by STM implementing a sophisticated approach to minimize flash wear. And they also provide the source code including a working .ld file – Codo Mar 08 '21 at 15:14
  • So what's on line 40 of your load script then? – Codo Mar 08 '21 at 15:18
  • on line 40 is this `FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 63K // subtracted 1kb from original value (64K)` Did i do something wrong there? i mean its pretty much the same as the original, i just changed 64 to 63 – Werner Thomassen Andrade Mar 08 '21 at 15:23
  • 1
    Remove the `//` comment. Maybe linker does not support `//` comments, only `/* */` – KamilCuk Mar 08 '21 at 15:42
  • That got rid of the error! @KamilCuk. The code didn't work tho, there must be more to it. When I try to access it variable either by reading or writing, It breaks the code. I Will keep on searching for how to make it work and post the solution here – Werner Thomassen Andrade Mar 08 '21 at 16:46
  • 2
    *"It breaks the code"* – does it crash? It sounds as if you're trying to write like so: *persistent_config = 42;*. That won't work. You have to erase an entire flash block. Then you can write to it using the dedicated flash functions. And before writing the next time, you have to erase it again. – Codo Mar 08 '21 at 20:22
  • Yeah all that was missing, didn't know about that. found some help and edited the post. Thx all – Werner Thomassen Andrade Mar 08 '21 at 20:55

0 Answers0