(STM32F4) IAP程式碼實現
IAP學習, 主要想了解實際上程式碼放在不同的Flash位置如何轉跳且執行。
我的應用程序只做了Pin12, Pin13 LED閃爍來分辨我的 App1 跟 App2的程式碼
App1 程式碼
1 int main(void) 2 { 3 Delay_Init(); 4 LED_Config(); 5 EXIT_GPIO_Config(); 6 printf("\n--------------------------------------------------\n"); 7 printf("\n STM32F4 IAP APP1 \n"); 8 printf("\n--------------------------------------------------\n"); 9 10 /* Flash unlock */ 11 FLASH_If_FlashUnlock(); 12 13 /* Test if User button on the Discovery kit is pressed */ 14 if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == Bit_RESET) 15 { 16 /* Check Vector Table: Test if user code is programmed starting from address 17 "APPLICATION_ADDRESS" */ 18 if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000) 19 { 20 /* Jump to user application */ 21 JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4); 22 Jump_To_Application = (pFunction) JumpAddress; 23 /* Initialize user application's Stack Pointer */ 24 __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS); 25 Jump_To_Application(); 26 } 27 } 28 29 while(1) 30 { 31 GPIOD->ODR |= GPIO_Pin_13; 32 DelayMs(200); 33 GPIOD->ODR &= ~GPIO_Pin_13; 34 DelayMs(200); 35 } 36 37 }
App2 程式碼
1 int main(void) 2 { 3 Delay_Init(); 4 LED_Config(); 5 EXIT_GPIO_Config(); 6 printf("\n--------------------------------------------------\n"); 7 printf("\n STM32F4 IAP APP2 \n"); 8 printf("\n--------------------------------------------------\n"); 9 10 while(1) 11 { 12 GPIOD->ODR |= GPIO_Pin_12; 13 DelayMs(200); 14 GPIOD->ODR &= ~GPIO_Pin_12; 15 DelayMs(200); 16 } 17 18 }
App1 轉跳 App2 經過一個IO的判斷去決定是否轉跳, 在App2的程式碼內也要指定程式碼放的位置。
分別是 system_stm32f4xx.c 理頭的 VECT_TAB_OFFSET 必須修改成App2的位置
Flash 位置也要改成從0x8010000開始
轉跳代碼
1 /* Flash unlock */ 2 FLASH_If_FlashUnlock(); 3 4 /* Test if User button on the Discovery kit is pressed */ 5 if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == Bit_RESET) 6 { 7 /* Check Vector Table: Test if user code is programmed starting from address 8 "APPLICATION_ADDRESS" */ 9 if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000) 10 { 11 /* Jump to user application */ 12 JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4); 13 Jump_To_Application = (pFunction) JumpAddress; 14 /* Initialize user application's Stack Pointer */ 15 __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS); 16 Jump_To_Application(); 17 } 18 }
第9行 APPLICATION_ADDRESS必須定義成APP2 Flash 存放的Address, 這段代碼在STM官方網站理頭都下載得到
#define APPLICATION_ADDRESS (uint32_t)0x08010000 if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)
在我的代碼裡頭, 在開機時只需要把 PA0 接到 GND, LED 閃爍的就是P12的LED。
App1 Code 位置從 0x8000000 開使堆疊(Stack)
App2 Code 位置從 0x8010000 開始堆疊(Stack)