要求:将BOOT0保持为高电平,以便STM32在首次连接到计算机时处于DFU模式。计算机软件可以闪存或立即离开到 0x08000000 运行闪存程序。
问题:当 BOOT0 保持高电平时,DFU 离开命令不起作用。
潜在的解决方案:用户已经在 STMF4 产品上解决了这个问题,因为它具有 Cortex-M3/M4 https://community.st.com/t5/stm32-mcus-embedded-software/leave-dfu-while-boot0 -is-high-stm32f4/td-p/556307
取消注释此行也可以解决这些产品的问题。
#define USER_VECT_TAB_ADDRESS
但是我还没有找到 Cortex-M0 (STM32F072RBT) 的分步解决方案的资源
我尝试过重新定位向量表并从 SRAM 启动。然而,由于我从未找到明确的方法来做到这一点,我相信我所有的尝试都损坏了代码。
大图动机:发布 PCB 上没有按钮或开关的产品 (STM32F072RBT),并允许客户通过 USB 串行接口刷新并与其产品交互。
我试图为我正在开发的产品做一些相同的事情。 STM 代表建议以下解决方案:始终启动到您的应用程序,但当您的应用程序希望进入 DFU 模式时,向您尚未使用的 RAM 区域写入一个神奇值并触发软重置,然后在应用程序启动检查过程中尽早进行对于神奇值,而不是运行正常的启动序列,跳转到系统引导加载程序。
您需要在 AN2606 中查找芯片的正确系统引导加载程序地址。下面的代码使用 STM32C011xx 的地址
// See Section STM32C011xx devices bootloader in AN2606
#define STM32C011xx_SYSTEM_BL_START_ADDR 0x1FFF0000 // FIXME: use address for your chip
// Pick somewhere in RAM that isn't currently used (soft reset doesn't wipe RAM itself)
#define STM32_SYSTEM_BL_MAGIC_ADDR 0x200003FC
// Something unique
#define STM32_SYSTEM_BL_MAGIC_VALUE 0xC0C1C2C3
void Reboot_To_Dfu(void)
{
*((volatile uint32_t *) STM32_SYSTEM_BL_MAGIC_ADDR) = STM32_SYSTEM_BL_MAGIC_VALUE;
// Memory barriers
__DSB();
__ISB();
// Soft reset
NVIC_SystemReset();
while (1);
}
void Handle_Dfu_Switch(void)
{
// Check if we should go into bootloader mode
if (*((volatile uint32_t *) STM32_SYSTEM_BL_MAGIC_ADDR) == STM32_SYSTEM_BL_MAGIC_VALUE) {
// Reset our trigger
*((volatile uint32_t *) STM32_SYSTEM_BL_MAGIC_ADDR) = 0x00000000;
uint32_t stack_pointer = ((const uint32_t *) STM32C011xx_SYSTEM_BL_START_ADDR)[0];
uint32_t jump_addr = ((const uint32_t *) STM32C011xx_SYSTEM_BL_START_ADDR)[1];
// Redirect vector table
SCB->VTOR = STM32C011xx_SYSTEM_BL_START_ADDR;
// Change MSP and PSP
__set_MSP(stack_pointer);
__set_PSP(stack_pointer);
// Memory barriers
__DSB();
__ISB();
void (*SysMemBootJump)(void) = (void (*)(void)) (jump_addr);
SysMemBootJump();
while (1);
}
}
在您的 system_stm32xyz.c 中(其中
xyz
取决于您的芯片)将此行放在 SystemInit
函数的顶部:
void SystemInit(void)
{
// Consider jumping to DFU instead of normal boot
Handle_Dfu_Switch();
// typical SystemInit code continues here...
}
我最终没有使用这个,所以我不是 100% 它有效,如果你尝试一下并且它对你有效,我会很高兴知道。