OTA的学习

本文详细介绍了ESP32的OTA(Over-the-Air)升级机制,包括分区表的概念、创建和配置,以及如何进行固件升级。重点讨论了OTA升级流程,如固件下载、验签、更新和回滚策略。还涉及到数字签名在固件安全升级中的作用,以及如何在本地搭建HTTP服务器进行OTA实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、什么是OTA?

OTA升级机制可以让联网设备在固件正常运行时通过网络(WIFI或蓝牙)进行固件升级。

要想通过OTA方式进行固件升级,首先要配置设备的分区表。

二、什么是分区表?

每片ESP32的flash上,可包含多个应用程序和多种不同类型的数据(例如校准数据、文件系统数据、参数存储器数据等)。具体来说,分区表就在ESP32flash的默认偏移地址0x8000处,长度为0x1000(4KB)。

flash地址在0x9000之前的结构是固定的,第一部分是二级的BootLoader,后面紧接着就是分区表,尺寸为0x1000。分区表的主要作用就是用来管理0x9000之后的数据。

三、如何创建分区表?

我们可以创建一个分区表文件来实现,即CSV文件。下表是一张ESP32 flash大小为4M的分区表文件。

在这个分区表中,指定了两个1600KB大小的应用程序分区(APP),存放我们待升级的固件,因此我们升级的固件大小不能超过1600KB。

ESP32 SPI Flash 内有与升级相关的(至少)四个分区:OTA dataFactory AppOTA_0OTA_1。其中 FactoryApp 内存有出厂时的默认固件。

首次进行 OTA 升级时,OTA Demo 向 OTA_0 分区烧录目标固件,并在烧录完成后,更新 OTA data 分区数据并重启。

系统重启时获取 OTA data 分区数据进行计算,决定此后加载 OTA_0 分区的固件执行(而不是默认的 Factory App 分区内的固件),从而实现升级。

同理,若某次升级后 ESP32 已经在执行 OTA_0 内的固件,此时再升级时 OTA Demo 就会向 OTA_1 分区写入目标固件。再次启动后,执行 OTA_1 分区实现升级。以此类推,升级的目标固件始终在 OTA_0OTA_1 两个分区之间交互烧录,不会影响到出厂时的 Factory App 固件。

四、怎么配置OTA FLASH分区?

在创建此分区文件后,我们可以在编译项目时通过 menuconfig中配置指定自定义分区表文件。

你可以在菜单Partition Table-->Partition Table中选择为Custom partition table CSV,同时选定分区表文件。

芯片升级整体过程

首先是连接上网络。其次是定义分区表,确定OTA_0和OTA_1。

芯片从OTA_0启动然后触发OTA升级。芯片将从HTTPS服务器下载新固件并将其保存到OTA_1分区中,然后将自动更新ota_data分区数据,指示下次重启后应从OTA1分区启动。引导加载程序将读取ota_data分区中的内容并运行所选定的应用程序分区。

应用程序回滚

如果在新版应用第一次启动时发生断电或意外崩溃,则会回滚至之前正常运行的版本。

建议:尽快完成自测,防止因断电回滚。

只有 OTA 分区可以回滚。工厂分区不会回滚

回滚的主要目的是确保设备更新后正常运转。该功能可使设备在更新新版本后出现严重错误时,回滚到之前正常运行的应用版本。当设置了回滚使能,并执行完OTA升级,应用更新至新版本后,芯片可能有三种情况。

1、应用程序运行正常。esp_ota_mark_app_valid_cancel_rollback()标记合法函数将应用程序状态标记为合法 ESP_OTA_IMG_VALID,启动无限制。

2、应用程序出现严重错误,无法继续工作,必须回滚到原先版本。esp_ota_mark_app_invalid_rollback_and_reboot()标记非法重启函数将正在运行的版本标记为非法ESP_OTA_IMG_INVALID,然后重启芯片。重启后引导加载器不会选取刚才更新的版本,而是此前正常运行的版本。

 实现原理

核心流程:

1.制作升级包

2.下载升级包

3.验签升级包

4.更新程序

下载方式:

不管采用OTA方式还是有线通信方式升级,下载升级包的方式包括后台式下载和非后台式下载两种模式。

