STM32 Bootloader:使用文件头加载并启动应用程序

文章目录

  • STM32 Bootloader:使用文件头加载并启动应用程序的完整解析
    • 一、系统整体流程
    • 二、镜像头结构 image\_header\_t
    • 三、Bootloader 主函数流程
      • 1. 初始化 UART
      • 2. 调用启动函数
      • 3. 拷贝 APP 并跳转启动
    • 四、跳转执行 APP 的实现
    • 五、总结与扩展思路


明白了,以下是去除表情后的正式技术文章版本:


STM32 Bootloader:使用文件头加载并启动应用程序的完整解析

在嵌入式系统中,Bootloader 是系统启动的第一段程序,它的主要职责是加载应用程序、校验完整性以及为远程升级提供支持。本文将结合一个基于 STM32 的 Bootloader 实例,详细讲解如何借助镜像头(Image Header)从 Flash 中加载并执行主应用程序。


一、系统整体流程

本文的 Bootloader 实现具有以下基本功能流程:

  1. 初始化 UART,输出启动信息;
  2. 从指定的 Flash 地址读取应用程序头部结构;
  3. 解析镜像头部,获取程序加载地址和大小;
  4. 将应用程序从 Flash 拷贝到 RAM;
  5. 设置中断向量表并跳转到应用程序入口地址。

流程图如下:

启动 Bootloader↓
读取 image_header_t↓
解析 ih_load / ih_size↓
Flash → RAM 拷贝程序数据↓
配置向量表↓
跳转执行 APP

二、镜像头结构 image_header_t

为了描述应用程序的信息,Bootloader 使用一个自定义的数据结构 image_header_t,包含如下字段:

typedef struct image_header {__be32 ih_magic;      // 魔数,用于识别合法镜像__be32 ih_hcrc;       // 头部 CRC 校验值__be32 ih_time;       // 镜像生成时间戳__be32 ih_size;       // 应用程序大小(单位:字节)__be32 ih_load;       // 应用加载地址__be32 ih_ep;         // 程序入口地址__be32 ih_dcrc;       // 数据部分 CRC 校验uint8_t ih_os;        // 操作系统标识uint8_t ih_arch;      // CPU 架构uint8_t ih_type;      // 镜像类型uint8_t ih_comp;      // 压缩类型uint8_t ih_name[32];  // 镜像名称
} image_header_t;

为了确保头部字段正确读取,还实现了 be32_to_cpu 函数来转换大端字节序为当前平台字节序:

unsigned int be32_to_cpu(unsigned int x) {unsigned char *p = (unsigned char *)&x;return (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3];
}

三、Bootloader 主函数流程

1. 初始化 UART

uart_init();
putstr("bootloader\r\n");

用于串口输出调试信息。

2. 调用启动函数

unsigned int app_pos = 0x08040000;
relocate_and_start_app(app_pos);

指定 APP 存放在 Flash 的 0x08040000 位置。

3. 拷贝 APP 并跳转启动

relocate_and_start_app 是整个 Bootloader 的核心函数,负责:

  • 解析头部信息;
  • 读取加载地址和大小;
  • 拷贝程序数据到目标 RAM 区域;
  • 设置向量表基地址;
  • 跳转到新的应用入口。
void relocate_and_start_app(unsigned int pos) {image_header_t *head = (image_header_t *)pos;unsigned int load = be32_to_cpu(head->ih_load);unsigned int size = be32_to_cpu(head->ih_size);unsigned int new_pos = pos + sizeof(image_header_t);putstr("load = "); puthex(load); putstr("\r\n");putstr("size = "); puthex(size); putstr("\r\n");copy_app((int *)new_pos, (int *)load, size);start_app(new_pos);  // 跳转执行
}

copy_app 函数用于将应用程序从 Flash 拷贝到 RAM:

void copy_app(int *from, int *to, int len) {for (int i = 0; i < len/4+1; i++) {to[i] = from[i];}
}

四、跳转执行 APP 的实现

