cancel
Showing results for 
Search instead for 
Did you mean: 

Problem accessing Internal Boot Loader in STM32H743xx

James1
Associate II

Hi Everyone,

I am working on a project where I need to program STM32H743xx MCU through UART, but I am facing problem in entering the internal bootloader through software. I have created a .s file to enter the bootloader where I need to wait for a firmware command and then enter the bootloader mode.

Note: I am successfully entering the bootloader mode when I directly call the DFUBoot() function but when I call through HAL_UART_RxCpltCallback I don't see any response from the bootloader.

DFU_Bootloader.s

        AREA  demo, CODE

PRESERVE8

ALIGN

DFU_Bootloader   PROC

 EXPORT DFU_Bootloader            [WEAK]

        IMPORT SystemInit

        IMPORT __main 

        LDR   R0, =0x2001FFFC ;

        LDR   R1, =0xBEEFBEEF ;

        LDR   R2, [R0, #0]

        CMP   R1, R2

        BNE   NotDFuse1

        STR   R0, [R0, #0]   ; Invalidate Key

        LDR   R1, =0xE000ED00 ; SCB

        LDR   R0, =0x1FF09800 ; ROM BASE

        STR   R0, [R1, #8]   ; VTOR

        LDR   SP,[R0, #0]   ; ROM Stack Pointer

        LDR   R0,[R0, #4]   ; ROM Program Counter

        BX   R0

ENDP

NotDFuse1 PROC

 EXPORT NotDFuse1

        LDR   R0, =SystemInit

        BLX   R0

        LDR   R0, =__main

        BX   R0

 ALIGN

 ENDP

 END

HAL_UART_Receive_DMA(&huart3,&newreceive[0],1); // UART DMA RX for firmware Cmd

// UART RX Callback

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

{

if(newreceive[0]==0xAA)

{

HAL_UART_Transmit_DMA(&huart3, &sendtx[0],1);

DFUBoot();

}

else{}

}

void DFUBoot(void)

{

__HAL_RCC_DMA1_CLK_DISABLE();

HAL_NVIC_DisableIRQ(DMA1_Stream0_IRQn);

HAL_NVIC_DisableIRQ(DMA1_Stream1_IRQn);

__DSB();

 Boot1 = 0xBEEFBEEF; // Special Key to End-of-RAM

__DSB();

DFU_Bootloader(); 

}

Any help would be highly appreciated.

3 REPLIES 3

It is not surprising that this doesn't work from interrupt context.

Try using the method as I originally published it, or ponder how to unwind the call stack.​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Hi Clive,

Thank you very much for your reply. I don’t want to use reset handeler to enter Bootload mode, I need to use interrupt mode to enter bootload, Is there any other method to unwind the callback as even after disabling the DMA stream it is not working??? In STM32F4 it works in interrupt mode after remapping the memory but in STM32H7 I don’t see any register to remap. I am successful in programming STM32H7 using Hardware reset but stuct with this problem entering bootloader mode using software

The loader is going to be intolerant to any interrupts you have functioning, this will include USART and SysTick ones, it has no understanding of what you've set up. The core also needs to unwind the NVIC state.

So setting up another DMA transaction isn't helpful. Loading the RAM constant was for the reset method. The best place to unwind would be the IRQ Handler that is firing here, and that interrupt should have the least priority. The goal being to return to the DFUBoot() function, and from there entering the system boot loader. Alternatively you can flag the request, and call DFUBoot() from the foreground task/loop.

__DSB() is rather ineffectual in the H7 caching/write-back scenario

Original method for those reader unfamiliar with it https://community.st.com/s/question/0D50X00009XkW8QSAV/stm32h743-how-to-start-the-system-boot-loader-via-software

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..