后台式下载:

在升级的时候,新固件在后台悄悄下载,即新固件下载属于应用程序功能的一部分,在新固件下载过程中,应用可以正常使用,也就是说整个下载过程对用户来说是无感的,下载完成后,系统再跳到BootLoader程序,由BootLoader完成新固件覆盖老固件的操作。比如智能手机升级Android或者iOS系统都是采用后台式方式,新系统下载过程中,手机可以正常使用。

非后台式下载:

在升级的时候,系统需要先从应用程序跳入到BootLoader程序,由BootLoader进行新固件下载工作,下载完成后BootLoader继续完成新固件覆盖老固件的操作,至此升级结束。早先的功能机就是采用非后台来升级操作系统的,即用户需要先长按某些按键进入bootloader模式,然后再进行升级,整个升级过程中手机正常功能都无法使用

新旧固件覆盖模式:

新固件替换老固件覆盖的两种方式:双区模式和单区模式。

双区模式:

双区模式中老固件和新固件在flash中各占一块bank(存储区)。假设老固件放在bank0(运行区)中,新固件放在bank1(下载区)中,升级的时候,应用程序先把新固件下载到bank1中,只有当新固件下载完成并校验成功后,系统才会跳入BootLoader程序,然后擦除老固件所在的bank0区,并把bank1的新固件拷贝到bank0中。

后台式下载必须采用双区模式进行升级。

优点:

升级过程中出现问题或者新固件有问题,它还可以选择之前的老固件老系统继续执行而不受其影响。

缺点:

多占用flash空间的一个存储区,在系统资源比较紧张的时候较为困难。

 

单区模式:

单区模式的非后台式下载只有一个bank0(运行区),老固件和新固件共享这一个bank0。升级的时候,进入bootloader程序后先擦除老固件,然后直接把新固件下载到同一个bank中,下载完成后校验新固件的有效性,新固件有效升级完成,否则要求重来。

优点:

跟双区模式相比,单区模式节省了Flash空间的一个bank,在系统资源比较紧张的时候,单区模式是一个不错的选择。

缺点:

如果升级过程中出现问题或者新固件有问题,单区模式碰到这种情况就只能一直待在bootloader中,然后等待再次升级尝试,此时设备的正常功能已无法使用,从用户使用这个角度来说,可以说此时设备已经“变砖”了。

相比较,双区模式虽然牺牲了很多存储空间,但是换来了更好的升级体验。

二、MCU OTA升级

以MCU(微控制器)固件升级为例,讲解嵌入式裸机程序的OTA升级。由于裸机固件是固化在设备的存储器(如flash)中,即存储器中保存的是机器码,对MCU进行OTA固件升级,也就是要实现通过OTA方式将存储器中旧固件的机器码替换为新固件的机器码。

数字签名

签名:

A给B发送消息,A先计算出消息的消息摘要,然后使用自己的私钥加密消息摘要,被加密的消息摘要就是签名。

验签:

B收到消息后,也会使用和A相同的方法计算消息摘要,然后用A的公钥解密签名,并与自己计算出来的消息

摘要进行比较,如果相同则说明消息是A发送给B的,同时,A也无法否认自己发送消息给B的事实。

(B使用A的公钥解密签名文件的过程,叫做"验签")

密码学基础概念:

1.什么是消息摘要?

2.什么是非对称加解密?私钥与公钥?

3.什么是数字签名?

数字签名的作用:

保证数据完整性,机密性和发送方角色的不可抵赖性。

消息摘要函数:

MD4、MD5、SHA-1、SHA-256、SHA-384、SHA-512

数字签名算法:

RSA、Rabin方式、ElGamal方式、DSA

2.1  制作升级包
通过签名工具使用签名算法对固件进行数字签名,签名后的文件即为升级包。

升级包的内容一般包括firmware、header和signature value。

Firmware:固件

Header:头部信息。存放配置信息,如版本号、产品类型等。

Signature value:签名值。对firmware和header签名后的值。

签名工具:

上位机软件,能计算固件的签名值,并将固件打包为升级包的格式。

固件签名:

上位机软件先计算整个固件的消息摘要,使用非对称密码的私钥对摘要进行加密,

被加密后的消息摘要数据就是签名值

