Calling stm32 internal bootloader from application

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderators: barthess, RoccoMarco

geoffroy
Posts: 7
Joined: Fri Oct 30, 2015 3:28 pm

Calling stm32 internal bootloader from application

Postby geoffroy » Tue Jan 19, 2016 9:46 am

Hi Giovanni,

We are trying to calling the STM32 SystemMemory Bootloader from our application,
but we encountered some problems.

In order to make bootloader working, it's necessary to do some stuff before : (from ST documentation)

Disable all peripheral clocks
• Disable used PLL
• Disable interrupts
• Clear pending interrupts

Here is my function which enters in bootloader mode :

Code: Select all

void enter_bootloader_mode()
{
   chSysDisable();

   //shut down any tasks here ...

   uint32_t application_address = 0x1FF01FFE; //corresponding to stm32l152RE <=== code crash here
   __set_MSP( * (__IO uint32_t*) application_address);
   bootJump = *(__IO uint32_t*) (application_address + 4);
   bootJump();
   
   while(1);
}


But, every time, debugger stop at :
__set_MSP( * (__IO uint32_t*) application_address)
and I get a : _unhandled_exception(void) { ... }
in vectors.c

apparently, reading address 0x1FF01FFE is not permitted ..
Have you any ideas about what is occurring ?

Thanks in advance for any help ..
Geoffroy

vambwodonk
Posts: 15
Joined: Tue Oct 14, 2014 5:36 am

Re: Calling stm32 internal bootloader from application

Postby vambwodonk » Tue Jan 19, 2016 10:21 am

Hi, Geoffroy

Maybe you need more than ChSysDisable(). You need to stop entire OS like this
http://wiki.chibios.org/dokuwiki/doku.php?id=chibios:howtos:stop_os

Tell us if you successful with this project, :D

flabbergast
Posts: 71
Joined: Sat Aug 22, 2015 1:22 pm

Re: Calling stm32 internal bootloader from application

Postby flabbergast » Wed Jan 20, 2016 12:32 am

The way I do it is that I patch the ResetHandler supplied with chibios, so that it reads a word at the end of the memory, and if it matches a predefined value, it jumps to the bootloader. This jump is "safe" because nothing has been initialised yet, it is just after a reset. Now when I want to jump to bootloader from the application, I just write the predefined word to the end of the memory and request reset.

To see the code, see here.
Here are the important bits: The actual patch to crt0 chibios code is here; the correct bootloader address is passed in the Makefile like this; and finally the jump in the application is implemented here.

EDIT: This approach may work without patching chibios by performing the bootloader-jump-check in the __early_init() function, which can be redefined in the board definition files. I have not tried this yet.

User avatar
Giovanni
Site Admin
Posts: 12177
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 570 times
Been thanked: 487 times
Contact:

Re: Calling stm32 internal bootloader from application

Postby Giovanni » Wed Jan 20, 2016 9:15 am

Editing __early_init() is legit, it is like creating new board files.

Giovanni

geoffroy
Posts: 7
Joined: Fri Oct 30, 2015 3:28 pm

Re: Calling stm32 internal bootloader from application

Postby geoffroy » Thu Jan 21, 2016 12:19 pm

@flabbergast

We tested the solution about patching chibios. It's working great ;-)

Thanks ! :D

flabbergast
Posts: 71
Joined: Sat Aug 22, 2015 1:22 pm

Re: Calling stm32 internal bootloader from application

Postby flabbergast » Thu Jan 21, 2016 6:24 pm

Good to know! Just to give credit where it is due, my approach is based on this forum thread.

Also, I have now moved the required code to board definition files, so patching core chibios code is no longer needed: the modifications to the board files are like this to the header and this to the __early_init function; calling from the main application is still the same (but it uses now the BOOTLOADER_MAGIC define instead of the straight value) and BOOTLOADER_ADDRESS should be now passed in the Makefile in UDEFS (not UADEFS) and as a string constant (not a number constant), like this.

I'm sure the inline assembly bit can be replaced by some C magic one-liner with lots of brackets and stars, but I'm not good enough to know how ;)

trainman419
Posts: 4
Joined: Sat Jul 11, 2015 5:28 am

Re: Calling stm32 internal bootloader from application

Postby trainman419 » Mon Apr 11, 2016 8:01 pm

I'm trying to do the same thing with ChibiOS 3.0.5 on an STM32F407, and it doesn't seem to be working. Is there something that has changed in the Reset_Handler on newer versions of ChibiOS?

I can enter the bootloader by pulling BOOT0 high, but the jump into the bootloader from __early_init() doesn't work:

Code: Select all

#define BOOTLOADER_ADDRESS 0x1FFF0000

    /* Remap the system memory onto address 0 */
    asm("LDR r0, =0x40023844;" /* RCC_APB2ENR */\
        "LDR r1, =0x00004000;" /* enable SYSCFG clock */\
        "STR r1, [r0, #0];"\
        "LDR r0, =0x40013800;" /* SYSCFG_MEMRMP */\
        "LDR r1, =0x00000001;" /* remap ROM at zero */\
        "STR r1, [r0, #0];");

    /* Jump into the bootloader
     * Page 70 of the reference manual (RM0090) describes how to set up the
     * stack pointer and jump to the bootloader
     *
     * Load the initial stack pointer value from the first location in memory
     * then Jump to the next address */
    asm("LDR r0, =%[Is];"\
        "LDR r1, [r0, #0];"\
        "MOV sp, r1;"\
        "LDR r0, [r0, #4];"\
        "BX  r0;"\
        : : [Is] "i" (BOOTLOADER_ADDRESS));


I've also added the remap of address 0 as suggested by https://my.st.com/public/STe2ecommuniti ... views=1164 , but it doesn't seem to be helping.

flabbergast
Posts: 71
Joined: Sat Aug 22, 2015 1:22 pm

Re: Calling stm32 internal bootloader from application

Postby flabbergast » Tue Apr 12, 2016 12:44 am

I have actually discovered that the approach I described does not quite work (on F042) because F042's bootloader *always* checks the BOOT0 pin (and the only other possibility is setting the option byte) - so the only reliable way I found to not just jump to the bootloader code but also stay there is to devise a hardware way to keep BOOT0 high during that check (e.g. a RC circuit).

I don't think the ResetHandler code has changed recently, and my understanding is that actually not much happens before the __early_init() function is called.

LHelge
Posts: 15
Joined: Sun Sep 21, 2014 10:58 pm
Been thanked: 1 time

Re: Calling stm32 internal bootloader from application

Postby LHelge » Thu Apr 14, 2016 9:08 am

What is the benefit of doing this in __early_init() instead of in the beginning of main() I can the that the former is called first by the bootup code but will it make any difference?`

I would rather have the bootloader check in main() for two reasons, the __early_init() will be overwritten each time I generate new board-files from the config XML. And I think it would be cleaner to keep as much application code as possible out of the board-files.

User avatar
Giovanni
Site Admin
Posts: 12177
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 570 times
Been thanked: 487 times
Contact:

Re: Calling stm32 internal bootloader from application

Postby Giovanni » Thu Apr 14, 2016 12:20 pm

Hi,

__early_init() comes before memory initialization and static constructors which can be slow, so it is the right place for clock-up and urgent initializations.

Said that, it could be moved elsewhere, it does not have to be in board files.

Giovanni


Return to “STM32 Support”

Who is online

Users browsing this forum: MSN [Bot] and 7 guests