Skip to main content
Grant Bt
Associate III
September 28, 2021
Question

Locate Constant Data in Flash at Fixed Address

  • September 28, 2021
  • 7 replies
  • 4862 views

Yet another question on locating data, this time fixed in flash. I want to place some main application attributes at a fixed flash location so that my bootloader can learn about the installed app. I have had partial success. (For now this is for an STM32F103, but I'm just learning so that's not for sure.)

With STM32CubeIde I have this in my main.c application code:

uint32_t const Version __attribute__((section(".AppInfo"))) = 0x12345678UL;
uint32_t const Features __attribute__((section(".AppInfo"))) = 0xDEADC0DEUL;

And in the .ld file I have added this (between .isr_vector (0x08002000) and .text:

.AppInfo 0X08003000 : 
 {
 . = ALIGN(4);
 KEEP(*(.AppInfo))
 . = ALIGN(4);
 } >FLASH

Now, while this works (I checked the .map file), I get a giant hole in my Flash usage between the vectors and where my AppInfo goes. Then of course the .text begins after.

  

There is no way to have the linker mix this into the .text area? I would like to have control over where the AppInfo goes, so any suggestions? Should I just pick the next boundary after the ISR Vectors and hope that table never grows? (seems like not a brilliant idea!)

This topic has been closed for replies.

7 replies

Grant Bt
Grant BtAuthor
Associate III
September 28, 2021

For comparison, here is what I am doing in Keil (I build in both for now).

uint32_t const Version __attribute__((at(0X08003000UL))) = 0x12345678UL; // Compiler v5
uint32_t const Features __attribute__((at(0X08003004UL))) = 0xDEADC0DEUL; // Compiler v5

And that's all I've had to do (surprisingly).

Tesla DeLorean
Guru
September 28, 2021

I'd make it a structure to commit the ordering, content, and __attribute__ it into the carved out AppInfo section.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
TDK
September 28, 2021

The GCC Linker, which is used by STM32CubeIDE, has no way of doing this in a similar fashion to Keil.

The vector table length won't change unless you change chips. Seems like a fine place. It won't grow by a lot, in any case, so having a bit of buffer for the vector table and placing your structure right after that seems like a fine solution.

Another solution is to place things like this in unused spaces within the vector table. Technically not allowed, but it works. Would also be chip dependent.

"If you feel a post has answered your question, please click ""Accept as Solution""."
alister
Senior III
September 29, 2021

>There is no way to have the linker mix this into the .text area? I would like to have control over where the AppInfo goes, so any suggestions? Should I just pick the next boundary after the ISR Vectors and hope that table never grows? (seems like not a brilliant idea!)

The data is for the boot code to interrogate. You could put it anywhere. But you want the boot to find it at some fixed start address and you want it to be simple.

Placing it in the middle of the .text section is not sensible because of its unnecessary impacts.

You could make it the first input section of the .text section, if you want to. But placing it immediately following the vector table is more sensible as it is better to read and to administer.

Putting it in the vector table is sensible too, so long as it is after any vectors you'd use.

Its length may change with no trouble. Whether that's because it is variable length and the boot code would know how to parse it, or that's because you may need to add details in some backwards compatible fashion in future, the linking takes care of that.

Your C definition

const char myData[] __attribute__ ((section ("MY_SECTION"))) = "the data";

Your linker command file:

<snip>
 
SECTIONS
{
 .isr_vector :
 {
 KEEP(*(.isr_vector))
 } >APP_VECTOR
 
 MY_SECTION :
 {
 KEEP(*(MY_SECTION))
 } >APP_ROM
 
 .text : ALIGN(4)
 {
 *(.text*)
 
 <snip>
 
 } >APP_ROM
 
<snip>

https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-section-variable-attribute

https://sourceware.org/binutils/docs/ld/MEMORY.html#MEMORY

https://sourceware.org/binutils/docs/ld/SECTIONS.html#SECTIONS

Grant Bt
Grant BtAuthor
Associate III
September 29, 2021

Thanks gang! As mentioned I need to establish the address for all time, so I will place it after the vectors as recommended. I will also allow (waste) a bit of space between the vectors and my section in case the vector table size changes due to a micro part change. It may be that F103 is not suitable (I'm only using it due to the wealth of educational materials available). I may switch to F4 or newer G0 or L0 part or other.

If I end up using the Keil tools, then this question is moot.

Piranha
Principal III
September 29, 2021

You can combine both methods. Put your constant data immediately after the vector table and put an address to that location in an unused slot of vector table. There are 5 unused slots between the first 16, which will be the same for almost all Cortex-M CPUs. Linker script can do all of it automatically.

Grant Bt
Grant BtAuthor
Associate III
September 30, 2021

This is a very interesting idea! I assume you mean the "Reserved" ones from the table below (found in startup_stm32f103xb.s for example)? I would prefer it said "Unused" rather than "Reserved" though. :smiling_face_with_smiling_eyes: Alternatively one could choose a vector in the silicon vendor section after, but I'm not experienced enough to know how stable those are from variant to variant.

; Vector Table Mapped to Address 0 at Reset
 AREA RESET, DATA, READONLY
 EXPORT __Vectors
 EXPORT __Vectors_End
 EXPORT __Vectors_Size
 
__Vectors DCD __initial_sp ; Top of Stack
 DCD Reset_Handler ; Reset Handler
 DCD NMI_Handler ; NMI Handler
 DCD HardFault_Handler ; Hard Fault Handler
 DCD MemManage_Handler ; MPU Fault Handler
 DCD BusFault_Handler ; Bus Fault Handler
 DCD UsageFault_Handler ; Usage Fault Handler
 DCD 0 ; Reserved
 DCD 0 ; Reserved
 DCD 0 ; Reserved
 DCD 0 ; Reserved
 DCD SVC_Handler ; SVCall Handler
 DCD DebugMon_Handler ; Debug Monitor Handler
 DCD 0 ; Reserved
 DCD PendSV_Handler ; PendSV Handler
 DCD SysTick_Handler ; SysTick Handler
 
 ; External Interrupts
 DCD WWDG_IRQHandler ; Window Watchdog
 DCD PVD_IRQHandler ; PVD through EXTI Line detect
 DCD TAMPER_IRQHandler ; Tamper
 DCD RTC_IRQHandler ; RTC
 DCD FLASH_IRQHandler ; Flash
 DCD RCC_IRQHandler ; RCC
 DCD EXTI0_IRQHandler ; EXTI Line 0