STM32F4通过SoftReset跳转到Bootloader,没有BOOT0和BOOT1引脚

时间:2014-12-10 13:53:57

标签: c bootloader stm32 stm32f4discovery

我问,因为可以在这里找到类似问题的答案:Jump to Bootloader in STM32 through appliction i.e using Boot 0 and Boot 1 Pins in Boot mode from User flash

用户“JF002”@ JF002回答“当我想跳转到引导加载程序时,我在其中一个备份寄存器中写入一个字节,然后发出软复位。然后,当处理器重新启动时,就在在程序开始时,它将读取该寄存器。该寄存器包含指示它应该在引导加载程序模式下重启的值。然后,跳转到引导加载程序就容易得多了“

有人可以一步一步向我解释该解决方案或显示代码示例吗? 在这个时候,我写了我的考试,我非常依赖于帮助这个,因为它只是编程的一小部分,我没有经验。

2 个答案:

答案 0 :(得分:2)

我认为User @ JF002所指的“备份寄存器”是STM32上的SRAM。以下对我有用:

使用以下命令在程序开头配置备份寄存器:

RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
PWR_BackupAccessCmd(ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE);
PWR_BackupRegulatorCmd(ENABLE);

使用以下程序在程序中将A_VALUE写入备份寄存器:

(*(__IO uint32_t *) (BKPSRAM_BASE + OFFSET)) = A_VALUE;

其中OFFSET是要在SRAM中写入的地址。使用0作为第一个地址。

使用NVIC_SystemReset()发出软重置命令。

在启动时,请阅读(*(__IO uint32_t *) (BKPSRAM_BASE + OFFSET))并检查A_VALUE

RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
PWR_BackupAccessCmd(ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE);
PWR_BackupRegulatorCmd(ENABLE);    

void (*SysMemBootJump)(void);
volatile uint32_t addr = 0x1FFF0000; // For STM32F4 Discovery

if((*(__IO uint32_t *) (BKPSRAM_BASE + 0)) == A_VALUE) 
{
  (*(__IO uint32_t *) (BKPSRAM_BASE + 0)) = 0; // Reset memory, if desired.

  SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4))); // Set Bootloader address

  __set_MSP(*(uint32_t *)addr); // Move Stack Pointer

  SysMemBootJump(); // Execute Bootloader
}
else
{
  RunYourApplication();
}

答案 1 :(得分:0)

我对男人的回答有一个小问题。我的问题是,在打开系统电源时,选择的任何内存位置的值与A_VALUE相同的可能性不为零。如果发生这种情况,则该软件无法判断它读取的值(A_VALUE)是由于在软复位之前已将其写入内存位置还是仅由于随机机会。

如果OP采用前者,则系统会不适当地启动引导加载程序,从而有可能破坏软件。如果他/她承担后者,则将缺少所需的引导负载。都不可接受。

一种改进将是具有更安全的身份验证,其中将随机模式写入到只要系统通电即可保存的内存块中,并且CRCC(循环冗余码检查)在该块上竞争。然后在软重启时,再次计算CRCC。如果答案仍然有效,则说明该块是完整的,并且可以认为引导是由软重启引起的。

完美吗?不会,但是内存字节块中的所有位碰巧产生正确的CRCC值的概率远小于少数几个位导致读取值A_VALUE的概率。