下面的代码显示了我当前尝试实现到引导加载程序的跳转:
- #define ApplicationAddress 0x1FFFC400
- void JumpBootloader(void)
- {
- typedef void (*pFunction)(void); // defines function pointer for bootloader jump
- /* Set System memory address plus 4 bytes */
- uint32_t JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);
- pFunction Jump_To_Boot = (pFunction) JumpAddress;
- // /* Set main stack pointer
- // * This must be done last otherwise all other variables might get mangled! */
- __set_MSP(*(__IO uint32_t*) ApplicationAddress);
- Jump_To_Boot();
- }
当在 BOOT 引脚拉高的情况下调用此函数时,微控制器正确地重新启动进入引导加载程序模式,尽管在大约一秒钟的轻微延迟之后(可以听到 Windows 连接和断开连接的声音)是公认的。
当通过 BOOT 引脚浮动/拉低调用时(注意我在正常操作期间使用此引脚驱动 LED),设备像以前一样在一小段延迟后断开连接,但随后无法连接,给出错误“设备描述符请求失败” .
我查看了其他线程/
论坛并尝试了各种不同的方法,例如在调用上述函数之前取消初始化所有外围设备,将系统内存重新映射到 0x0 (__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();),并在行为上进行不同的更改。例如,下面的代码在调用后简单地跳回用户应用程序:
- void JumpBootloader(void)
- {
- typedef void (*pFunction)(void);
- pFunction JumpToApplication;
- uint32_t JumpAddress = 0x1FFFC400;
- Device_DeInit();
- HAL_RCC_DeInit();
- SysTick->CTRL = 0;
- SysTick->LOAD = 0;
- SysTick->VAL = 0;
- JumpToApplication = (void (*)(void)) (*((uint32_t *)(JumpAddress + 4)));
- /* Initialize user application's Stack Pointer */
- __set_MSP(*(__IO uint32_t*) JumpAddress);
- JumpToApplication();
- }
- void Device_DeInit(void)
- {
- USBD_Stop(&hUsbDeviceFS);
- USBD_DeInit(&hUsbDeviceFS);
- HAL_TIM_Base_Stop_IT(&htim16);
- HAL_SPI_DeInit(&hspi1);
- HAL_DMA_DeInit(&hdma_spi1_tx);
- HAL_DMA_DeInit(&hdma_spi1_rx);
- HAL_TIM_Base_MspDeInit(&htim16);
- HAL_GPIO_DeInit(LED_USB_GPIO_Port, LED_USB_Pin);
- HAL_GPIO_DeInit(LED_AXIOM_GPIO_Port, LED_AXIOM_Pin);
- HAL_DeInit();
- }
我在这里错过了一个关键点吗?是否有任何我没有满足的先决条件?
如果有任何问题,我正在使用 USB DFU。