固件签名的意义:

计算hash值可以识别固件是否被篡改和伪装,确保固件的完整性。

使用非对称秘钥签名方便后续验证升级包身份的合法性。

2.2  下载升级包

根据上位机软件和MCU设备约定的通信协议,上位机软件将升级包通过OTA方式发送给MCU设备,

MCU设备收到数据后,根据通信协议解析出升级包的数据,并将升级包的数据保存到存储器中。

通信协议的作用:

通讯双方约定俗成地用于数据交流的格式。

下载的方式:

1.在应用程序中下载:后台式

2.在BootLoader中下载:非后台式

2.3  验签升级包

MCU设备接收完所有的升级包后,先计算升级包中固件的摘要,然后使用非对称秘钥的

公钥解密升级包的签名值,如果解密出来的固件摘要与自己计算的摘要相同,则验签成功。

2.4  更新固件

验签成功保证了固件的完整性和合法性后,MCU设备从应用程序进入BootLoader程序,

在BootLoader程序中将flash中的新固件数据搬运到旧固件的存储区,将其覆盖。

然后BootLoader程序启动固件运行,此时固件为新固件。

flash固件数据更新:

擦除flash,写flash。

在使用分区表时,最简单的方法就是打开项目配置菜单(idf.py menuconfig),并在 CONFIG_PARTITION_TABLE_TYPE 下选择一个预定义的分区表:

  • “Single factory app, no OTA”

  • “Factory app, two OTA definitions”

  • 分区表设置成Factory app, two OTA definitions

  • 这里我们选择如下:

  • 在以上两种选项中,出厂应用程序均将被烧录至 flash 的 0x10000 偏移地址处。这时,运行 idf.py partition-table ,即可以打印当前使用分区表的信息摘要(当然肯定是得先烧写程序到ESP32里面)
  •  

     

  •  

     

    输入 idf.py monitor,结果如下

 分区表设置成Single factory app, no OTA

 输入 idf.py monitor,结果如下

 

 分区表设置为Single factory app(large),no OTA

 

 

 

 接下来演示在本地 PC 端搭建 http 服务器实现 ESP32 OTA 过程

 设置 WiFi 账号密码:

 

注意:wifi的SSID和密码一定要跟连接的热点或者路由器一致。

 使能 HTTP OTA:

 由于 ESP-IDF 默认为 HTTPS OTA,需要在 menuconfig 里打开以下选项来让 HTTP OTA 成功进行

 

准备需要 OTA 的 Bin 文件

在此处以需要升级的 Bin 为 helloworld.bin 为例,将 helloworld.bin 文件放在build目录下 

 

 查询 python 版本,执行如下命令:

 

  • 如果上述指令返回的 Python 版本是 3.X ,通过如下命令建立服务器

 

  查询本机 IP

在任意终端输入 ipconfig,结果如下

 

可以看到 PC 的 ip 地址为 192.168.1.102 ,后续在填写 OTA URL 时需要用到此 ip。 

 注:服务器建立好后,可通过网址 ip地址:8070 在网页端查询本地服务器(ip地址为pc机的地址)

 

 这个目录列表就是终端的路径下的。

进入网页后,这里主要是复制hello_world.bin的地址

在这里插入图片描述

 我这里复制到的地址如下所示,这就是新固件的下载地址待会需要用到

 

配置 OTA URL 

 menuconfig 里配置 OTA URL 为 http://192.168.1.102:8070/hello_world.bin

1.到此升级包准备工作已经完成
2.那个http服务端需要一直打开,不能关闭
3.你的电脑必须是在2.4G频段的wifi,否则ESP32无法和电脑在同一个局域网内
4.点击hello_world.bin,看看能不能下载,如果不能下载,可能是电脑的防火墙拦截了,可以关闭防火墙试试。否则你的ESP32也是不能下载到固件的
 

 检查分区表

在上述 menuconfig 里检查分区表是否选择为正确包含 OTA 分区的分区表,OTA 示例里会默认做以下修改: 

 

 

 开始 OTA

此时在 OTA 示例终端 下输入 idf.py flash monitor 编译烧写 OTA 示例至 ESP32 中即可发现 OTA 升级成功。 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值