一文读懂Bootloader:从原理到OTA应用

原创 无际单片机编程 2025-04-18 14:41

关注公众号,回复“入门资料”获取单片机入门到高级开挂教程

 开发板带你入门,我们带你飞

文 | 无际(微信:2777492857)

全文约4976字,阅读大约需要 10 分钟

在2016年,我在做一个网关项目时,需要实现远程固件升级功能,也就是大家常听到的OTA。

          

 

当时,我对此一窍不通,Bootloader、IAP、OTA都是啥玩意?全部都是我的知识盲区。

          

 

公司也没人教,我只能硬着头皮去学习,记得之前对接的是云智易,整个项目前前后后搞了一年,才勉强做稳定,其实还有一些BUG,APP获取子设备信息不稳定,平台的协议没设计好,链路交互不够精简。

          

 

这个项目其中有个功能就是OTA,当时我啥也不懂,厚着脸皮,这里问问,那里搜搜,又从他们平台技术支持的嫖一点,在他爱搭不理的状态下,慢慢磨出来的经验。 

          

 

一、Bootloader到底是个啥玩意儿?

简单来说,Bootloader就是单片机上电或复位后,在你的主应用程序(也就是你辛辛苦苦写的业务逻辑代码)运行之前,先跑起来的一小段特殊程序。

          

 

你可以把它想象成电脑开机时的BIOS/UEFI。电脑按下电源键,不是直接就进Windows或MacOS了对吧?得先有个东西检查下硬件,做点初始化,然后再去加载操作系统。

          

 

单片机的Bootloader干的也是类似的事情,只不过规模小得多,目标也更专一:初始化必要的硬件,然后决定是启动主应用程序,还是进入某种特殊模式(比如,准备接收新的固件)。

          

 

它通常被烧录在单片机内部或者外部Flash存储器的一个特定区域,这块区域往往还带有写保护,防止被应用程序不小心破坏掉。毕竟,如果连Bootloader都挂了,那设备很可能就真的“启动不能”了,到时候返厂维修,那成本可就上去了。    

          

 

二、为啥我们需要Bootloader?直接跑应用它不香吗?

          

 

直接跑应用当然行,很多简单的项目就是这么干的。代码编译、烧录、运行,一条龙。但问题来了,如果你的产品已经卖出去了,部署到了天南海北,这时候发现一个bug,或者想加个新功能,咋办?

          

 

总不能让用户把设备拆开,拿出J-Link/ST-Link,吭哧吭哧连上电脑,重新烧录吧?这用户体验也太差了,而且很多场景下根本不现实。

          

 

这时候,Bootloader的价值就体现出来了。它最重要的使命之一,就是实现固件的远程更新,也就是我们常说的IAP(In-Application Programming,在应用编程)或者更时髦的OTA(Over-The-Air,空中升级)。

          

 

有了Bootloader,我们就可以通过预留的通信接口(比如串口UART, USB, CAN, 以太网, 甚至无线方式如蓝牙, Wi-Fi, LoRa, NB-IoT等),给设备发送新的应用程序固件。Bootloader负责接收这些固件数据,把它写入到应用程序的存储区域,然后重新启动,加载新的程序。

          

 

总结一下Bootloader的核心优势:

1.固件更新能力:无需物理接触和专用烧录工具,即可更新设备功能或修复bug,极大降低维护成本。

2.灵活性:产品可以先发布,后续通过软件升级迭代。

3.可靠性(如果设计得好):可以设计成即使应用程序损坏,也能通过Bootloader进行恢复。    

          

 

所以你看,对于需要持续维护和升级的产品来说,Bootloader不是可有可无的点缀,而是实实在在的刚需。

          

 

三、Bootloader的工作原理

          

 

咱们来深入一点,看看Bootloader内部是怎么运作的。

          

 

1. 启动流程:

单片机上电或复位。

CPU根据内部设定,从一个固定的地址(通常是Flash的起始地址,也就是复位向量表所在位置)取出第一条指令。

