2025-09-17 2:55 PM - last edited on 2025-09-17 4:05 PM by Andrew Neil
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!
2025-09-17 3:12 PM
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.