单片机 Bootloade与二进制文件的生成

news/2025/2/27 13:16:59/

单片机的 Bootloader 是一种特殊的程序,负责在单片机上电后初始化硬件、更新用户应用程序(固件),并将控制权移交给用户程序。以下是其运行机制和关键流程的详细说明:

1、单片机 Bootloader 的核心作用

固件更新:通过通信接口(如 UART、USB、CAN、I2C、SPI 等)接收新固件,写入 Flash 存储。

程序跳转:根据条件(如按键触发、标志位)决定运行 Bootloader 还是用户程序。
硬件初始化:配置时钟、外设、通信模块等。

安全校验:对固件进行 CRC 校验或数字签名验证,防止错误或恶意代码写入。.

2、单片机 Bootloader 的运行流程

1.上电启动
硬件复位
单片机上电后,CPU 从固定地址(如0x00000000)开始执行代码,通常指向Bootloader 的入口。
部分单片机(如 STM32)支持从不同存储区域启动(通过 BOOT 引脚选择启动 Bootloader 或用户程序)。

初始化硬件
配置时钟、GPIO、通信接口(如 UART/USB)、Flash 控制器等。

2.判断运行模式
Bootloader 模式:
检测触发条件(如按键按下、特定引脚电平、通信端口收到特定指令)。
若触发条件满足,进入固件更新流程。
用户程序模式:
若未触发,直接跳转到用户程序起始地址(如0x08000000,需与应用程序的链接脚本一致)。

3、固件更新流程

3.1 等待接收固件数据

通知上位机(PC 或主机设备)开始传输固件。
固件通常以二进制(.bin)或十六进制(.hex)格式传输,包含起始地址、数据长度、校验信息。

3.2 擦除 Flash

擦除用户程序存储区。

3.3 写入 Flash

按数据包逐块写入 Flash,同时进行 CRC 校验。
若校验失败,重传或报错。

3.4 写入 Flash

写入结束标志,复位或跳转到用户程序。

3.5 跳转到用户程序

关闭 Bootloader 使用的外设。
设置APP起始地址。

4、 Bootloader 设计的关键技术

4.1 存储空间划分

如一个芯片FLASH大小为512K
Bootloader 区: 占用 Flash 起始部分(如 0x00000000~0x00010000),大小按需制定,需在编译时指定。
用户程序区: 从 Bootloader 区之后开始(如 0x00010000~0x0007F000)。
配置区: 在 Flash 或 EEPROM 中存储标志,通常运用最后一页(4K)作为配置区,大小按需制定。在配置内可以存储固件升级标志、固件升级方式、固件大小、固件检验值、固件版本号等。(如0x0007F000~ 0x00080000)
在这里插入图片描述

4.2 安全机制

CRC 校验: 确保数据传输完整性。
数字签名: 使用非对称加密(如 RSA)验证固件来源。
写保护: 防止误写 Bootloader 区域(通过 Flash 保护位)。

5. 单片机 Bootloader 实现实例

以新塘M480芯片为例。升级方式可以通过串口、CAN、蓝牙、U盘等信道。
当前处于APP重新中:
步骤1:上位机触发固件升级。
步骤2:擦除配置区。对于Flash来说最小擦写单位为 块(Block)扇区(Sector) 擦除(如 4KB、64KB)。故最小擦除4K。将配置区数据写入配置区
步骤3:设置中断向量映射地址,将向量地址映射为0x00000000。
步骤4:进行系统复位。
切换到bootload中
步骤5:初始化外设。
步骤6:读取配置区标志。
步骤7:根据配置区配置进行后续工作,是进行固件升级还是跳入APP执行。
步骤8:在进行固件升级的情况下获取固件升级包内容。
步骤9:接收到一定数量的配置信息,如4K(FLASH最小擦写单位),在写入之前可以先擦除需要写的内存,写入后需要再读出来进行验证。
步骤10:完成最后一包数据的写入。
步骤11:为跳转到APP做准备。清除外设配置、设置中断向量映射地址,将向量地址映射到APP地址。
步骤12:进行系统复位。

伪代码操作

