基於RT-Thread完整版搭建的極簡Bootloader

嵌入式小美老師 發佈 2024-04-01T11:39:01.870357+00:00

這裡我就用事實來證明並非如此,完全可以裁剪到 Nano 一樣的大小,並且 RT-Thread 完整版 還支持 menuconfig 不需要自己添加代碼文件,真香。

項目背景

Agile Upgrade: 用於快速構建 Bootloader 的中間件。

  • example 文件夾提供 PC 上的示例

特性

  1. 適配 RT-Thread 官方固件打包工具 (圖形化工具及命令行工具)
  2. 使用純 C 開發,不涉及任何硬體接口,可在任何形式的硬體上直接使用
  3. 加密、壓縮支持如下:
  4. AES256
  5. fastlz
  6. quicklz

  7. 原生適配 file 及 fal 操作接口
  8. 移植簡單,實現自定義的後端只需適配幾個操作接口
  9. 使用簡單,幾行代碼即可實現固件升級
  10. 全過程日誌輸出
  11. 提供過程回調,可將過程及進度顯示在自定義硬體上


  12. 基於 RT-Thread 4.1.0 版本
  13. 基於正點原子探索者開發板

代碼地址:

https://github.com/loogg/agile_upgrade_mcu_demOS

https://github.com/loogg/agile_upgrade

(請複製至外部瀏覽器打開)

  • 目錄結構

2、Bootloader

一般 Bootloader 實現的邏輯如下:

嵌入式物聯網需要學的東西真的非常多,千萬不要學錯了路線和內容,導致工資要不上去!

無償分享大家一個資料包,差不多150多G。裡面學習內容、面經、項目都比較新也比較全!某魚上買估計至少要好幾十。

點擊這裡找小助理0元領取:點擊文中文領取


這種方式適合於簡單的裸機程序或可控的 OS 程序(即所有外設硬體都可把控),在準備環境的時候將其全部關閉。

但對於一些複雜的或者 OS 中輪子已造好的程序,有一些因素不花時間研究無法把控,在準備環境時很可能就會遺漏一些未關閉導致出各種各樣的問題。

這裡提供一種 萬能 方法:

- 利用晶片中的不受軟體復位影響的可供用戶使用的寄存器 (如 STM32 中的備份寄存器)。
- 在需要跳入 APP 運行時將該寄存器賦值然後軟體復位。
- 在 OS 還沒初始化時判斷該寄存器值,如果需要跳轉只需要簡單的準備環境即可跳轉。

該方法可以使 Bootloader 就作為一個 OS 應用程式開發,需要跳轉的時候就操作一下寄存器並軟體復位即可。

該倉庫下所有的 Bootloader 例子均使用此方法。

以正點原子探索者開發板的 stm32f4 為例,將 system_stm32f4xx.c 文件的 SystemInit 函數修改:

1void boot_start_application(void);
2void SystemInit(void)
3{
4 boot_start_application();
5
6 ...
7}

boot_start_application 的實現為:

1typedef void (*boot_app_func)(void);

2void boot_start_application(void) {
3 __HAL_RCC_PWR_CLK_ENABLE();
4 HAL_PWR_EnableBkUpAccess();
5
6 RTC_HandleTypeDef RTC_Handler = {0};
7 RTC_Handler.Instance = RTC;
8 uint32_t bkp_data = HAL_RTCEx_BKUPRead(&RTC_Handler, BOOT_BKP);
9 HAL_RTCEx_BKUPWrite(&RTC_Handler, BOOT_BKP, 0);
10
11 if (bkp_data != 0xA5A5) return;
12
13 boot_app_func app_func = NULL;
14 uint32_t app_addr = BOOT_APP_ADDR;
15 if (((*(__IO uint32_t *)(app_addr + 4)) & 0xff000000) != 0x08000000) return;
16
17 /* 棧頂地址在 128K RAM 間 */
18 if (((*(__IO uint32_t *)app_addr) - 0x20000000) >= (STM32_SRAM_SIZE * 1024)) return;
19
20 app_func = (boot_app_func) * (__IO uint32_t *)(app_addr + 4);
21 /* Configure main stack */
22 __set_MSP(*(__IO uint32_t *)app_addr);
23 /* jump to application */
24 app_func();
25}

設置寄存器並軟體復位的實現為:

1static void boot_app_enable(void) {
2 __disable_irq();
3 RTC_HandleTypeDef RTC_Handler = {0};

4 RTC_Handler.Instance = RTC;
5 HAL_RTCEx_BKUPWrite(&RTC_Handler, BOOT_BKP, 0xA5A5);
6 HAL_NVIC_SystemReset();
7}

3、RT-Thread 完整版、RT-Thread Nano 及裸機對比

3.1、RTOS 與裸機

很多人都會覺得裸機開發比 RTOS 簡單並且編譯出來的空間小的多,但以我的開發經驗來說並非如此。

  1. 開發難易程度
  2. 裸機
  3. 裸機開發經常使用的是前後台框架,一個有多步執行操作的 task 基本上都是使用 switch case 方式。
  4. 一級延時很好處理只需要改變 task 的再一次進入時間即可。
  5. 嵌套延時則需要加狀態位並在函數中嵌套 switch case,程序非常臃腫。
  6. RTOS
  7. RTOS 中多步操作只需按順序調用函數即可,掛起也只需調用系統提供的 API ,代碼精簡且邏輯清晰。
  8. 資源占用
  9. 以 RT-Thread Nano 舉例,官方給出的數據如下:

