ST意法半导体
直播中

王斌

7年用户 1323经验值
私信 关注
[问答]

STM32F042从应用程序进入引导加载程序,无法进行连接怎么解决?

下面的代码显示了我当前尝试实现到引导加载程序的跳转:


  • #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。







回帖(1)

王学超

2023-1-6 11:24:05
****************************************************** ************************
编辑:实施时要小心!设置 BOOT_SEL = 0 禁用物理引导引脚工作。这会产生一些非常严重的影响——如果固件升级失败,则无法让设备进入引导加载程序模式(因为进入引导加载程序的代码不存在)。要恢复设备,您必须使用 ST Link 调试器连接并重新编程。
****************************************************** ************************
供将来参考/任何搜索相同问题的人:
在请求引导加载程序时调用的函数中:


  • void StartBootloader(void)
  • {
  •     /* The STM32F042 has:
  •      * 6k SRAM in address: 0x2000 0000 - 0x2000 17FF
  •      */
  •     *((unsigned long *)0x200017F0) = 0xDEADBEEF;

  •     // Reset the processor
  •     NVIC_SystemReset();

  •     /* We then do a check in SystemInit() at startup to see if this 'magic number' has been set */
  • }

我们在启动时在 SystemInit() 中进行检查:


  • void SystemInit(void)
  • {
  •     /* Check if we should go into bootloader mode.
  •      *
  •      * Set the main stack pointer __set_MSP() to its default value.  
  •      *
  •      * Note that 0x1FFFC400 is "System Memory" start address for STM32F042
  •      */

  •     if( *((unsigned long *)0x200017F0) == 0xDEADBEEF )
  •     {
  •         *((unsigned long *)0x200017F0) =  0xCAFEFEED; // Reset our magic trigger
  •         __set_MSP(0x20001800); // set main stack pointer to start of stack

  •                                                        // 0x1fffC400 is "System Memory" start address for STM32F042
  •         SysMemBootJump = (void (*)(void)) (*((uint32_t *) 0x1fffC404)); // Point the PC to the System Memory reset vector (+4)
  •         SysMemBootJump();
  •     }
  •     ...
  •     //Normal SystemInit code here
  •     ...
  • }

为了使其正常工作,BOOTMODE 配置寄存器必须如下所示:


  • 引导选择 = 0
  • nBOOT0 = 1

注意:寄存器值和引导配置特定于 STM32F042。这应该适用于其他芯片,但您需要找到正确的堆栈值、RAM 地址结束等。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分