嵌入式的OTA升级 浅谈

简介

OTA升级是嵌入式设备几乎都有的一项功能。对于简单的设备来说,例如单片机设备,OTA升级需要将新的固件刷写到FLASH上即可;对于高级一点的Linux设备来说,更加复杂,首先需要对ROM进行分区,再决定升级方式,是单备份升级还是双备份升级。

本文主要讲解嵌入式设备的OTA升级流程架构,虽然会涉及到一些实现细节,但是并不会事无巨细的讲解每一步操作。

升级的本质

所谓的升级,无非是使用新的程序替换旧的程序。

但是,就像一个人不借助镜子永远看不到自己的眼睛一样,程序也永远不能自己替换自己。因此,程序的升级一般有下列几种主流的做法:

  1. 先把自己加载到RAM中执行,然后替换ROM中的程序,接着再重启一下。
    1. 这种做法是Linux或者windows操作系统中最常见的做法,因为在操作系统中,二进制程序默认就会加载 到RAM中执行
  2. 再使用一个程序B,跳转到程序B执行,程序B负责把新的程序替换到旧程序的位置
  3. 再使用一个程序B和单独的一块ROM(以下简称ROM-B),把新的程序放到ROM-B里面去,然后程序B负责在ROM-A和ROM-B中进行切换。

单片机上的OTA

先了解一下单片机程序的执行原理:
通常单片机都内置有一块FLASH用于存储代码,一块RAM用于存储数据。 FLASH中的代码可以直接被CPU读取并执行。

因此单片机进行升级,通常就不能使用上述1的RAM升级方法。都要使用到第三个程序,通常叫做bootloader。

具体做法如下:

单备份升级

  1. 下载升级包 upgrade.bin 到 FLASH的 0x8300000位置
  2. 在FLASH上或者其他任何重启不会丢失的位置设置一个标志位 flag
  3. 重启
  4. 进入Bootloader
  5. Bootloader中判断标志位 flag是否设置,如果设置了,则
  6. 拷贝0x83000000到 0x820000位置
  7. 校验md5
  8. 跳转到0x8200000执行
  9. 完成升级

双备份升级

  1. 下载升级包 upgrade.bin 到 FLASH的 0x8300000位置
  2. 在FLASH上或者其他任何重启不会丢失的位置设置一个标志位 flag
  3. 重启
  4. 进入Bootloader
  5. Bootloader中判断标志位 flag是否设置,如果设置了,则
  6. 跳转到0x8300000执行
  7. 完成升级

Linux系统上的OTA

Linux系统由多个部分组成,如下所示:
![图片.png](https://img-blog.csdnimg.cn/img_convert/b2e197aea9831c74a736a975cf4518e4.png#clientId=u1047b838-162b-4&from=paste&height=147&id=u3abc3256&margin=[object Object]&name=图片.png&originHeight=147&originWidth=738&originalType=binary&ratio=1&size=32769&status=done&style=none&taskId=u6ed9c885-8bb8-4c72-8967-711c19df36b&width=738)

  • bootloader :
    • 主要用于加载kernel和设备树到ram中
    • 通过传递参数的形式,可以简单的配置kernel,比如配置以太网地址,使用的根文件系统位置
    • 不需要升级
  • kernel
    • 系统核心,需要加载到RAM中运行
  • 根文件系统
    • 比较大,类似于windows中的C盘的概念
  • APP
    • 根文件系统中的一个二进制可执行程序

因此升级也需要分开考虑:

ROM分区

linux的ROM是以分区的形式来管理,而不是像单片机一样直接以地址来管理的,如下图所示:
![图片.png](https://img-blog.csdnimg.cn/img_convert/0d2f3b2705f0417871c65fa1a7aa83f5.png#clientId=u1047b838-162b-4&from=paste&height=121&id=u343933c6&margin=[object Object]&name=图片.png&originHeight=121&originWidth=746&originalType=binary&ratio=1&size=30596&status=done&style=none&taskId=u2cbafa51-3fe5-40bd-af5b-5fd7d76b60c&width=746)
因此通常可以把上述的每个部分都单独放在一个分区当中,这样方便操作。

APP升级

APP升级比较简单。 APP执行时会加载到RAM中执行,所以可以随时覆盖ROM上的APP,然后重启即可。

根文件系统升级

根文件系统升级比较复杂,因为根文件系统在ROM上,且Linux一直在使用。故只能使用上述的2/3, 配合程序B进行升级。
举例:

单备份升级

首先需要一个额外的kernel和设备树,以及一个很小的ramrootfs。

  1. 下载升级包到备份分区
  2. 修改uboot引导参数
  3. 重启从ramrootfs启动
  4. 检查备份分区的升级包
  5. 拷贝升级包到rootfs分区
  6. 修改uboot引导参数
  7. 重启

双备份升级
  1. 下载升级包到备份分区
  2. 解压升级包到rootfs-2分区
  3. 修改uboot引导参数
  4. 重启
  5. 从rootfs-2启动
  6. 升级完成

kernel升级

kernel会由uboot加载到RAM中运行,因此也只需要直接替换即可。

单备份和双备份

根据上述的描述,可以看出,单备份升级其实存在风险:假设在拷贝升级包的时候设备突然断电,此时设备处于一个中间态 - 既没有升级成功,也没有升级失败。 设备直接变砖。

而双备份升级可以一定程度上的保证原子性,即设备要么升级失败,要么升级成功。

  • 5
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值