int main(void){ GPIO_InitTypeDef GPIO_InitDef; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); GPIO_InitDef.GPIO_Pin = GPIO_Pin_13; GPIO_InitDef.GPIO_Mode = GPIO_Mode_IN; GPIO_InitDef.GPIO_OType = GPIO_OType_PP; GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitDef.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOA, &GPIO_InitDef); uint32_t pin = !GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_13); GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitDef); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, DISABLE); void (*SysMemBootJump)(void); if ( (*((unsigned long *)0x2001C000) == 0xDEADBEEF) || pin || !app_ok()) {//Memory map, datasheet *((unsigned long *)0x2001C000) = 0xCAFEFEED; //Reset bootloader trigger __set_MSP(0x20001000); //Point the PC to the System Memory reset vector (+4) //AN2606 //Table 64. Bootloader device-dependent parameters SysMemBootJump = (void (*)(void)) (*((uint32_t *) 0x1FFF0004)); SysMemBootJump(); while (1); }else{ uint32_t stack = ((const uint32_t *)APP_START)[0]; uint32_t entry = ((const uint32_t *)APP_START)[1]; asm volatile( "msr msp, %0 \n\t" "bx %1 \n\t" : : "r" (stack), "r" (entry) ); while(1); } }
void checkForBootLoaderRequest(void) { uint32_t bt; __PWR_CLK_ENABLE(); __BKPSRAM_CLK_ENABLE(); HAL_PWR_EnableBkUpAccess(); bt = (*(__IO uint32_t *) (BKPSRAM_BASE + 4)) ; if ( bt == 0xDEADBEEF ) { (*(__IO uint32_t *) (BKPSRAM_BASE + 4)) = 0xCAFEFEED; // Reset our trigger // Backup SRAM is write-back by default, ensure value actually reaches memory // Another solution would be marking BKPSRAM as write-through in Memory Protection Unit settings SCB_CleanDCache_by_Addr((uint32_t *) (BKPSRAM_BASE + 4), sizeof(uint32_t)); void (*SysMemBootJump)(void); __SYSCFG_CLK_ENABLE(); SYSCFG->MEMRMP |= SYSCFG_MEM_BOOT_ADD0 ; uint32_t p = (*((uint32_t *) 0x1ff00000)); __set_MSP(p); //Set the main stack pointer to its defualt values SysMemBootJump = (void (*)(void)) (*((uint32_t *) 0x1ff00004)); // Point the PC to the System Memory reset vector (+4) SysMemBootJump(); while (1); } }