cancel
Showing results for 
Search instead for 
Did you mean: 

Generating Bin File for Dual Application Bootloader

A_Major
Associate II

Greetings,

I am creating a project with STM32CubeIDE for a STM32L4 microcontroller. My project consists of multiple components :

  • Bootloader - Base program that jumps to one of my applications
  • Applications - Application program for my project
  • Python Script - Feeds the generated binary file of my application to the bootloader

My memory sections are as follow (copied from the bootloader project) :
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 96K
RAM2 (xrw) : ORIGIN = 0x10000000, LENGTH = 32K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 64K
APP_SLOT_1 (rwx) : ORIGIN = 0x8010000, LENGTH = 192K
APP_SLOT_2 (rwx) : ORIGIN = 0x8040000, LENGTH = 256K
}

Whereas the section from my linker script of my application is :
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 96K
RAM2 (xrw) : ORIGIN = 0x10000000, LENGTH = 32K
FLASH (rx) : ORIGIN = 0x8010000, LENGTH = 192K    or   FLASH (rx) : ORIGIN = 0x8040000, LENGTH = 256K
}
Then I have to set the vector table offset in the application according to the flash location (system_stm32l4xx.c):
#define VECT_TAB_OFFSET 0x00010000U   or   #define VECT_TAB_OFFSET 0x00040000U 

So, I have to determine these two settings followed by building the application project to generate the bin file. After that, I can manually write the flash memory pages with the bin file values and then my bootloader jumps to this program.
All this is working, allowing me to control which program my bootloader loads.

Here is my question :
I would like to generate .bin files that sets dynamically the vector table offset so I don't have to create a binary file for every application slot by changing the USER_VECT_TAB_OFFSET and memory sections. How can I do this?

So far I tried setting the Vector Table Offset Register SCB->VTOR in the bootloader before modifying the reset handler that jumps to my application.
I also tried setting SCB->VTOR in the application at SysInit. For this, I commented the definition of USER_VECT_TAB_ADDRESS.
I also set the memory section to include both application slots :
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 96K
RAM2 (xrw) : ORIGIN = 0x10000000, LENGTH = 32K
FLASH (rx) : ORIGIN = 0x8010000, LENGTH = 448K
}

Even if my binary file is loaded properly at address 0x8040000 as seen from STM32CubeProgrammer, the bootloader always jump to the application at location 0x8010000 or back to the bootloader at 0x8000000.

I also tried generating a binary file from the .elf files using the Arm GNU Toolchain arm-none-eabi-objcopy. The generated binary file kept its static reference, so It would not work on the second application slot at 0x8040000.

9 REPLIES 9

I would like to generate .bin files that sets dynamically the vector table offset so I don't have to create a binary file for every application slot by changing the USER_VECT_TAB_OFFSET and memory sections. How can I do this?

Use a symbol? g_pfnVectors ?? What ST should have done since Day-Zero..

extern uint32_t *g_pfnVectors;

SCB->VTOR = (uint32_t)(&g_pfnVectors);

https://community.st.com/t5/embedded-software-mcus/stm32f105rb-when-the-program-is-flashed-to-0x800000-the-debug/m-p/63006

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
SGAUR.1
Associate III

Hello A_Major,

I'm facing exact same issue, did you find solution for it ?

Shriram

There's plenty of material describing how the MCU operates, and you have a wealth of debuggers, should be able to navigate to a solution from basic principles.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
SGAUR.1
Associate III

Hello Tesla,

I tried your previous suggestion : and looks like this is just not working.

"Use a symbol? g_pfnVectors ?? What ST should have done since Day-Zero..

extern uint32_t *g_pfnVectors;

SCB->VTOR = (uint32_t)(&g_pfnVectors);"

The problem is, in linker file you've to provide flash start address and .isr_vector symbol keeps following this flash starting address.
If I remove .isr_vector section from Linker file to keep it floating and provide during systemInit(), mcu generate hard-fault.

Let me know if you've other ideas of implementation.

Shriram

 

Thank you for your reply.

I have tried your solution. When I upload the bin file to the second application slot, It still redirects me to the first application slot.
I have tried different methods of modifying SCB->VTOR in the SystemInit function and none seem to work.
Let me know if you have other ideas.

A_Major

Hi Shriram,
I have not found a solution yet. I will let you know if I find a solution.
A_Major

Define "not working" ?

What DOES HAPPEN? These things don't operate via magic or random, the MCU operates in a very logical and sequenced way. Start from the BEGINNING, and focus less on where it ended up when it "failed". Determine what it is doing at each step, and why, and if it's not what you expect, reflect on that a litte.

The MCU is always going to use the vector table, the vector table needs to be on a correctly aligned address.

When it starts it pulls values from the table, you can inspect them. When you change the table it will pull destination addresses for the assorted interrupts and handlers from this new table, look at what's in the table, and what the MCU is going to do with those.

Addresses in the table are ABSOLUTE, the Linker will have fixed them up, look at the output object files, dump them, disassemble them, and follow the anticipate route of code execution.

If you have firmware images located at multiple addresses you're going to have to navigate the MCU to those through some means of control transfer. You're loading new addresses, and jumping / branching to them.

What's not working about the symbol method? The linker should be establishing the addresses based on the linker script, and conveyed in the .MAP file. If you set the vector table to a symbol it will no longer be dependent on editing a second file with a #define, it will simply get in the normal flow of the linker. The address could be unsuitable, the linker could be confused by demands put on it, but it should be apparent through inspection and basic validation.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

It is my understanding as well that .isr_vector follows the flash start address and is causing the error. The only way for me to upload properly at the second application slot my code with my bootloader is by setting the FLASH section in my linker script to the second application start address (i.e FLASH (rx) : ORIGIN = 0x8040000, LENGTH = 256K in my example). This is because the isr_vector will then be aligned to this address.

However, I expect the flash section to start from the first application and include both (Like the original post : FLASH (rx) : ORIGIN = 0x8010000, LENGTH = 448K). I modify in the application's SystemInit to the address of my application dynamically, but I think we should also set isr_vector dynamically.
I have not found a way to do this, this vector is fixed at compile time, not at runtime.

A_Major

SGAUR.1
Associate III

Hello A_Major,

I got some pointers but haven't reached to a working solution yet.
We need to compile code using -fPIC flag in compile settings (i.e. Position independent code). This will generate code with relative addressing.
There are other settings/modifications involved to make this working (some in linker, some in start up files). I'm attaching link to a site which explains about this concept. Hope this helps.

https://mcuoneclipse.com/2021/06/05/position-independent-code-with-gcc-for-arm-cortex-m/

Thanks,

Shriram