问题
i ask because of an answer to a similar quastion which can be found here: Jump to Bootloader in STM32 through appliction i.e using Boot 0 and Boot 1 Pins in Boot mode from User flash
The User "JF002" @JF002 answered "When I want to jump to the bootloader, I write a byte in one of the backup register and then issue a soft-reset. Then, when the processor will restart, at the very beginning of the program, it will read this register. This register contains the value indicating that it should reboot in bootloader mode. Then, the jump to the bootloader is much easier"
Can someone explain that solution to me step-by-step or show a code example? At this time i write my exam and i am really reliant to help about this because it is only a little part with programming and i have no experience in that.
回答1:
What I think User @JF002 is referring to by "backup register" is the SRAM onboard the STM32. The following has worked for me:
Configure backup registers at the beginning of the program using:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
PWR_BackupAccessCmd(ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE);
PWR_BackupRegulatorCmd(ENABLE);
Write A_VALUE
to a backup register during your program using:
(*(__IO uint32_t *) (BKPSRAM_BASE + OFFSET)) = A_VALUE;
where OFFSET
is the address to write in SRAM. Use 0
for first address.
Issue a soft reset command using NVIC_SystemReset()
.
On boot, read (*(__IO uint32_t *) (BKPSRAM_BASE + OFFSET))
and check for 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();
}
回答2:
I have a small problem with man's answer. My problem is that there is a non-zero probability that the value of whatever memory location you pick is the same as A_VALUE when you power the system on. If that happens, then the software cannot tell whether the value that it reads (A_VALUE) is due to it having been written to the memory location prior to a soft reset, or due to random chance alone.
If the OP assumes the former, then the system starts up a bootload inappropriately with the potential of trashing the software. If he/she assumes the latter, then a required bootload will be missed. Neither is acceptable.
An improvement would be to have a more secure authentication wherein a random pattern was written to a block of memory that is saved as long as the system is powered, and a CRCC (cyclical redundancy code check) competed over that block. Then on soft reboot, the CRCC is calculated again. If the answer is still valid, the block is intact and it may be assumed that the boot was caused by a soft reboot.
Is it perfect? No, but the probability that all the bits in a block of memory bytes happens to yield the correct CRCC value is very much smaller than the probability of some small number of bits causing the value A_VALUE to be read.
来源:https://stackoverflow.com/questions/27402774/stm32f4-jump-to-bootloader-via-softreset-and-without-boot0-and-boot1-pin