In my application I am using one of the FLASH pages on the STM32F103 to store parameters (similar to the EEPROM emulation discussed in AN2594). Currently, this is implemented similar to the following:
First of all, I'm not sure how to guarantee that the compiler/linker does not attempt to use the same FLASH space that I am using for my data. Second, I think there should be a more readable way to implement this. With the RAISONANCE compiler for the STM8S I was able to use the "at" keyword when declaring variables, so I could do something like this:
Code:
s16 flash_var[10] at 0x0807F800;
flash_var[0] = ram_var[0];
What is the best way to do this with the STM32 family and gcc build tools?
Be carrefull, the STM8 code memory is EEPROM, and the STM32 one is FLASH. So, you have to erase it page by page before writing it.
To separate flash code memory and flash data memory, you can add a section into the linker script. For example, the CircleAPP.ld contains this instructions :
The FLASH section is reserved for the application code, and FLASHB1 for the CircleOS. So, in your case, you can use this type of section to reserve data flash area : FLASHB1 (rw) : ORIGIN = 0x807F800, LENGTH = xK
In the link script you have to add this section declaration ("flash_data_sect " for example) into the SECTIONS paragraph :
/* This is for saving data area */ .flash_data_sect : { *(.flash_data_sect) } >FLASH_B1
In your code you have to declare your variables with the correct attribute : __attribute__ ((section("flash_data_sect"))) __IO uint16_t flash_var[10];
Thank you for your recommendation. However, I am having trouble using a non-default linker script. I tried setting to "...\Ride\Lib\ARM\STM32F10x_COMMON.ld" but then I get an error at the end of the build:
Code:
Building C:\...\<my_project>.rapp
Running: LD
"C:\...\Ride\arm-gcc\bin\arm-none-eabi-gcc.exe" -mcpu=cortex-m3 -mthumb -Wl,-T -Xlinker "C:\...\<my_project>.elf.ld" -u _start -Wl,-static -Wl,--gc-sections -nostartfiles -Wl,-Map -Xlinker "C:\...\<my_project>.map" -Wl,--warn-once
C:\...\<my_project>.elf.ld:55: undefined symbol `_estack' referenced in expression
collect2: ld returned 1 exit status
Build failed
When using the default linker script it works OK; I get the following instead:
Code:
Building C:\...\<my_project>.rapp
Running: LD
"C:\...\Ride\arm-gcc\bin\arm-none-eabi-gcc.exe" -mcpu=cortex-m3 -mthumb -Wl,-T -Xlinker "C:\...\<my_project>.elf.ld" -u _start -Wl,-static -Wl,--gc-sections -nostartfiles -Wl,-Map -Xlinker "C:\...\<my_project>.map" -Wl,--warn-once
"C:\...\Ride\arm-gcc\bin\arm-none-eabi-objcopy.exe" "C:\...\<my_project>.elf" --target=ihex "C:\...\<my_project>.hex"
"C:\...\Ride\Bin\rexrdr.exe" "C:\...\<my_project>.elf.sizetmp" 0 "C:\...\Ride\arm-gcc\bin\arm-none-eabi-size.exe" "C:\...\<my_project>.elf"
"C:\...\Ride\Bin\dwf2xml.exe" "C:\...\<my_project>.dbi" "C:\...\<my_project>-globals.Standard.xml" "C:\...\<my_project>.Standard.xml" ARM
DWF2XML 2.00.01 - Raisonance Dwarf information extractor
Copyright (c) Raisonance S.A.S. 2007-2009. All rights reserved.
Build successful
It seems that this _estack parameter is not getting defined or something...could this be because there is a more specific linker script file that needs to get included somewhere? I noticed that there are some linker scripts generated automatically in my project folder too -- will these still be generated if I do not use the default link script?
Also, I need to ensure that the processor can keep running the critical code while the data area(s) of FLASH are being erased or programmed. Does the CPU stall during any FLASH access during programming or just access to page being erased/programmed? The documentation in PM0042 is vague about this. Do I need to execute from RAM during FLASH erasing/programming to avoid stalling?
PM0042 :
The main Flash memory can be programmed 16 bits at a time. The program operation is started when the CPU writes a half-word into a main Flash memory address with the PG bit of the FLASH_CR register set. Any attempt to write data that are not half-word long will result in a bus error response from the FPEC. $1
"...\Ride\Lib\ARM\STM32F10x_COMMON.ld" is not the script used when you select "use default script". It is one of its sub-scripts.
First, re-select the default script and build the application. Then, edit ".\<application_name>.elf.ld" which has been generated by the IDE during the link. It specifies the input files, and then it includes another script (main script) which was also generated during the link with the "default script" option, and is the one you should specify in the "custom linker script" option. (or a copy of it)
To do what you described in your first post, you should also correct Yves' code like this:
And if you want it to work in CircleOS, there will be other things to change: flash addresses are fixed at load time, not at compile time. you cannot force them and if you try it will either break the OS or just not work.
I hope it helps.
You will find more information on all this in the GettingStartedARM_Ride7 document and in the linker documentation from GCC.
INCLUDE "C:\<my_project_dir>\STM32F103_384K_64K_FLASH.ld"
OUTPUT("C:\<my_project_dir>\<my_project>.elf")
C:\<my_project_dir>\STM32F103_384K_64K_FLASH.ld:
Code:
/*
Default secondary/main linker script for STM32F103_384K_64K
Copyright RAISONANCE S.A.S. 2007-2010
!!! This file is automatically generated by Ride if the default linker script option is active !!!
Do not modify it if the option is set, as it will be erased at every link.
If you need to use your own script please configure your Ride7 project linker options to use your custom linker script
You can take this one as example for wrting your custom linker script
You can use, copy and distribute this file freely, but without any waranty.*/
/* include the common STMxxx sub-script */
INCLUDE "STM32F10x_COMMON.ld"
/* include the memory spaces definitions sub-script */
[b]INCLUDE "STM32F103_384K_64K_DEF.ld"[/b]
/* include the sections management sub-script for FLASH mode */
INCLUDE "sections_FLASH.ld"
STM32F103_384K_64K_DEF.ld:
Code:
/*
Linker subscript for STM32F103 definitions with 384K Flash and 64K RAM
Copyright RAISONANCE 2007-2009
!!! This file is automatically generated by Ride !!!
Do not modify it, as it will be erased at every link.
You can use, copy and distribute this file freely, but without any waranty.
*/
/* Memory Spaces Definitions */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 384K
STARTFLASH (rx) : ORIGIN = 0x0, LENGTH = 0x0
CRPPATCH (r) : ORIGIN = 0x0, LENGTH = 0
FLASHPATCH (r) : ORIGIN = 0x00000000, LENGTH = 0
ENDFLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0
FLASHB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0
EXTMEMB0 (rx) : ORIGIN = 0x00000000, LENGTH = 0
EXTMEMB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0
EXTMEMB2 (rx) : ORIGIN = 0x00000000, LENGTH = 0
EXTMEMB3 (rx) : ORIGIN = 0x00000000, LENGTH = 0
}
/* higher address of the user mode stack */
_estack = 0x20010000;
So I am supposed to modify STM32F103_384K_64K_DEF.ld? Will it be overwritten? Do I choose "<my_project>.elf.ld" in Project Options for linker script?
The file to specify in the options is STM32F103_384K_64K_FLASH.ld.
Then you can modify it and its subscripts (STM32F103_384K_64K_DEF.ld in your case).
These files will be overwritten only if you link using the "use default script" option. So if you deselect the option it's OK, but it's better to make copies, in case you select the option by accident.
Can I also use __attribute__ ((section (".xxxxx"))) to locate functions? For example, I would like to load a function into RAM for running a customized bootloader.
OK, thanks again. I was able to answer my own question this time. When the "Generate Long Calls" option is enabled in the RIDE7 project options the project builds OK. (No changes to linker script files are needed since .data section already includes any sections named ".RAMtext") The startup code copies the function from FLASH into RAM before calling main().
And how do you force fixed data on a specific address? I mean something like a constant - so that I have 00 at 0x08013000. My idea doesn't work, even though it compiles:
I tested your code and it works. What do you mean by "it doesn't work" ? Is the address false or is it the value ? Are you sure that the section FLASHB1 is not already used ?
Yes, I also have tested this code and also want to say that its working really very fine. As I knew only little bit about that but after watching this I came to know proper about that. I also want to say that it also increase my knowledge about that.