cancel
Showing results for 
Search instead for 
Did you mean: 

Jump to application at 0x8001000 when no bootloader is present

Tom
Associate II

Hi Guys,

I'm writting a bootlader/application for STM32L4 in STM32CubeIDE i I want my app to run even if there is no bootloader in memory.

This is my *.ld file:

/* Memories definition */
MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 96K
  RAM2    (xrw)    : ORIGIN = 0x10000000,   LENGTH = 32K
  FLASH    (rx)    : ORIGIN = 0x8001000,   LENGTH = 1024K-0x1000
  BOOT     (rx)    : ORIGIN = 0x8000000,   LENGTH = 131K
}

I my app source I have the below function (which is properly placed at 0x8000000 in flash) :

#define MY_BL_FUNCTIONS __attribute__((section(".bootsection")))
void __attribute__((optimize("O0"))) Bootloader_JumpToApplication(void); MY_BL_FUNCTIONS
 
void __attribute__((optimize("O0"))) Bootloader_JumpToApplication(void)
{
        asm("ldr R0,=0x8001004"); //my app start address
        asm("BX R0");   //jump to app
}

Unfortunately asm("BX R0") makes a sudden jump to my HardFault_Handler. instead of 0x8001004.

What do I do wrong?

Thanks in advance

Tom

10 REPLIES 10
Bassett.David
Senior

Hello Tom,

Perhaps try "asm("ldr R0,=0x8001005"); //my app start address"

I believe Thumb-2 addresses are designated by bit-0 set.

Good Luck,

Dave

Show disasm.

> function (which is properly placed at 0x8000000 in flash)

A minimal vector table has to be at 0x0800'0000, with address of that function (possibly 0x0800'0009, if it follows immediately after that vector table) at 0x0800'0004.

[EDIT] Oh, and the displacement may be too far to use the pc-relative addressing (to which ldr R0, =xxxx translates)

 https://developer.arm.com/documentation/dui0552/a/the-cortex-m3-instruction-set/memory-access-instructions/ldr--pc-relative

JW

No, doesn't work like that.

Also Vector Table, is a TABLE OF ADDRESSES, NOT CODE, Thumb code has an ODD address, the Cortex-M can't execute 32-bit ARM code, with EVEN addresses.

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

Thanks guys, I changed my bootloader func. to:

    SCB->VTOR=0x8001000;
    asm("ldr R0,=0x8001004");
    asm("BX R0");

tried asm("ldr R0,=0x8001005"); too but same result.

Of course I also did in system_stm32l4xx.c:

#define VECT_TAB_OFFSET    0x1000

This is my disassembly:

08000000:   push    {r7}
08000002:   add     r7, sp, #0
08000004:   ldr     r3, [pc, #16]   ; (0x8000018 <Bootloader_JumpToApplication+24>)
08000006:   ldr     r2, [pc, #20]   ; (0x800001c <Bootloader_JumpToApplication+28>)
08000008:   str     r2, [r3, #8]
0800000a:   ldr     r0, [pc, #20]   ; (0x8000020)
0800000c:   bx      r0
0800000e:   nop     
08000010:   mov     sp, r7
08000012:   ldr.w   r7, [sp], #4
08000016:   bx      lr
08000018:   stc     0, cr14, [r0, #-0]
0800001c:   asrs    r0, r0, #32
0800001e:   lsrs    r0, r0, #32
08000020:   asrs    r4, r0, #32
08000022:   lsrs    r0, r0, #32
08000024:           ; <UNDEFINED> instruction: 0xffffffff
08000028:           ; <UNDEFINED> instruction: 0xffffffff
0800002c:           ; <UNDEFINED> instruction: 0xffffffff
08000030:           ; <UNDEFINED> instruction: 0xffffffff
08000034:           ; <UNDEFINED> instruction: 0xffffffff

Tom

LDR Rx,= will translate to an ADD/SUB (near or further) with PC for short compatible addresses, an immediate move if the constant packs, or a PC relative load access to a literal pool.

What you can't do is branches to the entire 32-bit address space

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

VECTOR TABLE != CODE

What are words at 0x08000000 and 0x08001000 should be initial SP/PC pair at minimum

Execution starts assuming SCB->VTOR = 0, memory mapped at zero depends on BOOT pins, and can be ROM, FLASH or RAM

ldr r0,=0x08001004

ldr r0,[r0, #0] ; Load ADDRESS in VTOR+4

bx r0

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

Apart from the official documentation by ARM and ST, the internet is full of materials about Cortex-M vector table, startup scripts etc.

  FLASH    (rx)    : ORIGIN = 0x8001000,   LENGTH = 1024K-0x1000
  BOOT     (rx)    : ORIGIN = 0x8000000,   LENGTH = 131K

0x1000 = 4K. Those regions have an overlap of a 127K!

> I want my app to run even if there is no bootloader in memory.

You are misunderstanding what a bootloader is. Bootloader is a code that is always present and always capable of recovering a device to a fully working condition. If there is some boot/update code that can be missing or otherwise broken at some point, then that is a second (stage) bootloader.

Tom
Associate II

Hi Piranha

The overlap is no the problem here, as everything goes into flash as expected as you could see.

I understand how bootloader works but at dev stage in order to flash bootloader and app I'd have to manuallly merge bootloader hex and app hex before programming which I dont want cause it makes no sense. It is easier to place a simple jump at 0x8000000 to the app so I can quickly debug and run the app in CubeIDE.

DaltonDuarte
Associate

Any solution?