cancel
Showing results for 
Search instead for 
Did you mean: 

AN2606 System memory boot mode - Jumping to bootloader

bobseabrook9
Associate II
Posted on May 05, 2016 at 17:39

I am using a stm32f4discovery. When SB18 is removed (underside) to make boot0=1, to boot from system-bootloader, my windows7 sucessfully detects the USB DFU interface (it appears in Device manager in the ''Universal Serial Bus Controllers'' node as ''STM Device in DFU Mode''. Great!).

Next, I replaced SB18 to boot from user flash at 0x08000000.  

AN2606 revision 27 page 20 clearly states that ''..user can execute bootloader by performing a jump to system memory from user code.'' Exactly what address do I jump to.????   Page 93 says says bootloader starts at 0x1fff0000 (size 30688 bytes). However this is vector table. containing an intial SP and PC of 20001d80 and 1fff3da1. In my usercode I have NOT enables any PLL,interrupts, peripherals, so right at the start of main() I simply jump to 1fff3da1 (1fff3da0 in thumb2 mode) using instructions;

 __set_MSP(0x20001d80);

 __set_PSP(0x20001d80);

 __ASM volatile (''b 0x1fff3da1\n'');

 but my windows7 does NOT detect the USB DFU interface. Can anyone tell me how to make this work?

What actually happens is that I get hard-fault because when I jump to 0x1fff3da1 the debugger takes me to ''*ABS*0x1fff3da0_veneer'' at 0x08005f28. 

I have tried jumping to 1fff3da0. Same result.

I am using GNU C++ in SW4STM32. 

#it's-deja-vu-all-over-again
4 REPLIES 4
bobseabrook9
Associate II
Posted on May 05, 2016 at 18:35

Thanks Clive1. Looks like its a mapping solution rather than a jump as stated in AN2606.

Posted on May 05, 2016 at 19:27

For USB/DFU yes, as it is far more involved. The USART System Loader, on the F1, and in my experience generally, does not need interrupts. I suspect the code doesn't explicitly set SCB->VTOR, which it assumes is zero (per processor default), one could set that to the ROM base, and I'd suspect it would have the same effect.

Anyway, one should generally jump through the vector table rather than specifying explicit addresses, as the ''ROM'' has a tendency to change with different versions of the loader.

I've been doing this stuff long before the App Note, so I'm not sure who wrote it or where they lost the plot.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
bobseabrook9
Associate II
Posted on May 06, 2016 at 16:09

Follow up;

Actually a jump to bootloader from C language works in principle, the compiler was objecting to syntax

           __ASM volatile (''b 0x1fff3da1\n'');

1. Replacing it with

  __ASM volatile (''ldr R0, =0x1fff3da1\n'');    

  __ASM volatile (''bx R0\n'');                  

    Works. Or

2.  replacing it with with;

    void (*func)(void) = (void (*)(void))0x1fff3da1; 

    func();

    works, or

3. replacing it with a call to

           extern ''C'' void loader(void);

           loader();

    works,

    where ''loader'' is an assembler function in the startup.s file alongside Reset_Handler that looks  like this

    

  .weak loader

  .type  loader, %function

  loader:

                 LDR        R0, =0x1FFF0000

                 LDR        SP, [R0, #0]

                 LDR        R0, [R0, #4]

                 BX         R0

    Or 

4. replacing it with this C implementation

 typedef void (*fptr_t)(void);                       //function ptr type

 uint32_t* tableptr = (uint32_t*)0x1fff0000;  //vector table in sys mem

 fptr_t function = (fptr_t)tableptr[1];             //jump destination

 function();                                                //jump

    works - and uses the vector table at start of system memory.

    

( - Also I replaced wrong SP inititialization

  __set_MSP(0x20001d80);

  __set_PSP(0x20001d80);

with

  __ASM volatile (''ldr sp, =0x20001d80\n'');

- )

 Works, although it is better to get the initial SP from the vector table at 0x1fff0000 like this

         __ASM volatile (''ldr r0, =0x1fff0000\n ldr sp, [r0, #0]\n''  : : : ''sp'');

Yes this deliberately ignores the bigger picture, the idea is to test the claim that we can simply jump to the bootloader from main flash C code, and the answer is yes we can. Other posts, and AN2606, deal very well with the details of how you do this properly. For me that is a separate step.