我问,因为可以在这里找到类似问题的答案:Jump to Bootloader in STM32 through appliction i.e using Boot 0 and Boot 1 Pins in Boot mode from User flash
用户“JF002”@ JF002回答“当我想跳转到引导加载程序时,我在其中一个备份寄存器中写入一个字节,然后发出软复位。然后,当处理器重新启动时,就在在程序开始时,它将读取该寄存器。该寄存器包含指示它应该在引导加载程序模式下重启的值。然后,跳转到引导加载程序就容易得多了“
有人可以一步一步向我解释该解决方案或显示代码示例吗? 在这个时候,我写了我的考试,我非常依赖于帮助这个,因为它只是编程的一小部分,我没有经验。
答案 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的概率。