基于RT-Thread完整版搭建的极简Bootloader
项目背景
Agile Upgrade: 用于快速构建 bootloader 的中间件。
example文件夹提供 PC 上的示例
特性
适配
RT-Thread官方固件打包工具 (图形化工具及命令行工具)使用纯 C 开发,不涉及任何硬件接口,可在任何形式的硬件上直接使用
加密、压缩支持如下:
AES256
fastlz
quicklz
原生适配 file 及 fal 操作接口
移植简单,实现自定义的后端只需适配几个操作接口
使用简单,几行代码即可实现固件升级
全过程日志输出
提供过程回调,可将过程及进度显示在自定义硬件上
基于 RT-Thread 4.1.0 版本
基于正点原子探索者开发板

代码地址:
https://github.com/loogg/agile_upgrade_mcu_demos
https://github.com/loogg/agile_upgrade
(请复制至外部浏览器打开)
目录结构

2、Bootloader
一般 Bootloader 实现的逻辑如下:

这种方式适合于简单的裸机程序或可控的 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();56 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 简单并且编译出来的空间小的多,但以我的开发经验来说并非如此。
开发难易程度
裸机
裸机开发经常使用的是前后台框架,一个有多步执行操作的
task基本上都是使用switch case方式。一级延时很好处理只需要改变
task的再一次进入时间即可。嵌套延时则需要加状态位并在函数中嵌套
switch case,程序非常臃肿。RTOS
RTOS 中多步操作只需按顺序调用函数即可,挂起也只需调用系统提供的 API ,代码精简且逻辑清晰。
资源占用
以 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。

———————End———————
你可以添加微信:rtthread2020 为好友,注明:公司+姓名,拉进RT-Thread官方微信交流群!

