Skip to main content
Visitor II
May 16, 2020
Question

STM32L072CZ - Jumping in DFU bootloader via software

  • May 16, 2020
  • 6 replies
  • 2928 views

Hello

I'm migrating my STM32F072 project to the STM32L072.

In my original project (F072) I can jump to the DFU bootloader by software via a function located before SystemInit.

I tried to convert this to be used by L072 by changing the address of bootloader program to 0x1ff00004 it's not working.

Is it due to the dual memory bank? Is there a way to get it working?

Thank-you

André

    This topic has been closed for replies.

    6 replies

    Graduate II
    May 16, 2020

    I.m.h.o., best way to do so is to set some marker in on-chip ram, trigger reset and early in startup code test for that pattern in RAM and if found, reset it. set up VTOR etc for system bootloader and jump to system bootloader.

    Visitor II
    May 17, 2020
    void (*SysMemBootJump)(void);
     
    #define SRAM_ADDRESS_DFU			(unsigned long *)0x20004FF0	// *((unsigned long *)0x20004FF0) 20kRam
     
    void SystemInit (void)
    {
    		 if ( *((unsigned long *)SRAM_ADDRESS_DFU) == 0xDEADBEEF ) {
    	 *((unsigned long *)SRAM_ADDRESS_DFU) = 0xCAFEFEED; // Reset our trigger
    	 __set_MSP(0x20002250);
    	 // 0x1ff0 0000 is "System Memory" start address for STM32 L0xx
    	 SysMemBootJump = (void (*)(void)) (*((uint32_t *) 0x1ff00004)); // Point the PC to the System Memory reset vector (+4)
    	 SysMemBootJump();
    	 while (1);
    	 }
    ....

    Hi,

    It's exactly what I do, working perfectly with F072, not working with L072

    Super User
    May 16, 2020

    This thread claims the BOOT0 pin is sampled in the bootloader, but I'm a bit skeptical. The other comments should help you:

    https://community.arm.com/developer/tools-software/tools/f/keil-forum/41955/stm32l072-jumping-to-embedded-bootloader-from-application-code

    Graduate II
    May 17, 2020

    You have to set  SYSCFG->CFGR1 so that system rom gets mapped at address 0 before the jump

    Visitor II
    May 17, 2020

    Hi thank-you for feedback,

    I added

    	 SysMemBootJump = (void (*)(void)) (*((uint32_t *) 0x1ff00004)); // Point the PC to the System Memory reset vector (+4)
    	 SYSCFG->CFGR1 |= 0x01 ;
    	 SysMemBootJump();

    Maybe I didn't correctly understand you, but the system reset immediately and didn't jump in the DFU mode

    Graduate II
    May 17, 2020

    STM32L0 also has VTOR, so you may need to set it too.

    Visitor II
    May 17, 2020

    Not better :(

    Graduate II
    June 21, 2024

    Jump on MCUs with detection firmware in flash not work or better say work , but default jump back to app if is detected in flash. One way is erase first memory sector before jump.

    Second maybe as AN2606 pattern say 

    MM1_0-1718982848005.png

    try BFB2 0

    Graduate II
    May 18, 2020

    Then single step in the debugger and find out where and why things go wrong.

    Visitor II
    June 21, 2024

    Hi, I'm facing the same issue on my L072.

    Have you finally succeeded to get into DFU ? If so, can you tell me how ?

    Visitor II
    December 13, 2024

    This is my code, it worked fine on my L072.

    It is imporant to erase the first 4 bytes of user flash, you can find in AN2606 Rev 64 (p.69).

    I was helped by many posts, thanks all.

    teru839_0-1734103053594.png

     

    #define BOOTLOADER_MAGIC_ADDR 		 ((uint32_t*) ((uint32_t) 0x2000142c)) // ._user_heap_stack front addr
    #define BOOTLOADER_MAGIC_TOKEN 		 0xDEADBEEF
    #define BOOTLOADER_START_ADDR 		 0x1FF00000
    
    // call this at any time to initiate a reboot into bootloader
    void RebootToBootloader(){
     *BOOTLOADER_MAGIC_ADDR = BOOTLOADER_MAGIC_TOKEN;
     NVIC_SystemReset();
    }
    
    // call this in first line of main()
    void bootloaderSwitcher(){
     uint32_t jumpaddr;
     FLASH_EraseInitTypeDef erase;
     uint32_t pageError = 0;
    
     if (*BOOTLOADER_MAGIC_ADDR == BOOTLOADER_MAGIC_TOKEN){
     *BOOTLOADER_MAGIC_ADDR = 0;
    
     // Avoid the empty check mechanism
     erase.TypeErase = FLASH_TYPEERASE_PAGES;
     erase.PageAddress = 0x08000000;
     erase.NbPages = 1;
     HAL_FLASH_Unlock();
     HAL_FLASHEx_Erase(&erase, &pageError);
     HAL_FLASH_Lock();
    
     void (*bootloader)(void) = 0;
     jumpaddr = *(__IO uint32_t*)(BOOTLOADER_START_ADDR + 4);
     bootloader = (void (*)(void)) jumpaddr;
     __set_MSP(*(__IO uint32_t*) BOOTLOADER_START_ADDR); 
     bootloader();
     while(1){}
     }
    }