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

embedded/2025/2/26 4:37:22/

单片机的 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/embedded/167193.html

相关文章

【Python爬虫(37)】解锁分布式爬虫:原理与架构全解析

【Python爬虫】专栏简介:本专栏是 Python 爬虫领域的集大成之作,共 100 章节。从 Python 基础语法、爬虫入门知识讲起,深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑,覆盖网页、图片、音频等各类数据爬取&#xff…

Docker 与 CI/CD:自动化构建和部署

在现代软件开发中,CI/CD(持续集成/持续部署) 是一种高效的软件开发和运维方法。CI/CD 通过自动化构建、测试和部署流程,减少了人为错误,提高了软件交付的速度和质量。Docker,作为一种容器化平台&#xff0c…

设计模式-创建型模式

创建型模式组成 创建型设计模式关注的是对象的创建过程,旨在将对象的创建与使用分离,从而提高程序的灵活性和可复用性。以下是几种常见的创建型设计模式: 1. 单例模式(Singleton) 目的:确保一个类只有一…

Linux之文件系统

1.前言 文件 内容属性 文件分为被打开的文件(跟基础IO有关,在内存上)和没有被打开的文件(在磁盘上)。 在磁盘上找没有被打开的文件属于文件系统的工作 2.对硬件的理解 2.1 磁盘,服务器,机柜,机房 1.磁…

sqli-labs-master第46关

目录 报错注入 直接注入 数据库名 数据库中的表名 users表结构: users表数据: python脚本注入 直接注入 获取数据库名 获取表名 获取表结构 获取数据 布尔盲注 获取数据库名 获取表名 获取表结构 获取数据 报错注入 直接注入 数据库名…

web网络安全:SQL 注入攻击

SQL 注入攻击(SQL Injection)概述 SQL 注入(SQL Injection) 是Web应用程序中最常见的安全漏洞之一。攻击者通过在应用程序的输入字段中插入恶意SQL代码,能够操控数据库执行非预期操作,导致数据泄露、篡改甚…

当前就业形势下C++方向后端开发学习指南

文章目录 1. C后端开发的职业方向1.1 C的应用领域1.2 后端开发的职业选择 2. 当前就业形势分析2.1 C开发者的市场需求2.2 C开发者的薪资水平 3. 学习路线3.1 入门阶段:掌握基础知识3.2 进阶阶段:掌握后端开发的核心技术3.2.1 数据库与C3.2.2 网络编程 3.…

Windows 快速搭建C++开发环境,安装C++、CMake、QT、Visual Studio、Setup Factory

安装C 简介 Windows 版的 GCC 有三个选择: CygwinMinGWmingw-w64 Cygwin、MinGW 和 mingw-w64 都是在 Windows 操作系统上运行的工具集,用于在 Windows 环境下进行开发和编译。 Cygwin 是一个在 Windows 上运行的开源项目,旨在提供类Uni…