如果Bootloader被放置在这个起始地址,那么CPU就开始执行Bootloader的代码。

          

 

2. 硬件初始化:

          

 

Bootloader不需要像主应用程序那样初始化所有的外设。它只需要初始化最基本的硬件,满足它的核心功能需求即可。

          

 

这通常包括:

时钟系统:让CPU和外设跑起来。

GPIO:可能需要用来检测某个引脚状态,判断是否进入升级模式,或者控制LED指示状态。    

通信接口:用于接收新固件的接口,比如UART, SPI, I2C, CAN, USB等。

          

 

3. 决策逻辑:跑应用还是搞升级?

          

 

这是Bootloader的一个关键环节。初始化完成后,它需要决定接下来干什么。常见的判断方式有:

          

 

检测特定GPIO引脚:比如,上电时长按某个按钮,Bootloader检测到这个引脚是低电平,就进入升级模式。

          

 

检查共享内存区域的标志位:应用程序可以在某个不易失存储(如Flash的特定扇区)写入一个标志,请求下次启动时进入升级模式。Bootloader启动时读取这个标志。

          

 

通信接口等待:启动后,在一定时间内(比如1-2秒)监听某个通信接口,如果收到了特定的“进入升级”指令,就进入升级模式;否则超时后就去启动应用程序。

          

 

检查应用程序有效性:计算应用程序区域的校验和(Checksum/CRC),如果校验和错误或者程序区域为空,可能强制进入升级模式。

          

 

这个决策过程,有点像Bootloader每天都要面对的灵魂拷问:“今天,我是该跳转到应用,还是留下来等等更新?”

          

 

4. 跳转到应用程序:    

          

 

如果决定运行主应用程序,Bootloader需要做几件重要的事情(以ARM Cortex-M为例):

          

 

设置主堆栈指针 (MSP):应用程序有自己的堆栈,Bootloader需要从应用程序的向量表(通常位于应用程序Flash区域的起始处)的第一个字读取MSP的初始值,并设置到CPU的MSP寄存器。

          

 

获取复位处理函数地址:应用程序的入口点不是main函数,而是复位处理函数(Reset_Handler)。这个函数的地址通常存储在应用程序向量表的第二个字。

          

 

执行跳转:获取到地址后,通过函数指针或者汇编指令,直接跳转到应用程序的Reset_Handler执行。

          

 

注意:如果应用程序使用了中断,还需要考虑中断向量表的重定向问题。通常通过修改NVIC的VTOR(Vector Table Offset Register)寄存器,将中断向量表的基地址指向应用程序的向量表。这一步可以在Bootloader跳转前完成,也可以由应用程序自己初始化时完成。

          

 

5. 进入升级模式 (IAP过程):

          

 

如果决定进入升级模式,Bootloader会:

          

 

初始化通信接口:准备接收数据。

          

 

遵循预定义的通信协议:与上位机(发送固件的工具或服务器)进行交互。协议可能很简单(比如,握手->发数据块->应答->结束),也可能比较复杂(带加密、分包、重传机制)。    

          

 

接收固件数据:通常按块(Packet/Frame)接收。

          

 

数据校验:每接收一块数据,都要进行校验(如CRC校验),确保数据在传输过程中没有损坏。

          

 

擦除Flash:在写入新数据之前,必须先擦除应用程序占用的Flash扇区。Flash存储器的特性是写之前必须先擦除,而且通常是按扇区(Sector)或块(Block)擦除的。

          

 

写入Flash:将校验通过的数据块写入到Flash的对应位置。

          

 

状态反馈:向上位机报告接收和写入的状态(成功、失败、重传请求等)。

          

 

完成与验证:全部数据接收并写入完成后,可能会进行一次整体的固件校验。然后向上位机发送完成信号。

          

 

复位:升级完成后,通常会触发一次软件复位,让CPU重新从头开始执行。这次,Bootloader检查发现无需升级(或者升级标志已被清除),就会跳转到刚刚写入的新应用程序。

          

 

