STM32 Bootloader 跳轉到App


1.什么是Bootloader

Bootloader是硬件啟動的引導程序,是運行操作系統的前提。在操作系統內核或用戶應用程序運行之前運行的一段小代碼。對硬件進行相應的初始化和設定,最終為操作系統准備好環境。

2.Bootloader的特點

Bootloader不屬於操作系統,一般采用匯編語言和C語言開發。需要針對特定的硬件平台編寫。在移植過程時,首先為開發板移植Bootloader。Bootloader不但依賴於CPU的體系架構,而且依賴於嵌入式系統板級設備的配置。

3.STM32中bootloader的內存分配

stm32默認的是從0x08000000開始啟動程序,所以bootloader也存在於這個地址,大小可以設置。如下圖舉例分配 48K的大小空間給Bootloader

 

內存分配 地址 大小
Bootloader 0x08000000 --- 0x0800c000 48K
Application 0x0800c000 --- 0x0802C000 128K
Free Space 0x0802C000 --- 0x08xxxxxx  ---

還有一種分配方式:鏡像的備份  Firmware --->  Application Bak ---> SysRest ----> Bootloader -----> Check if new Firmware -----> Move App Bak to App area

 這種方式需要更大的存儲空間,如果MCU內置FLASH 不夠備份Firmware則需要外置Flash,將Firmware備份在外置FLASH。

內存分配 地址 大小
Bootloader 0x08000000 --- 0x0800c000 48K
Application 0x0800c000 --- 0x0802C000 128K
Application Bak 0x0802C000 --- 0x0804C000 128K
Free Space  0x0804C000 --- 0x08xxxxxx   ---

根據實際MCU的Flash的大小和固件的大小來分配空間。一般可以把固件信息(app固件的StartAddr, EndAddr, FirmwareSize, CRC等)存放在Free Spae.

 

bootloader的作用一般是用作更新APP,和初始化后設定跳轉到對應的APP。如果APP不加更新功能的話也可以直接將APP寫入到0x08000000這個地址里。更新程序就是數據包的接收、校驗、寫入,全部寫入完成后檢查APP的啟動向量為合格就可以跳轉到APP里。

 

 

4. Bootloader的跳轉簡單實現

4.1 Bootloader

我基於STM32Cube配置的外設,IDE用的STM32SW4,STM32F103RCT6。

在實現IAP功能前,先實現跳轉。這里先不涉及固件更新。

/*FLASH  : 0x8000000  --- 0x8040000    Total Size: 256K
 *RAM  : 0x20000000 --- 0x2000C000    Total Size: 48K
 *Bootloader: 0x8000000 --- 0x8008000   Total Size: 32K

*/

  1 /* Includes ------------------------------------------------------------------*/
  2 #include "main.h"
  3 #include "stm32f1xx_hal.h"
  4 #include "usart.h"
  5 #include "gpio.h"
  6 
  7 /* USER CODE BEGIN Includes */
  8 #include "stdio.h"
  9 /* USER CODE END Includes */
 10 
 11 /* USER CODE BEGIN PFP */
 12 /* Private function prototypes -----------------------------------------------*/
 13 pFunction jump2app;
 14 void (*jump2app)();
 15 /* USER CODE END PFP */
 16 
 17 
 18 
 19 /* USER CODE BEGIN 0 */
 20 #ifdef __GNUC__
 21     #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
 22 #else
 23     #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
 24 #endif
 25 
 26 /*retargets the C library printf function to the USART*/
 27 PUTCHAR_PROTOTYPE
 28 {
 29     HAL_UART_Transmit(&huart1,(uint8_t*)&ch, 1, 0xFFFF);
 30     return ch;
 31 }
 32 
 33 //FLASH            : 0x8000000  --- 0x8040000       Total Size: 256K
 34 //RAM           : 0x20000000 --- 0x2000C000       Total Size: 48K
 35 //Bootloader     : 0x8000000 --- 0x8008000     Total Size: 32K 
 36  
