cancel
Showing results for 
Search instead for 
Did you mean: 

Locate Constant Data in Flash at Fixed Address

Grant Bt
Senior

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!)

7 REPLIES 7
Grant Bt
Senior

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).

TDK
Guru

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".

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
Up vote any posts that you find helpful, it shows what's working..
alister
Lead

>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
Senior

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
Chief II

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.

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