程序员开发实例大全宝库

网站首页 > 编程文章 正文

基于RT-Thread完整版搭建的极简Bootloader

zazugpt 2024-08-22 04:42:20 编程文章 14 ℃ 0 评论

项目背景

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

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表