1在運行兩個線程 (main 線程 + idle 線程) 情況下,ROM 和 RAM 依然保持著極小的尺寸。
2以下是基於 Cortex M3 的 MDK 工程編譯結果 (優化等級 3)
3
4Total RO Size (Code + RO Data) 4000 ( 3.91kB)
5Total RW Size (RW Data + ZI Data) 1168 ( 1.14kB)
6Total ROM Size (Code + RO Data + RW Data) 4092 ( 4.00kB)
7

從數據中可以得知資源占用並沒有相差非常大。

3.2、RT-Thread 完整版與 RT-Thread Nano

許多人對於這兩個的爭議在於:RT-Thread 完整版 資源占用太大,小晶片用不了等等。

這裡我就用事實來證明並非如此,完全可以裁剪到 Nano 一樣的大小,並且 RT-Thread 完整版 還支持 menuconfig 不需要自己添加代碼文件,真香。

同時 RT-Thread 還有許多純 C 語言的不涉及硬體的軟體包,使用 menuconfig 拿來即用,真香。

這裡我以正點原子探索者開發板 bsp 為例,基於 RT-Thread v4.1.0 版本,具體工程查看 RTT_Template。

  • CubeMX 生成的 MDK 工程編譯結果 (優化等級 0)

1Total RO Size (Code + RO Data) 8120 ( 7.93kB)
2Total RW Size (RW Data + ZI Data) 1832 ( 1.79kB)
3Total ROM Size (Code + RO Data + RW Data) 8136 ( 7.95kB)
4

  • 在運行兩個線程 (main 線程 + idle 線程) 情況下的 MDK 工程編譯結果 (優化等級 0), 適配了 rt_hw_console_output
1Total RO  Size (Code + RO Data)                13256 (  12.95kB)
2Total RW  Size (RW Data + ZI Data)              3136 (   3.06kB)
3Total ROM Size (Code + RO Data + RW Data)      13396 (  13.08kB)
4
兩者比較差值1Total RO  Size (Code + RO Data)                 5136 (   5.02kB)
2Total RW  Size (RW Data + ZI Data)              1304 (   1.28kB)
3Total ROM Size (Code + RO Data + RW Data)       5260 (   5.14kB)
4


從上述數據可以得出結論:RT-Thread 完整版

 通過裁剪可以完全媲美 RT-Thread Nano

,所以首選 RT-Thread 完整版
。
4、Bootloader 工程使用tools 文件夾下包含了固件打包工具和應用層固件 app.bin
,起始地址為 0x08080000
。應用層分區如下:
在應用程式中下載固件需要使用 ymodem_ota -p [dst]
 命令,[dst]
 為目標分區 download_w25q
 或 download_onchip
。以下工程編譯結果都是基於 優化等級 0
。4.1、MinimalistBoot 使用該工程下提供 3 個配置文件,通過 ENV
 工具的 menuconfig
 Load
 配置並 save
 為 .config
 後執行 scons --target=mdk5 -s
 即可生成工程。該工程未使用動態內存分配,故編譯結果即為真實內存使用。配置文件分別為:.config.minimal
、.config.w25q_qlz
 和 .config.Shell_qlz
。.config.minimal
極簡 Bootloader
,不支持壓縮和加密類型固件,下載分區為 download_onchip
。.config.w25q_qlz
支持 quicklz
 方式壓縮的固件,下載分區為 download_w25q
。.config.shell_qlz
支持 quicklz
 方式壓縮的固件,升級失敗可通過敲擊鍵盤 Enter
 鍵進入 Shell
,下載分區為 download_onchip
。4.2、FalBoot 使用該工程基於 FAL
 組件,提供 4 個配置文件,通過 ENV
 工具的 menuconfig
 Load
 配置並 save
 為 .config
 後執行 scons --target=mdk5 -s
 即可生成工程。配置文件分別為:.config.minimal
、.config.dev_qlz
、.config.w25q_dev_qlz
 和 .config.shell_dev_qlz
。.config.minimal
不支持壓縮和加密類型固件,下載分區為 download_onchip
。.config.dev_qlz
使用了設備框架,支持 quicklz
 方式壓縮的固件,下載分區為 download_onchip
。.config.w25q_dev_qlz
使用了設備框架,支持 quicklz
 方式壓縮的固件,下載分區為 download_w25q
。.config.shell_dev_qlz
使用了設備框架,支持 quicklz
 方式壓縮的固件,升級失敗可通過敲擊鍵盤 Enter
 鍵進入 Shell
,下載分區為 download_onchip。


轉載自:RTThread物聯網作業系統

文章來源於基於RT-Thread完整版搭建的極簡Bootloader

原文連結:https://mp.weixin.qq.com/s/A3lMMsFBavKS2-a4MC68Kg

關鍵字: