一、什么是固件升级

固件升级是指在设备已经投入使用后,通过修改设备上的固件程序,来对设备的功能、性能、安全等方面进行改进。设备的固件通常存储在非易失性存储器中,如Flash芯片。固件升级可以通过多种方式实现,如串口、USB、网络等。
固件升级的理论基础可见另一篇博客链接: link

二、为什么需要bootloader

在许多嵌入式系统中,单片机的固件需要定期升级。这些升级可能会包括修复漏洞、添加新功能或优化系统性能。在过去,升级单片机的固件通常需要专业的编程器或设备,而现在通过使用bootloader可以简化这个过程。

什么是Bootloader

Bootloader是一个小程序,用于启动和初始化单片机。它通常是预装在单片机内部的,并在每次上电或重置时自动运行。Bootloader的作用是准备好单片机的运行环境,以便启动操作系统或其他应用程序。
在单片机中使用bootloader的一个主要原因是为了方便升级固件。通过使用bootloader,我们可以在不使用专业编程器的情况下,通过传输固件数据到单片机内部来进行升级。此外,bootloader还提供了一些其他功能,例如对存储器进行擦除、校验固件完整性等。

实现bootloader

需要遵循以下步骤:
步骤1:编写bootloader程序
bootloader程序通常是C语言编写的,其中包括以下基本功能:
○ 初始化单片机的时钟、外设等
○ 读取从外部设备(如SD卡、串口等)接收的固件数据
○ 将固件数据写入内部存储器
○ 校验固件完整性
○ 启动固件
步骤2:链接和生成bootloader映像
我们需要将bootloader程序与应用程序链接起来,并生成bootloader映像文件。bootloader映像文件通常是一个可执行文件,可以通过编程器或其他工具烧写到单片机内部存储器的特定区域中。
步骤3:设计固件更新协议
固件更新协议定义了如何将固件数据传输到单片机内部,以及如何进行校验和验证。协议可以使用各种通信方式实现,例如UART、SPI或USB等。
步骤4:实现固件更新功能
固件更新功能需要在应用程序中实现。它可以在应用程序的某个特定位置中提供固件更新功能的入口点。

单片机启动代码

单片机启动代码通常存储在单片机内部存储器中,如ROM或Flash中。存储位置通常由单片机的芯片设计者预定义,并在单片机的数据手册或技术资料中有详细说明。
在单片机启动时,复位向量表指定了程序从哪个地址开始执行。这个地址通常指向存储器中的启动代码区域。启动代码区域通常包括一些基本的初始化操作,例如设置时钟、初始化寄存器、清除内存等。
在一些支持Flash存储器的单片机中,启动代码可以被修改和更新。这种方式可以实现灵活的程序更新和升级,但也需要在程序中进行相关设置和操作。
总的来说,单片机启动代码通常存储在单片机内部存储器中,并由芯片设计者预定义在复位向量表中。程序开发者需要根据单片机的数据手册或技术资料,了解存储位置和启动过程,并编写相应的启动代码,以确保程序可以正确地启动和执行。

编译生成bin文件

生成bin文件的目的是将单片机程序编译后生成一个二进制文件,用于将固件升级到单片机的内部存储器中。bin文件中存储的是单片机程序的机器指令和数据,可以直接被单片机读取和执行,实现固件升级的目的。
可以通过keil等任意的IDE来生成bin文件

程序跳转

实现程序跳转的过程中,bootloader会将程序控制权转移到用户程序的入口点,从而启动新的固件代码。这样可以保证用户程序能够正确地运行,并且避免了升级过程中由于程序跳转不正确导致的问题。实现程序跳转的理论依据是单片机中的中断和跳转指令。在单片机中,中断是一种可以使程序在执行过程中暂停并转移控制权到中断服务程序的机制。在固件升级过程中,可以通过定义一个中断服务程序,将控制权转移到这个中断服务程序中,从而实现程序跳转。具体步骤如下:
1)在程序跳转前,将中断向量表的地址设置为用户程序入口点的地址。
2)触发一个中断,将程序控制权转移到中断服务程序中。
3)在中断服务程序中,将用户程序的入口地址存储在程序计数器(PC)中,然后返回主程序。
4)主程序重新启动,开始执行用户程序。
除了中断,单片机还可以通过跳转指令来实现程序的跳转。在固件升级过程中,可以在程序跳转前使用跳转指令,将程序的控制权转移到用户程序入口点的地址处。具体步骤如下:
1)将用户程序入口点的地址存储在一个预定义的寄存器中,例如链接寄存器(LR)。
2)使用跳转指令(例如BX指令),将程序的控制权转移到链接寄存器中存储的地址处。
3)主程序重新启动,开始执行用户程序。
以上两种方式,都可以实现程序的跳转,从而实现固件升级的目的。具体采用哪种方式,取决于具体的应用场景和要求。例如,在使用bootloader进行固件升级时,常常会采用第一种方式,即通过中断来实现程序跳转,以保证固件升级的安全性和可靠性。总的来说,用bootloader实现程序跳转的意义在于实现了更加灵活和可靠的固件升级方式,同时保证了用户程序能够正确地运行。

三、工程实现

固件升级的方式主要采用IAP(In-Application Programming) 应用编程的方式实现。即通过APP程序实现将要升级的固件从外部接口写入flash中,然后通过boot loader程序实现将升级的固件覆盖原本的固件程序,然后运行升级的固件。IAP将主存储区分成两个区域,一个区域存开发者自己设计的boot loader程序,另一个区域存储真正需要运行的APP程序。boot loader程序主要作用是给单片机升级。单片机启动时,首先从boot loader程序启动;然后判断是否需要升级固件,一般情况下不需要升级,会跳到存储区另一部分的APP程序开始运行;如果需要进行升级,通过某种方式(比如wifi接收升级包等)先将接收到的程序写入存储区中APP存储的区域,写入后跳转到该未知,即实现了程序的升级。我们将flash分为四个区域,flash地址分配如下图1所示。

其实现的流程如下图2所示。首先出厂的时候将boot loader程序下载到MCU中,然后上电启动boot loader,在boot loader程序中读取参数区的是否升级的标志位,根据标志位进行升级或直接进入主应用程序。同时将MCU内置的flash(508KB)划分为四个区域:boot loader区、APP区、备份区和参数区,分别存储对应的固件数据。其中APP区为正在运行的程序,备份区为下载的新固件存放区,更新固件即将备份区复制到APP区即可。

物联沃分享整理
物联沃-IOTWORD物联网 » IOT项目固件升级指南

发表评论