↓点击阅读原文报名
爱我就请给我在看
相关文章:
基于RT-Thread完整版搭建的极简Bootloader
项目背景Agile Upgrade: 用于快速构建 bootloader 的中间件。example 文件夹提供 PC 上的示例特性适配 RT-Thread 官方固件打包工具 (图形化工具及命令行工具)使用纯 C 开发,不涉及任何硬件接口,可在任何形式的硬件上直接使用加密、压缩支持如下…...
3.flinkDateStreamAPI介绍env与source
执行环境 Flink可以在不同的环境上下文中运行.可以本地集成开发环境中运行也可以提交到远程集群环境运行. 不同的运行环境对应的flink的运行过程不同,需要首先获取flink的运行环境,才能将具体的job调度到不同的TaskManager 在flink中可以通过StreamExecutionEnvironment类获取…...
$ 2 :数据类型
1.数据类型 1.1基本类型 a、整型int b、浮点型float c、字符型char 1.2构造类型 a、数组[ ] b、结构体struct 1.3指针类型 * 1.4空类型(void) 2.关键字 autoconstdoublefloatintshortstructunsignedbreakcontinueelseforlongsignedswitchvoidcasedefaultenumgotoregistersiz…...
类和对象 - 上
本文已收录至《C语言》专栏! 作者:ARMCSKGT 目录 前言 正文 面向过程与面向对象 面向过程的解决方法 面向对象的解决方法 面向对象的优势 类的引入 早期C类的实现 class定义类 class定义规则 类成员的两种定义方式 类的访问限定符及封装 访…...
补档:红黑树代码实现+简略讲解
红黑树讲解和实现1 红黑树介绍1.1 红黑树特性1.2 红黑树的插入1.3 红黑树的删除2 完整代码实现2.1 rtbtree.h头文件2.2 main.c源文件1 红黑树介绍 红黑树( Red-Black tree,简称RB树)是一种自平衡二叉查找树,是计算机科学中常见的一种数据结构,…...
FirePower X2 14.0.1 for RAD Studio Alexandria
介绍 FirePower X2 FirePower X2 集成了 RAD Studio 11.0 Alexandria 中的新功能,并预览了我们的新特色组件 TwwDataGrouper。 FirePower X2 还允许您为 Apple 的新 M1 芯片构建应用程序,这样您就可以进一步利用 M1 芯片来提高本机应用程序的性能&#x…...
二十九、MongoDB 恢复数据( mongorestore )
MongoDB mongorestore 脚本命令可以用来恢复备份的数据 语法 MongoDB mongorestore 命令脚本语法如下 $ mongorestore -h <hostname><:port> -d dbname <path> 参数说明 -h <:port>, -h<:port> MongoDB 所在服务器地址,默认为 l…...
【数据分析】缺失数据如何处理?pandas
本文目录1. 基础概念1.1. 缺失值分类1.2. 缺失值处理方法2. 缺失观测及其类型2.1. 了解缺失信息2.2. 三种缺失符号2.3. Nullable类型与NA符号2.4. NA的特性2.5. convert_dtypes方法3. 缺失数据的运算与分组 3.1. 加号与乘号规则3.2. groupby方法中的缺失值4. 填充与剔除4.1. fi…...
嵌入式开发--STM32H750VBT6开发中,新版本CubeMX的时钟问题,不能设置到最高速度480MHZ
嵌入式开发–STM32H750VBT6开发中,新版本CubeMX的时钟问题,不能设置到最高速度480MHZ 问题描述 之前开发的项目,开发环境是CubeMX6.6.1,H7系列的支持包版本是1.10.0。跑得没问题,最近需要对项目做修改,同…...
一文读懂PaddleSpeech中英混合语音识别技术
语音识别技术能够让计算机理解人类的语音,从而支持多种语音交互的场景,如手机应用、人车协同、机器人对话、语音转写等。然而,在这些场景中,语音识别的输入并不总是单一的语言,有时会出现多语言混合的情况。例如&#…...
问题三十四:傅立叶变换——高通滤波
高通滤波器是一种可以通过去除图像低频信息来增强高频信息的滤波器。在图像处理中,高通滤波器常常用于去除模糊或平滑效果,以及增强边缘或细节。在本篇回答中,我们将使用Python和OpenCV实现高通滤波器。 Step 1:加载图像并进行傅…...
flink 键控状态(keyed state)
github开源项目flink-note的笔记。本博客的实现代码都写在项目的flink-state/src/main/java/state/keyed/KeyedStateDemo.java文件中。 项目github地址: github 1. flink键控状态 flink键控状态是作用与flink KeyedStream上的,也就是说需要将DataStream先进行keyby之后才能使…...
【ChatGPT】sqlachmey 多表连表查询语句
感受下科技带来的魅力,这篇文章是通过ChatGPT自动生成的,不得不说技术强大!!! 在SQLAlchemy中进行多表连接查询可以使用join()方法或join()函数,具体用法如下: join()方法 join()方法可以在SQLAlchemy ORM中的查询中使用。假设…...
win11 系统登录问题,PIN 设置问题
我的电脑配置是华为MateBook X Pro 12,i7处理器,16G,1T,win11 系统通过微软账户登录,下午一直登录不进去,网络能连外网,分析应该是连微软服务器不行。连续登录几十次,偶尔可能有一次…...
数据结构六大排序
1.插入排序 思路: 从第一个元素开始认为是有序的,去一个元素tem从有序序列从后往前扫描,如果该元素大于tem,将该元素一刀下一位,循环步骤3知道找到有序序列中小于等于的元素将tem插入到该元素后,如果已排序…...
快速生成QR码的方法:教你变成QR Code Master
目录 简介: 具体实现步骤: 一、可以使用Python中的qrcode和tkinter模块来生成QR码。以下是一个简单的例子,演示如何在Tkinter窗口中获取用户输入并使用qrcode生成QR码。 1)首先需要安装qrcode模块,可以使用以下命令在终端或命令…...
tensorflow1.14.0安装教程--保姆级
//方法不止一种,下面仅展示一种。 注:本人电脑为win11,anaconda的python版本为3.9,但tensorflow需要python版本为3.7,所以下面主要阐述将python版本改为3.7后的安装过程以及常遇到的问题。 1.首先电脑安装好anaconda…...
AcWing算法提高课-3.1.3香甜的黄油
宣传一下算法提高课整理 <— CSDN个人主页:更好的阅读体验 <— 题目传送门点这里 题目描述 农夫John发现了做出全威斯康辛州最甜的黄油的方法:糖。 把糖放在一片牧场上,他知道 N 只奶牛会过来舔它,这样就能做出能卖好价…...
私库搭建1:Nexus 安装 Docker 版
本文内容以语雀为准 文档 https://hub.docker.com/r/sonatype/nexus3Docker 安装:https://www.yuque.com/xuxiaowei-com-cn/gitlab-k8s/docker-install 安装 创建文件夹 由于 Nexus 的数据可能会很大,比如:作为 Docker、Maven 私库时&…...
LeetCode-面试题 05.02. 二进制数转字符串【数学,字符串,位运算】
LeetCode-面试题 05.02. 二进制数转字符串【数学,字符串,位运算】题目描述:解题思路一:简单暴力。小数点后面的二进制,now首先从0.5开始之和每次除以2。然后依次判断当前数是否大于now,是则答案加1。若等于…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...
CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...