start_app PROCEXPORT start_app; 设置向量表地址ldr r3, =0xE000ED08  ; VTOR 寄存器地址str r0, [r3]         ; 写入新的向量表地址ldr sp, [r0]         ; 设置新栈顶ldr r1, [r0, #4]     ; 获取复位向量(入口地址)BX r1                ; 跳转执行应用ENDP

这段汇编设置了新的中断向量表,并将控制权转移到应用程序。


五、总结与扩展思路

该 Bootloader 实现了基础但关键的功能:从 Flash 加载带有文件头的应用程序,并跳转执行。这种结构使得:

  • 多固件管理更加方便;
  • 支持版本号校验、CRC 校验;
  • 可进一步扩展支持压缩、加密等功能;
  • 便于在线升级(IAP)系统实现。

后续可扩展的方向:

  1. 加入头部校验(如 CRC)确保数据完整性;
  2. 支持多应用启动(例如主应用 + 备份应用);
  3. 添加通信接口,如通过串口、USB、以太网接收新固件;
  4. 使用加密技术保护固件安全性。

如需进一步学习如何构建符合自己需求的 Bootloader,可结合具体芯片手册及启动流程,调整 向量表地址RAM 空间划分启动模式 等参数。

如果你希望支持更多启动方式,例如从 SD 卡、串口或外部 Flash 启动,也可以参考该结构扩展模块加载逻辑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/web/83668.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

无外接物理显示器的Ubuntu系统的远程桌面连接(升级版)

文章目录 操作步骤实践截图配置 Xorg 的虚拟显示界面(升级版) 操作步骤 “远程连接”,在设置里直接打开就可以.进行配置就行. 1.配置 GRUB 以支持无显示器启动 sudo nano /etc/default/grub (里面有一行改为: GRUB_CMDLINE_LINUX_DEFAULT"quiet splash videovesa:off vi…

ACCU-100安科瑞协调控制器:精准调控光伏逆变器

产品概述 ACCU-100微电网协调控制器是一款应用于微电网、分布式发电、储能等领域的智能协调控制器。它能接入光伏系统、风力发电、储能系统以及充电桩等设备&#xff0c;通过对微电网系统进行数据采集与分析&#xff0c;实时监控各类设备的运行状态和健康状况。在此基础上&…

长春光博会 | 麒麟信安:构建工业数字化安全基座,赋能智能制造转型升级

6月10日-13日&#xff0c;2025长春国际光电博览会Light国际会议&#xff08;简称长春光博会&#xff09;在长春东北亚国际博览中心盛大举行&#xff0c;吉林省委书记黄强出席并宣布开幕&#xff0c;省委副书记、省长胡玉亭致辞。本届大会聚焦光电信息领域的前沿技术和最新产品&…

书写时垂直笔画比水平笔画表现更好的心理机制分析

你有写字的时候总是垂直方向笔画好写&#xff0c;水平方向的笔画不好写的情况存在吗&#xff1f; 书写时垂直笔画比水平笔画表现更好的心理机制分析 从人类认知和行为模式的角度来理解这种现象。以下是深度心理分析&#xff1a; 核心心理动因 重力知觉内化&#xff1a; 垂直…

SpringAI使用总结

SpringAI使用总结 基本使用ChatModel和ChatClient简单对话流式输出预设角色prompt&#xff08;提示词&#xff09;function call&#xff08;工具调用&#xff09;参考 基本使用 ChatModel和ChatClient SpringAi支持非常多的模型&#xff0c;为了统一处理&#xff0c;SpringA…

历史交易数据涨跌分级

历史交易数据涨跌分级 # encoding:utf-8 import sys,traceback from loguru import loggersys.path.append("..") from QhSpiderTool import QhDorpFiled from QhCsvMode import *def QhZhangDieFenJi(QhDfData,QhFangFa"A"):"""历史交易数…

Kafka入门4.0.0版本(基于Java、SpringBoot操作)

Kafka入门4.0.0版本&#xff08;基于Java、SpringBoot操作&#xff09; 一、kafka概述 Kafka最初是由LinkedIn公司开发的&#xff0c;是一个高可靠、高吞吐量、低延迟的分布式发布订阅消息系统&#xff0c;它使用Scala语言编写&#xff0c;并于2010年被贡献给了Apache基金会&…

react react-router-dom中获取自定义参数v6.4版本之后

路由配置, AutnToken 组件作为权限、登录管理 import { createBrowserRouter, Navigate } from react-router-dom; import Layout from /layout/index; import Login from /pages/login; import Page404 from /pages/404;import AutnToken from /components/authToken; import…

AI中的Prompt

1. System 作用&#xff1a;设定 AI 的“角色设定”和“行为准则”。 内容&#xff1a;通常是描述 LLM 的身份、语气、行为范围、约束规则。 类似&#xff1a;在大语言模型中是最优先被考虑的提示。 示例&#xff1a; 你是一个专业的商品评价分析助手&#xff0c;请根据用户…

从人工到智能:IACheck如何重构检测报告审核工作流?

从人工到智能&#xff1a;IACheck如何重构检测报告审核工作流&#xff1f; 在当今AI技术迅猛发展的时代&#xff0c;各行各业正经历从“人工驱动”到“智能驱动”的根本性变革。检测认证&#xff08;TIC&#xff09;行业作为关乎质量与安全的重要支柱&#xff0c;也不例外。在…

React事件处理:如何给按钮绑定onClick点击事件?

系列回顾&#xff1a; 在前几篇文章中&#xff0c;我们已经学会了如何使用 State 管理组件的内部数据&#xff0c;以及如何通过 Props 实现父子组件之间的通信。我们的组件现在已经有了“数据”和“外观”。但是&#xff0c;它还像一个只能看的“模型”&#xff0c;无法与用户进…

【机器学习|学习笔记】粒子群优化(Particle Swarm Optimization, PSO)详解,附代码。

【机器学习|学习笔记】粒子群优化&#xff08;Particle Swarm Optimization, PSO&#xff09;详解&#xff0c;附代码。 【机器学习|学习笔记】粒子群优化&#xff08;Particle Swarm Optimization, PSO&#xff09;详解&#xff0c;附代码。 文章目录 【机器学习|学习笔记】粒…

深度剖析:AI 社媒矩阵营销工具,如何高效获客?

在社交媒体营销领域&#xff0c;竞争日益激烈&#xff0c;传统的社媒矩阵运营方式面临诸多挑战。而 AI 社媒矩阵营销工具的出现&#xff0c;正以前所未有的方式重构社媒矩阵的底层架构&#xff0c;为营销人员带来了全新的机遇与变革。接下来&#xff0c;我们将从技术破局、实战…

Spring XML 常用命名空间配置

Spring XML 常用命名空间配置 下面是一个综合性的Spring XML配置样例&#xff0c;展示了各种常用命名空间的使用方式&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans&quo…

UE5场景漫游——开始界面及关卡跳转

UE中实现UMG游戏界面搭建及蓝图控制&#xff0c;点击游戏界面中的按钮实现关卡的跳转效果。 一、游戏界面显示。1.创建UMG&#xff0c;2.搭建UI。3.关卡蓝图控制显示 二、点击按钮之后实现关卡跳转

CSS 外边距合并(Margin Collapsing)问题研究

在 CSS 中&#xff0c;margin-top 属性会导致外部 DIV 移动的现象主要是由于 外边距合并&#xff08;Margin Collapsing&#xff09; 造成的。这是 CSS 盒模型的一个特性&#xff0c;可能会与直觉相悖。 外边距合并的原理 当一个元素&#xff08;如内部 DIV&#xff09;的 ma…

清理电脑C磁盘,方法N:使用【360软件】中的【清理C盘空间】

1、先下载并打开【360安全卫士】&#xff0c;点击如下位置&#xff1a; 之后&#xff0c;可以把这个东西&#xff0c;创建快捷方式到电脑桌面&#xff0c;方便以后使用&#xff1a;

微服务集成seata分布式事务 at模式快速验证

微服务集成Seata分布式事务 本次demo代码地址业务场景&#xff1a;一般用于以下场景&#xff1a;使用 AT 模式的优势&#xff08;适用于快速验证&#xff09;&#xff1a;快速验证建议步骤&#xff1a;注意事项&#xff1a; 工具环境微服务版本选择Nacos 环境搭建与启动nacos 下…

LLM基础5_从零开始实现 GPT 模型

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 设计 LLM 的架构 GPT 模型基于 Transformer 的 decoder-only 架构&#xff0c;其主要特点包括&#xff1a; 顺序生成文本 参数数量庞大&#xff08;而非代码量复杂&#xff09; 大量重复…

Android 中 linux 命令查询设备信息

一、getprop 命令 在 Linux 系统中&#xff0c; getprop 命令通常用于获取 Android 设备的系统属性&#xff0c;这些属性包括设备型号、Android 版本、电池状态等。 1、获取 Android 版本号 adb shell getprop ro.build.version.release2、获取设备型号 adb shell getprop …