1. 什么是Bootloader
Bootloader是硬件啟動的引導(dǎo)程序,是運行操作系統(tǒng)的前提。在操作系統(tǒng)內(nèi)核或用戶應(yīng)用程序運行之前運行的一段小代碼。對硬件進行相應(yīng)的初始化和設(shè)定,最終為操作系統(tǒng)準備好環(huán)境。
2. Bootloader的特點
Bootloader不屬于操作系統(tǒng),一般采用匯編語言和C語言開發(fā)。需要針對特定的硬件平臺編寫。在移植過程時,首先為開發(fā)板移植Bootloader。Bootloader不但依賴于CPU的體系架構(gòu),而且依賴于嵌入式系統(tǒng)板級設(shè)備的配置。
3. STM32中bootloader的內(nèi)存分配
stm32默認的是從0x08000000開始啟動程序,所以bootloader也存在于這個地址,大小可以設(shè)置。如下圖舉例分配 48K的大小空間給Bootloader
還有一種分配方式:鏡像的備份 Firmware ---> Application Bak ---> SysRest ----> Bootloader -----> Check if new Firmware -----> Move App Bak to App area
這種方式需要更大的存儲空間,如果MCU內(nèi)置FLASH 不夠備份Firmware則需要外置Flash,將Firmware備份在外置FLASH。
根據(jù)實際MCU的Flash的大小和固件的大小來分配空間。一般可以把固件信息(app固件的StartAddr, EndAddr, FirmwareSize, CRC等)存放在Free Spae.
bootloader的作用一般是用作更新APP,和初始化后設(shè)定跳轉(zhuǎn)到對應(yīng)的APP。如果APP不加更新功能的話也可以直接將APP寫入到0x08000000這個地址里。更新程序就是數(shù)據(jù)包的接收、校驗、寫入,全部寫入完成后檢查APP的啟動向量為合格就可以跳轉(zhuǎn)到APP里。
4. Bootloader的跳轉(zhuǎn)簡單實現(xiàn)
4.1 Bootloader
我基于STM32Cube配置的外設(shè),IDE用的STM32SW4,STM32F103RCT6。
在實現(xiàn)IAP功能前,先實現(xiàn)跳轉(zhuǎn)。這里先不涉及固件更新。
/*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
調(diào)試Bootloader如下圖
4.2 Application
APP主要是修改ld文件,Bootloader分配了 32Kb, 剩余224K的先全分配給App, 實現(xiàn)簡單跳轉(zhuǎn)。
int main(void) { //NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x2000); /* USER CODE BEGIN 1 */ SCB->VTOR = ((uint32_t)0x8000000) | (0x8000 & (uint32_t)0x1FFFFF80); /* USER CODE END 1 */ /* MCU Configuration----------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ __enable_irq(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { printf("I am new APP !\n\r"); HAL_Delay(1000); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
再將APP燒錄,Reset
編輯:hfy
-
cpu
+關(guān)注
關(guān)注
68文章
10863瀏覽量
211799 -
操作系統(tǒng)
+關(guān)注
關(guān)注
37文章
6827瀏覽量
123335 -
STM32
+關(guān)注
關(guān)注
2270文章
10900瀏覽量
356092 -
bootloader
+關(guān)注
關(guān)注
2文章
235瀏覽量
45630
發(fā)布評論請先 登錄
相關(guān)推薦
評論