四、Bootloader, IAP, OTA,别再傻傻分不清

          

 

    

这三个词经常一起出现,关系紧密但含义不同:

          

 

Bootloader:是那段程序本身,它提供了加载应用程序和执行固件更新的基础能力。

          

 

IAP (In-Application Programming):是一种技术或过程,指的是在设备运行状态下(通常是在Bootloader的引导下,或者有时甚至是应用程序自己调用特定代码)对自身的程序存储器进行擦写,以达到更新固件的目的。

          

 

OTA (Over-The-Air):是一种固件交付方式,特指通过无线通信(Wi-Fi, Bluetooth, 蜂窝网络等)将新的固件包发送到设备。设备接收到OTA包后,通常会利用其IAP能力来完成实际的烧录更新。

          

 

所以,可以说:OTA是实现远程固件更新的一种高级方式,它依赖于设备的IAP能力,而IAP能力的实现往往离不开一个健壮的Bootloader。

          

 

五、动手写一个简单的Bootloader?

          

 

想自己动手写一个Bootloader?完全可以!虽然细节不少,但核心思路是清晰的。你需要关注以下几个方面:

          

 

1. 内存规划 

你需要精确规划Flash的内存布局。哪部分给Bootloader,哪部分给应用程序,可能还需要一块用于Bootloader和应用程序通信的共享区域(比如存放升级标志)。  

          

 

    

这通常通过修改编译器的链接脚本来实现。你需要告诉链接器,Bootloader的代码和数据放在哪里,应用程序的代码和数据从哪个地址开始放。

          

 

例如,我们可以在Keil里面设置APP程序从哪个地址开始放。

 通过上图设置,告诉编译器,我们的应用程序代码是从0x800C800这个地址开始,而Bootloader的,则是从0x8000000开始。

          

 

2. 通信协议设计

          

 

拿我们无际单片机项目6举例,这个项目实现了OTA升级,设备通过WiFi和4G连接我们开发的云平台。    

          

 

WiFi和4G之间通过MQTT,而单片机到WiFi和4G模块之前通过串口通讯。

          

 

    

这样,就需要设计一个串口协议。

          

 

          

 

          

 

    

          

 

例如,定义几个命令:

查询服务器是否有新的固件版本(0x21,0x22)

MCU申请获取OTA升级固件内容(0x24,0x25)

          

 

          

 

3. 核心逻辑实现

Bootloader的main函数:

初始化时钟、GPIO、通信接口。

检查是否需要进入升级模式(CheckIfUpdateRequest())。

如果需要升级,调用 EnterUpdateMode()

如果不需要升级,调用 JumpToApplication()

          

 

跳转函数的实现(C语言示例,ARM Cortex-M):    

 

#define APP_ADDRESS    (uint32_t)0x800C800 // 假设应用程序起始地址typedef void (*pFunction)(void)// 定义函数指针类型void JumpToApplication(void){    uint32_t jumpAddress;    pFunction applicationEntry;    // 检查应用程序起始地址是否有效 (至少包含向量表)    if (((*(volatile uint32_t*)APP_ADDRESS) & 0x2FFE0000) == 0x20000000    {        // 1. 获取应用程序的堆栈顶地址 (向量表第一个字)        uint32_t appStack = *(volatile uint32_t*)APP_ADDRESS;        // 2. 设置主堆栈指针 MSP        __set_MSP(appStack);        // 3. 获取应用程序的复位处理函数地址 (向量表第二个字)        jumpAddress = *(volatile uint32_t*)(APP_ADDRESS + 4);        applicationEntry = (pFunction)jumpAddress;        // 4. 跳转到应用程序的复位处理函数        applicationEntry();    }    else    {       // 应用程序无效,可以在这里处理,比如闪烁LED报错       while(1       {       }    }}

升级模式的实现 (EnterUpdateMode()):

循环等待接收命令。

根据命令处理:擦除Flash、接收数据、校验数据、写入Flash。

