基于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。若等于…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
云安全与网络安全:核心区别与协同作用解析
在数字化转型的浪潮中,云安全与网络安全作为信息安全的两大支柱,常被混淆但本质不同。本文将从概念、责任分工、技术手段、威胁类型等维度深入解析两者的差异,并探讨它们的协同作用。 一、核心区别 定义与范围 网络安全:聚焦于保…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...
边缘计算网关提升水产养殖尾水处理的远程运维效率
一、项目背景 随着水产养殖行业的快速发展,养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下,而且难以实现精准监控和管理。为了提升尾水处理的效果和效率,同时降低人力成本,某大型水产养殖企业决定…...
云原生安全实战:API网关Envoy的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关 作为微服务架构的统一入口,负责路由转发、安全控制、流量管理等核心功能。 2. Envoy 由Lyft开源的高性能云原生…...
多模态学习路线(2)——DL基础系列
目录 前言 一、归一化 1. Layer Normalization (LN) 2. Batch Normalization (BN) 3. Instance Normalization (IN) 4. Group Normalization (GN) 5. Root Mean Square Normalization(RMSNorm) 二、激活函数 1. Sigmoid激活函数(二分类&…...
运动控制--BLDC电机
一、电机的分类 按照供电电源 1.直流电机 1.1 有刷直流电机(BDC) 通过电刷与换向器实现电流方向切换,典型应用于电动工具、玩具等 1.2 无刷直流电机(BLDC) 电子换向替代机械电刷,具有高可靠性,常用于无人机、高端家电…...
湖北理元理律师事务所:债务清偿方案中的法律技术革新
文/金融法律研究组 当前债务服务市场存在结构性矛盾:债权人追求快速回款,债务人需要喘息空间。湖北理元理律师事务所通过创新法律技术,在《企业破产法》《民法典》框架下构建梯度清偿模型,实现多方利益平衡。 一、个人债务优化的…...
RabbitMQ work模型
Work 模型是 RabbitMQ 最基础的消息处理模式,核心思想是 多个消费者竞争消费同一个队列中的消息,适用于任务分发和负载均衡场景。同一个消息只会被一个消费者处理。 当一个消息队列绑定了多个消费者,每个消息消费的个数都是平摊的&a…...
【汇编逆向系列】四、函数调用包含单个参数之Double类型-mmword,movsd,mulsd,addsd指令,总结汇编的数据类型
一、汇编代码 上一节开始,讲到了很多debug编译独有的汇编方式,为了更好的区分release的编译器优化和debug的区别,从本章节开始将会提供debug和release的汇编用作对比 Debugb编译 single_double_param:00000000000000A0: F2 0F 11 44 24 08…...