\\APP中的运行代码
失能中断;
iap_flag = 0xAA; //设置升级标志
擦除FLASH(配置页地址,配置页大小);
写入FLASH((配置页地址,配置页大小,配置数据);
向量映射(0x00000000);
系统复位;
使能中断;
\\boot中的运行代码
初始化外设;
失能中断;
读取FLASH(配置页地址,配置页大小,配置数据)
使能中断;
各类校验等操作;
发送升级原因、升级包数量、固件大小等;
发送升级包请求;
获取到一定数量的升级包;
将升级包擦写读FLASH;
完成最后一包的写入;
发送升级结果;
清除外设设置;
向量映射(APP开始地址);
系统复位;

6、烧录文件类型

1.hex 文件
Intel HEX 格式,包含程序代码和烧录地址信息。
由 IDE(如 Keil、STM32CubeIDE)编译生成。
适用工具:ST-Link Utility、J-Flash等。

2.bin 文件
纯二进制文件,仅包含代码数据,需手动指定烧录地址。
适用工具:STM32CubeProgrammer、J-Link Commander、串口烧录工具、NuMicro ICP Programming Tool等。

3. 注意事项
烧录地址:
.bin文件需指定正确的起始地址(如 Flash 起始地址 0x08000000)。
.hex文件已包含地址信息,无需手动设置。

通常Bootloader代码与APP实现代码分开实现。则boot.bin与app.bin需要进行合并。

IMAGE.bin = boot.bin + app.bin;
DATA.bin = 配置信息;

在这里插入图片描述
若需要通过各类信道升级固件。

UPDATE.bin = 配置信息 +  app.bin; 

在这里插入图片描述
若配置区长度固定也可以写入文件低地址,应用程序区写高地址。由读取升级固件实现方式决定。

7、合并文件实现
利用python实现

这里主要阐述原理
if __name__ == "__main__":  #主函数
#利用sys模块引入参数 import sys
sys.argv[0]  #第一个参数
sys.argv[1]  #第二个参数
sys.argv[n+1]  #第n个参数  
#获取到需要的参数如:需要合成的文件1、需要合成的文件2、每页大小、输出的文件名、版本号等、CRC校验等、输出的文件路径等。

文件处理路径生成

def vfile_path(path_config):path = os.path.normpath(os.path.abspath(输出路径))  # 路径规范化print(f"输出路径: {path}")完整路径 = path + "\\" + 输出文件名try:Path( 完整路径).resolve()except OSError as e:  #判断路径是否合法print(f"路径非法: {e.strerror}")dir = os.path.dirname(完整路径) #路径提取if not os.path.exists(dir):os.makedirs(parent_dir,mode=0o777, exist_ok=False)  # 递归创建目录#print(f"创建父目录: {parent_dir}")return parent_dir

输出文件名拼接

info = [列表元素1,列表元素2,列表元素3,.....,列表元素n]
文件名="".join(info)

合成二进制文件

 with open(合成的文件1, 'rb') as app,open(输出的文件名, 'wb') as image:  #读取第一个文件的内容,打开app文件,使用'wb'代表以二进制覆盖的形式写入
os.path.isfile(合成的文件1) #判断文件是否存在
os.path.getsize(合成的文件1)  #判断文件是大小
#若写入的文件较大,可以利用divmod(文件大小、分段大小)分段写入
for _ in range(分段):
image.write(app.read(分段大小))  #读取合成的文件1 写入输出的文件。
if 最后一段余大小 > 0:
image.write(app.read(最后一段余大小))  #读取合成的文件1 写入输出的文件。
fp_image.write(b"\xff" * (int(页大小,10) - 最后一段余大小))          #补充最后一页内容重复上述步骤with open(合成的文件2, 'rb') as app,open(输出的文件名, 'ab') as image:  #读取第二个文件的内容,打开app文件,使用参数 "ab"代表以二进制追加的形式写入

写入具体内到二进制文件

通过zlib.crc32函数能够获取数据的CRC校验
endianness = sys.byteorder  #通过返回值可以判断大小端 big大端  little小端
通过 struct.pack可以将数据打包位二进制数据流
with open(输出文件,'wb') as fp:fp.write(struct.pack打包的数据流)
若后续需要再写入其他数据这以'ab'增加的形式写入数据

http://www.ppmy.cn/news/1575253.html

相关文章

【Linux】调试工具GDB的使用及案例讲解

Linux系列 文章目录 Linux系列前言一、gdb的使用背景二、gdb的使用总结 本篇主要针对小白讲解,可以很多地方比较咯嗦 前言 GDB是Linux下一款强大的调试工具。GDB可以调试C、C、Java等语言,对于在Linux下工作的程序员来说,GDB是必不可少的调试…

一文2500字从0到1实现压测自动化!

大家好,我是小码哥,最近工作有点忙,一直在实现压测自动化的功能,今天来分享一下实现思路 我所在的业务线现在项目比较少了,所以最近一个月我都没有做业务测试,需求开发完后RD直接走免测就上线,…

蓝桥杯18582-真人鉴定器

蓝桥杯18582-真人鉴定器 介绍 真人鉴定功能是一种常见的网络安全措施,用于保护网站免受机器人或自动化程序的恶意攻击。该功能基于人类视觉能力,要求用户在访问网站时通过切换右边轮播图,识别与左边要求的图片个数相符的图片,并…

STM32-智能台灯项目

一、项目需求 1. 红外传感器检测是否有人,有人的话实时检测距离,过近则报警;同时计时,超过固定时间则报警; 2. 按键 1 切换工作模式:智能模式、按键模式、远程模式; 3. 智能模式下,根…

TLS与自签名证书的创建、作用、用到的工具等知识的介绍

一、OpenSSL 与KeyTool 1.1、OpenSSL 1.1、是什么 OpenSSL 是一个跨平台密码学工具套件,它实现了安全套接层(SSL)和传输层安全(TLS)的协议栈,还提供了各种加密算法(如对称加密(如 A…

力扣 807. 保持城市天际线(Java实现)

题目分析 给定一个二维数组,行列长度相等,要保持四个方向仍一观察高度不变的情况下,适当添加建筑高度,问最大高度增量和。所谓四个方向高度不变的增量,其实就是arr[i][j]与同i行最大值同j列最大值之间的最小值的差&…

物联网综合实训室建设方案的探讨(职业院校物联网综合实训室建设方案)

随着物联网技术的迅猛发展,社会对物联网人才的需求日益增加。为了满足这一需求,高校和职业院校纷纷开始建设物联网综合实训室,以培养具备实际操作能力和创新思维的高素质物联网人才。本文旨在探讨一种行之有效的物联网综合实训室建设方案&…

C# 弃元的使用

总目录 前言 在C# 7.0及更高版本中,弃元(Discard)是一个新的语言特性,允许开发者在特定情况下忽略某些值。弃元用下划线 _ 作为占位符,明确表示忽略某个值,提升代码可读性 一、弃元是什么? 1.…