STM32L073RZ (rev Z) IAP jump to bootloader (system memory)

£可爱£侵袭症+ 提交于 2019-12-02 01:22:32
Jaroslav Houdek

The solution is to jump twice to the system memory. First Jump to bootloader startup to initialize Data in RAM until the Program counter will returned to Flash by the Dualbank management. Second Jump: Jump to the Dualbank bypassed address

How to use: User has first to initialize a variable “ Data_Address” (must be an offset Flash sector aligned address) in Flash to distinguish between first/second Jump.

EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
EraseInitStruct.PageAddress = Data_Address;
EraseInitStruct.NbPages     = 1;


    First_jump = *(__IO uint32_t *)(Data_Address);

    if (First_jump == 0) {  
        HAL_FLASH_Unlock();
        HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Data_Address, 0xAAAAAAAA);
        HAL_FLASH_Lock();

        /* Reinitialize the Stack pointer and jump to application address */ 
        JumpAddress = *(__IO uint32_t *)(0x1FF00004);
    }
    if (First_jump != 0) {  
        HAL_FLASH_Unlock();
        HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError);
        HAL_FLASH_Lock();

        /* Reinitialize the Stack pointer and jump to application address */ 
        JumpAddress =  (0x1FF00369);
    }

    Jump_To_Application = (pFunction) JumpAddress;
    __set_MSP(*(__IO uint32_t *)(0x1FF00000));
    Jump_To_Application(); 

Thanks for your help. I have my answer !

The v4.0 bootloader (initial version) does not implement the dual bank mechanism but this feature is supported by v4.1.

Software can jump to bootloader but it will execute the dual boot mechanism. So the bootloader goes back to bank1 (or bank2 if a code is "valid").

Today it is not possible to bypass the dual bank mechanism to execute the bootloader with my configuration: The boot0 pin is reset and the protection level is 0 (see "Table 11. Boot pin and BFB2 bit configuration" in the reference manual).

Where is your program counter when you call __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH()?

Remapping a memory region while you're executing out of that same region will end poorly! You may need to relocate this code into SRAM, or execute this code with PC set to the fixed FLASH memory mapping (0x0800xxxx).

First important thing: you use 0x1FF0 0000 as the addres where SP is stored, this is correct. Then you use 0x1 FF00 0004 as the address from which you load the function pointer. This is not correct - one zero too many.

Note that using __set_MSP() is generally not such a good idea if you also use MSP as your stack pointer (which you most likely are). The recent definition of this function, which marks "sp" as clobbered register, causes your change to be reverted almost immediately. Incidentally today I was doing exactly the same thing you are doing and I've found that problem. In your assembly listing you'll see that SP is saved into some other register before the msr msp, ... instruction and restored right after that.

Finally I wrote that manually (STM32F4, so different addresses):

constexpr uint32_t systemMemoryBase {0x1fff0000};

asm volatile
(
        "   msr     msp, %[sp]      \n"
        "   bx      %[pc]           \n"

        ::  [sp] "r" (*reinterpret_cast<const uint32_t*>(systemMemoryBase)),
            [pc] "r" (*reinterpret_cast<const uint32_t*>(systemMemoryBase + 4))
);

BTW - you don't need to set memory remap for the bootloader to work.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!