Skip to main content
Explorer
September 17, 2025
Solved

STM32H745XIHX entering bootloader in code: Switch USB from VCP to DFU on User Input

  • September 17, 2025
  • 2 replies
  • 972 views

Hi all,

I am a newer STM32 programmer, and I have been working on the STM32H745 Discovery board for the last few months. Something that I would like to do is be able to switch into USB DFU Mode within a UI that I have made for this board. I took inspiration from this post and changed the address to the appropriate one for the STM32H745. I would like to prerequisite that the USB port is initially configured as a VCP/CDC device. Here is the code that I have:

void (*SysMemBootJump) (void);

void USB_BootloaderInit()
{
	volatile uint32_t addr = 0x1FFF9800;	//from AN2606

	__disable_irq();

	// Reset USB OTG_FS

	// Disable caches
	SCB_DisableICache();
	SCB_DisableDCache();

	// Remap vector table
	HAL_RCC_DeInit();		//Reset the system clock
	SysTick->CTRL = 0;		//Reset the SysTick Timer
	SysTick->LOAD = 0;
	SysTick->VAL = 0;
	SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4)));	//Point the PC to the System Memory reset vector
	__set_MSP(*(uint32_t *)addr);	//Set the Main Stack Pointer

	SysMemBootJump();				//Run our virtual function defined above that sets the PC

	while(1);
}

 Now, to test this code, I am simply calling it at the very beginning of main as such:

int main(void)
{

 /* USER CODE BEGIN 1 */
USB_BootloaderInit();


 /* USER CODE END 1 */
/* USER CODE BEGIN Boot_Mode_Sequence_0 */
 int32_t timeout;
/* USER CODE END Boot_Mode_Sequence_0 */

 /* MPU Configuration--------------------------------------------------------*/
 MPU_Config();

/* USER CODE BEGIN Boot_Mode_Sequence_1 */
 /* Wait until CPU2 boots and enters in stop mode or timeout*/
 timeout = 0xFFFF;
 while((__HAL_RCC_GET_FLAG(RCC_FLAG_D2CKRDY) != RESET) && (timeout-- > 0));
 if ( timeout < 0 )
 {
 Error_Handler();
 }

But, when I get on STM32Cube Programmer, I do not see the device. I have tried using the debugger, but I think I am running into different issues because of the dual core nature of this. I would get errors from random things. The one that particularly stumped me is this line:
SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4))); //Point the PC to the System Memory reset vector

would consistently trigger a hard fault error (IMPRECISSER)

I have looked around the forum posts that exist and I do not think I have found something quite like my issue.

Thank you for your time!

 

    This topic has been closed for replies.
    Best answer by FBL

    Hi @ilikeCODINGbutitdoesntlikeME 

    DFU and CDC are different USB protocols. You need to implement a composite device for your application to switch to DFU mode.

     

    Here is an article on how to implement the USB device composite class USB DFU + HID. You can follow the same principle to implement your CDC application.

     

    2 replies

    Super User
    September 17, 2025

    Here is code for jumping to the bootloader that works. Note the line that says __enable_irq.

    How to jump to system bootloader from application ... - STMicroelectronics Community

     

    Don't jump from within an interrupt.

    Don't disable caches that aren't enabled.

    Ensure the M4 core isn't booting, or has code that won't interfere with the bootloader.

    Explorer
    September 18, 2025

    Thank you for your response!
    I think the key thing I was missing that you pointed out was disabling things that were never enabled. The program counter is now going to 0x1FF0CD4C, which, from my understanding, is the bootloader. 

    However, I still cannot see the device under the DFU tab of STM32Prog. Do you have any other advice?

    The bootloader is v9.1, and Nothing is connected to the board (I do not expect the PB15 thing to be an issue). Does PB15 need to be set in order for it to boot?

     

    Thanks!

    Super User
    September 18, 2025

    Did you enable interrupts? Post your updated code.

    FBLAnswer
    Technical Moderator
    September 23, 2025

    Hi @ilikeCODINGbutitdoesntlikeME 

    DFU and CDC are different USB protocols. You need to implement a composite device for your application to switch to DFU mode.

     

    Here is an article on how to implement the USB device composite class USB DFU + HID. You can follow the same principle to implement your CDC application.

     
    Explorer
    September 23, 2025

    I've determined it has something to do with the stuff being initialized on startup, so I ended up just having a check flag that is written in a RAM section that does not get overwritten. Then, on reset, the assembly code forces the STM32H745 into the bootloader. This has been a very repeatable way to do this, although I am unsure if CubeIDE/CubeMX overwrite this file yet.

     

    Thank you all for your help!