37
#define ApplicationAddress 0x8008000 38 39 40 void iap_load_app(uint32_t appAddr) 41 { 42 printf("first word : 0x%x\n",(*(uint32_t*)appAddr)); 43 if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000) 44 { 45 printf("IAP load APP!!!\n"); 46 47 __disable_irq(); 48 49 jump2app = (void (*)())*(__IO uint32_t*) (appAddr + 4); 50 51 __set_MSP(*(__IO uint32_t*) appAddr); 52 53 jump2app(); 54 } 55 }
56 /* USER CODE END 0 */ 57 58 /** 59 * @brief The application entry point. 60 * 61 * @retval None 62 */ 63 int main(void) 64 { 65 /* USER CODE BEGIN 1 */ 66 67 /* USER CODE END 1 */ 68 69 /* MCU Configuration----------------------------------------------------------*/ 70 71 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ 72 HAL_Init(); 73 74 /* USER CODE BEGIN Init */ 75 76 /* USER CODE END Init */ 77 78 /* Configure the system clock */ 79 SystemClock_Config(); 80 81 /* USER CODE BEGIN SysInit */ 82 83 /* USER CODE END SysInit */ 84 85 /* Initialize all configured peripherals */ 86 MX_GPIO_Init(); 87 MX_USART1_UART_Init(); 88 /* USER CODE BEGIN 2 */ 89 90 /* USER CODE END 2 */ 91 92 /* Infinite loop */ 93 /* USER CODE BEGIN WHILE */ 94 while (1) 95 { 96 printf("I am bootloader,jump to app after 5 seconds!\n"); 97 98 HAL_Delay(1000); 99 100 printf("1\r\n"); 101 102 HAL_Delay(1000); 103 104 printf("2\r\n"); 105 106 HAL_Delay(1000); 107 108 printf("3\r\n"); 109 110 HAL_Delay(1000); 111 112 printf("4\r\n"); 113 114 HAL_Delay(1000); 115 116 printf("ready to jump!\n"); 117 118 iap_load_app(ApplicationAddress); 119 /* USER CODE END WHILE */ 120 121 /* USER CODE BEGIN 3 */ 122 123 } 124 /* USER CODE END 3 */ 125 126 }

修改ld文件 STM32F103RCTx_Flash.ld

 

 編譯燒錄。首先將STM32F103RCT6的FLASH全部擦除如下圖,然后用STM32SW4燒錄Bootloader

 

 

 

 調試Bootloader如下圖

 

 

4.2 Application

APP主要是修改ld文件,Bootloader分配了 32Kb, 剩余224K的先全分配給App, 實現簡單跳轉。

 

 

 

 1 int main(void)
 2 {
 3     //NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x2000);
 4   /* USER CODE BEGIN 1 */
 5     SCB->VTOR = ((uint32_t)0x8000000) | (0x8000 & (uint32_t)0x1FFFFF80);
 6   /* USER CODE END 1 */
 7 
 8   /* MCU Configuration----------------------------------------------------------*/
 9 
10   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
11   HAL_Init();
12 
13   /* USER CODE BEGIN Init */
14 
15   /* USER CODE END Init */
16 
17   /* Configure the system clock */
18   SystemClock_Config();
19 
20   /* USER CODE BEGIN SysInit */
21 
22   /* USER CODE END SysInit */
23 
24   /* Initialize all configured peripherals */
25   MX_GPIO_Init();
26   MX_USART1_UART_Init();
27   /* USER CODE BEGIN 2 */
28   __enable_irq();
29   /* USER CODE END 2 */
30 
31   /* Infinite loop */
32   /* USER CODE BEGIN WHILE */
33   while (1)
34   {
35      printf("I am new APP !\n\r");
36 
37      HAL_Delay(1000);
38   /* USER CODE END WHILE */
39 
40   /* USER CODE BEGIN 3 */
41 
42   }
43   /* USER CODE END 3 */
44 
45 }

 

再將APP燒錄,Reset 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM