This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

STM32 Start DFU Bootloader

Hello,

I'm developing a bootloader for a STM32F2 Controller.
One Feature of the bootloader is that it can start the STM32 internal DFU bootloader.
Therefore I use some RAM Region where I set a Special value that is read by my bootloader when the bootloader starts.

My question is:
What is the better Approach? Read the value in Assembler code (Startup.s) and directly start the DFU bootloader from Assembler code or
read and start from the main function?

I know that the assembler code does not directly call the main function but an __main function.
Can anyone tell me what excatly is done in the __main fcuntion.

Parents
  • Hi Clive,

    thank you for your reply.

    I saw in your links that the bootloaer should be called in Assembler code before the call to SystemInit.
    I use more than just one variable for communication between the bootloader and the Firmware. Therefore I created a struct with 3 members.

    Therefore, it would be nicer to start the DFU mode from C code as I could directly read the variable value instead of using the RAM addresses.

    void Bootloader_DFU()
    {
        if(NonVolDataBL.u32Status == DFU_MODE)  // Check Special RAM variable if the SFU moed should be started.
        {
            volatile uint32_t SYSMEM_ADDR = 0x1FFF0000;
    
            // Reset Upgrade-Mode in RAM so that after a reset, the normal application will restart
            NonVolDataBL.u32Status = 0;
    
            // Disable RCC, set it to default (after reset) settings
            // Internal clock, no PLL, etc
            RCC_DeInit();
    
            // Enable SYSCFG clock.
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    
            // Disable systick timer and reset it to default values
            SysTick->CTRL = 0;
            SysTick->LOAD = 0;
            SysTick->VAL = 0;
    
            SYSCFG->MEMRMP = SYSCFG_MemoryRemap_SystemFlash;
    
            StartApplication(SYSMEM_ADDR);
        }
    }
    

    When I call this function directly as the first instruction in SystemInit it should work the same way as when I use the Assembler code isn't it?

    One additional question (not sure if this it the right Forum):
    The internal DFU bootloader checks for an incoming CAN Frame and then starts the DFU mode via CAN. My problem is, that there can be CAN traffic when I start
    the DFU mode. This can prevent the DFU mode from starting correctly. Does anyone know whether I can disable the DFU-CAN mode and directly start via USB Device?

Reply
  • Hi Clive,

    thank you for your reply.

    I saw in your links that the bootloaer should be called in Assembler code before the call to SystemInit.
    I use more than just one variable for communication between the bootloader and the Firmware. Therefore I created a struct with 3 members.

    Therefore, it would be nicer to start the DFU mode from C code as I could directly read the variable value instead of using the RAM addresses.

    void Bootloader_DFU()
    {
        if(NonVolDataBL.u32Status == DFU_MODE)  // Check Special RAM variable if the SFU moed should be started.
        {
            volatile uint32_t SYSMEM_ADDR = 0x1FFF0000;
    
            // Reset Upgrade-Mode in RAM so that after a reset, the normal application will restart
            NonVolDataBL.u32Status = 0;
    
            // Disable RCC, set it to default (after reset) settings
            // Internal clock, no PLL, etc
            RCC_DeInit();
    
            // Enable SYSCFG clock.
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    
            // Disable systick timer and reset it to default values
            SysTick->CTRL = 0;
            SysTick->LOAD = 0;
            SysTick->VAL = 0;
    
            SYSCFG->MEMRMP = SYSCFG_MemoryRemap_SystemFlash;
    
            StartApplication(SYSMEM_ADDR);
        }
    }
    

    When I call this function directly as the first instruction in SystemInit it should work the same way as when I use the Assembler code isn't it?

    One additional question (not sure if this it the right Forum):
    The internal DFU bootloader checks for an incoming CAN Frame and then starts the DFU mode via CAN. My problem is, that there can be CAN traffic when I start
    the DFU mode. This can prevent the DFU mode from starting correctly. Does anyone know whether I can disable the DFU-CAN mode and directly start via USB Device?

Children
No data