使用芯片厂商提供的Flash驱动库来执行擦写操作。注意处理好擦写的时序和错误。

          

 

应用程序的注意事项:

应用程序的链接脚本也要相应修改,确保它被链接到正确的地址(APP_ADDRESS)。

如果使用了中断,应用程序需要在初始化时设置NVIC的VTOR寄存器指向自己的向量表。

          

 

六、从IAP走向OTA

          

 

实现了基本的IAP Bootloader,除了IAP的基础,OTA还需要考虑:

          

 

    

1. 无线通信栈

          

 

需要在Bootloader(或者一个专门的、可更新的下载器应用)中集成无线通信协议栈(如Wi-Fi, BLE)。这对Bootloader的大小和复杂度提出了更高的要求。有时会采用两阶段Bootloader,第一阶段极简,负责加载第二阶段(带通信能力)或应用程序。

          

 

2. 安全性

          

 

这是OTA的重中之重!

          

 

固件签名与验签:防止恶意固件被刷入。服务器用私钥对固件签名,设备用公钥验证签名,确认固件来源可靠且未被篡改。

传输加密:防止固件在传输过程中被窃听或篡改,可以使用TLS/DTLS等安全传输协议。

安全存储:密钥的安全存储也是个挑战。

          

 

3. 健壮性

          

 

断点续传:无线环境不稳定,传输中断是常事。需要机制能从中断的地方继续传输。

电源管理:升级过程中断电怎么办?需要保证设备不会变砖。常用的方法是“双备份区(Dual-Bank)”或者使用日志/状态记录来确保更新的原子性(要么完全成功,要么回滚到旧版本)。

版本管理与回滚:如果新版本有问题,需要有机制能回滚到上一个稳定版本。

          

 

    

4. 后端支持

          

 

需要有服务器来存储固件、管理设备、推送更新任务,比如我们无际单片机的项目,通过自研的云平台,配合上自己设计的协议,就能打造一套完整的物联网OTA系统。

          

 

七、Bootloader开发的“坑”

          

 

开发Bootloader时,要特别小心,因为一旦出错,后果可能很严重。几个常见的“坑”和建议:

          

 

大小限制:Bootloader占用的空间越小越好,给应用程序留出更多空间。代码要精简,避免引入不必要的库。

          

 

稳定性压倒一切:Bootloader是设备的“最后防线”,必须极其稳定。充分测试各种边界条件和异常情况(如通信错误、Flash擦写失败)。

          

 

别忘了看门狗(Watchdog):在Bootloader执行擦写Flash等耗时操作时,一定要记得“喂狗”,防止看门狗超时导致复位,让设备陷入无限重启的循环。

          

 

日志与调试:Bootloader调试起来比应用程序困难,因为它运行在系统最早期。可以利用一个UART输出最关键的日志信息,或者通过调试接口(JTAG/SWD)单步跟踪。但要小心,连接调试器可能会影响某些硬件的正常初始化。

          

 

保护机制:Flash的写保护功能一定要用起来,保护Bootloader自身不被意外修改。    

          

 

版本意识:Bootloader和应用程序都需要有明确的版本号,方便管理和问题追溯。升级时可能需要进行版本兼容性检查。

          

 

          

 

好了,关于Bootloader的原理、应用到OTA的演进,我们就聊到这里。希望这篇有点啰嗦但力求实在的文章,能帮你揭开Bootloader的神秘面纱。它虽然只是一段“开场前的小程序”,但却肩负着让设备具备“进化”能力的关键使命。从简单的串口IAP到复杂的安全OTA,Bootloader技术的发展也见证了嵌入式系统功能的不断强大。

          

 

掌握Bootloader,不仅能让你在项目开发中更加游刃有余,也是衡量一个单片机工程师能力的重要标尺之一。

          

 

    

end



下面是更多无际原创个人成长经历、行业经验、技术干货

1.电子工程师是怎样的成长之路?10年5000字总结

2.如何快速看懂别人的代码和思维

3.单片机开发项目全局变量太多怎么管理?

4.C语言开发单片机为什么大多数都采用全局变量的形式

5.单片机怎么实现模块化编程?实用程度让人发指!

6.c语言回调函数的使用及实际作用详解

7.手把手教你c语言队列实现代码,通俗易懂超详细!

8.c语言指针用法详解,通俗易懂超详细!

无际单片机编程 单片机编程、全栈孵化。
评论 (0)
  • 一、gao效冷却与控温机制‌1、‌冷媒流动设计‌采用低压液氮(或液氦)通过毛细管路导入蒸发器,蒸汽喷射至样品腔实现快速冷却,冷却效率高(室温至80K约20分钟,至4.2K约30分钟)。通过控温仪动态调节蒸发器加热功率,结合温度传感器(如PT100铂电阻或Cernox磁场不敏感传感器),实现±0.01K的高精度温度稳定性。2、‌宽温区覆盖与扩展性‌标准温区为80K-325K,通过降压选件可将下限延伸至65K(液氮模式)或4K(液氦模式)。可选配475K高温模块,满足材料在ji端温度下的性能测试需求
    锦正茂科技 2025-04-30 13:08 352浏览
  • 贞光科技代理品牌紫光国芯的车规级LPDDR4内存正成为智能驾驶舱的核心选择。在汽车电子国产化浪潮中,其产品以宽温域稳定工作能力、优异电磁兼容性和超长使用寿命赢得市场认可。紫光国芯不仅确保供应链安全可控,还提供专业本地技术支持。面向未来,紫光国芯正研发LPDDR5车规级产品,将以更高带宽、更低功耗支持汽车智能化发展。随着智能网联汽车的迅猛发展,智能驾驶舱作为人机交互的核心载体,对处理器和存储器的性能与可靠性提出了更高要求。在汽车电子国产化浪潮中,贞光科技代理品牌紫光国芯的车规级LPDDR4内存凭借
    贞光科技 2025-04-28 16:52 307浏览
  • 随着电子元器件的快速发展,导致各种常见的贴片电阻元器件也越来越小,给我们分辨也就变得越来越难,下面就由smt贴片加工厂_安徽英特丽就来告诉大家如何分辨的SMT贴片元器件。先来看看贴片电感和贴片电容的区分:(1)看颜色(黑色)——一般黑色都是贴片电感。贴片电容只有勇于精密设备中的贴片钽电容才是黑色的,其他普通贴片电容基本都不是黑色的。(2)看型号标码——贴片电感以L开头,贴片电容以C开头。从外形是圆形初步判断应为电感,测量两端电阻为零点几欧,则为电感。(3)检测——贴片电感一般阻值小,更没有“充放
    贴片加工小安 2025-04-29 14:59 283浏览
  • 浪潮之上:智能时代的觉醒    近日参加了一场课题的答辩,这是医疗人工智能揭榜挂帅的国家项目的地区考场,参与者众多,围绕着医疗健康的主题,八仙过海各显神通,百花齐放。   中国大地正在发生着激动人心的场景:深圳前海深港人工智能算力中心高速运转的液冷服务器,武汉马路上自动驾驶出租车穿行的智慧道路,机器人参与北京的马拉松竞赛。从中央到地方,人工智能相关政策和消息如雨后春笋般不断出台,数字中国的建设图景正在智能浪潮中徐徐展开,战略布局如同围棋
    广州铁金刚 2025-04-30 15:24 253浏览
  • 在智能硬件设备趋向微型化的背景下,语音芯片方案厂商针对小体积设备开发了多款超小型语音芯片方案,其中WTV系列和WT2003H系列凭借其QFN封装设计、高性能与高集成度,成为微型设备语音方案的理想选择。以下从封装特性、功能优势及典型应用场景三个方面进行详细介绍。一、超小体积封装:QFN技术的核心优势WTV系列与WT2003H系列均提供QFN封装(如QFN32,尺寸为4×4mm),这种封装形式具有以下特点:体积紧凑:QFN封装通过减少引脚间距和优化内部结构,显著缩小芯片体积,适用于智能门铃、穿戴设备
    广州唯创电子 2025-04-30 09:02 312浏览
  • 文/Leon编辑/cc孙聪颖‍2023年,厨电行业在相对平稳的市场环境中迎来温和复苏,看似为行业增长积蓄势能。带着对市场向好的预期,2024 年初,老板电器副董事长兼总经理任富佳为企业定下双位数增长目标。然而现实与预期相悖,过去一年,这家老牌厨电企业不仅未能达成业绩目标,曾提出的“三年再造一个老板电器”愿景,也因市场下行压力面临落空风险。作为“企二代”管理者,任富佳在掌舵企业穿越市场周期的过程中,正面临着前所未有的挑战。4月29日,老板电器(002508.SZ)发布了2024年年度报告及2025
    华尔街科技眼 2025-04-30 12:40 258浏览
  • 网约车,真的“饱和”了?近日,网约车市场的 “饱和” 话题再度引发热议。多地陆续发布网约车风险预警,提醒从业者谨慎入局,这背后究竟隐藏着怎样的市场现状呢?从数据来看,网约车市场的“过剩”现象已愈发明显。以东莞为例,截至2024年12月底,全市网约车数量超过5.77万辆,考取网约车驾驶员证的人数更是超过13.48万人。随着司机数量的不断攀升,订单量却未能同步增长,导致单车日均接单量和营收双双下降。2024年下半年,东莞网约出租车单车日均订单量约10.5单,而单车日均营收也不容乐
    用户1742991715177 2025-04-29 18:28 263浏览
  • 文/郭楚妤编辑/cc孙聪颖‍越来越多的企业开始蚕食动力电池市场,行业“去宁王化”态势逐渐明显。随着这种趋势的加强,打开新的市场对于宁德时代而言至关重要。“我们不希望被定义为电池的制造者,而是希望把自己称作新能源产业的开拓者。”4月21日,在宁德时代举行的“超级科技日”发布会上,宁德时代掌门人曾毓群如是说。随着宁德时代核心新品骁遥双核电池的发布,其搭载的“电电增程”技术也走进业界视野。除此之外,经过近3年试水,宁德时代在换电业务上重资加码。曾毓群认为换电是一个重资产、高投入、长周期的产业,涉及的利
    华尔街科技眼 2025-04-28 21:55 187浏览
  • 在CAN总线分析软件领域,当CANoe不再是唯一选择时,虹科PCAN-Explorer 6软件成为了一个有竞争力的解决方案。在现代工业控制和汽车领域,CAN总线分析软件的重要性不言而喻。随着技术的进步和市场需求的多样化,单一的解决方案已无法满足所有用户的需求。正是在这样的背景下,虹科PCAN-Explorer 6软件以其独特的模块化设计和灵活的功能扩展,为CAN总线分析领域带来了新的选择和可能性。本文将深入探讨虹科PCAN-Explorer 6软件如何以其创新的模块化插件策略,提供定制化的功能选
    虹科汽车智能互联 2025-04-28 16:00 220浏览
  • 你是不是也有在公共场合被偷看手机或笔电的经验呢?科技时代下,不少现代人的各式机密数据都在手机、平板或是笔电等可携式的3C产品上处理,若是经常性地需要在公共场合使用,不管是工作上的机密文件,或是重要的个人信息等,民众都有防窃防盗意识,为了避免他人窥探内容,都会选择使用「防窥保护贴片」,以防止数据外泄。现今市面上「防窥保护贴」、「防窥片」、「屏幕防窥膜」等产品就是这种目的下产物 (以下简称防窥片)!防窥片功能与常见问题解析首先,防窥片最主要的功能就是用来防止他人窥视屏幕上的隐私信息,它是利用百叶窗的
    百佳泰测试实验室 2025-04-30 13:28 457浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