首页 > 其他分享 >MCU -- OTA (概念)

MCU -- OTA (概念)

时间:2023-07-26 10:46:27浏览次数:26  
标签:-- OTA 流程 校验 切换 镜像 MCU 固件 下载

一、A/B面OTA分类

二、A/B面OTA流程

三、A/B面OTA实现

四、A/B面OTA优缺点

 

 

一、A/B面OTA分类

  1. 双系统切换方案:使用两个独立的MCU芯片,每个芯片负责一个面(A面和B面)的固件运行。在升级时,先将待升级的固件下载到未运行的那一面对应的芯片上,并执行切换操作。这种方案需要双份硬件资源,但实现简单可靠;
  2. 双分区切换方案:使用单个MCU芯片,将存储空间划分为两个分区,分别用于存放A面和B面的固件。在升级时,将待升级的固件下载到未运行的分区,并在重启后切换分区。这种方案相对于双系统切换方案节省硬件成本,但需要较高的存储器和固件管理能力;
  3. 双镜像切换方案:使用单个MCU芯片,将存储空间划分为两个独立的镜像,分别用于存放A面和B面的固件。在升级时,将待升级的固件下载到未运行的镜像中,并通过引导程序切换到新的镜像。这种方案可以在固件运行期间完成切换,具有较高的实时性和可靠性;
  4. 双流程切换方案:使用单个MCU芯片,将固件设计为两个独立的流程,分别对应A面和B面。在升级时,将待升级的固件下载到未运行的流程中,并通过切换信号或事件触发切换到新的流程。这种方案适用于需要更细粒度控制和灵活切换的场景;
  5. 双引导程序切换方案:将存储空间划分为两个部分,分别用于存放A面和B面的引导程序。在升级时,将待升级的固件下载到未运行的引导程序中,并通过重启或软复位操作切换到新的引导程序。这种方案具有较低的系统开销和实现难度。

二、A/B面OTA流程

  1. 双系统切换方案
    开始 -> 检查当前运行的系统
          └─> 如果是A面系统,则下载B面固件
          └─> 如果是B面系统,则下载A面固件
    下载固件 -> 校验固件完整性和合法性
             └─> 如果校验失败,则重新下载固件
             └─> 如果校验通过,则保存固件到合适的存储介质
    切换系统 -> 执行系统切换操作
    确认切换 -> 验证切换是否成功
    结束

    在这个流程中,首先检查当前运行的系统是A面还是B面。然后根据当前的系统,下载对应面的固件。下载完成后,对固件进行校验,确保其完整性和合法性。如果校验失败,则重新进行固件下载。校验通过后,将固件保存到适当的存储介质中(例如Flash存储器)。接下来执行系统切换操作,将新固件加载到相应的系统中。最后确认切换是否成功。若切换成功,流程结束;若切换失败,则需要重新进行固件下载和切换操作。

  2. 双分区切换方案
    开始 -> 检查当前运行的分区
          └─> 如果当前运行的是A面分区,则下载B面固件到B面分区
          └─> 如果当前运行的是B面分区,则下载A面固件到A面分区
    下载固件 -> 校验固件完整性和合法性
             └─> 如果校验失败,则重新下载固件
             └─> 如果校验通过,则更新对应分区的固件
    切换分区 -> 设置下一次启动时要运行的分区
    确认切换 -> 验证切换是否成功
    结束

    在这个流程中,首先检查当前运行的分区是A面还是B面。然后根据当前的分区,下载对应面的固件到相应的分区中。下载完成后,对固件进行校验,确保其完整性和合法性。如果校验失败,则重新进行固件下载。校验通过后,更新对应分区的固件。接下来,设置下一次启动时要运行的分区。最后确认切换是否成功。若切换成功,流程结束;若切换失败,则需要重新进行固件下载和切换操作。

  3. 双镜像切换方案
    开始 -> 检查当前运行的镜像
          └─> 如果当前运行的是A面镜像,则下载B面固件到B面镜像
          └─> 如果当前运行的是B面镜像,则下载A面固件到A面镜像
    下载固件 -> 校验固件完整性和合法性
             └─> 如果校验失败,则重新下载固件
             └─> 如果校验通过,则在合适的存储介质中保存固件
    切换镜像 -> 设置下一次启动时要运行的镜像
    确认切换 -> 验证切换是否成功
    结束

    在这个流程中,首先检查当前运行的镜像是A面还是B面。然后根据当前的镜像,下载对应面的固件到相应的镜像中。下载完成后,对固件进行校验,确保其完整性和合法性。如果校验失败,则重新进行固件下载。校验通过后,将固件保存到适当的存储介质中(例如Flash存储器)。接下来,设置下一次启动时要运行的镜像。最后确认切换是否成功。若切换成功,流程结束;若切换失败,则需要重新进行固件下载和切换操作。

  4. 双流程切换方案
    开始 -> 检查当前运行的流程
          └─> 如果当前运行的是流程A,则下载流程B相关的代码和资源
          └─> 如果当前运行的是流程B,则下载流程A相关的代码和资源
    下载代码和资源 -> 校验代码和资源完整性和合法性
                  └─> 如果校验失败,则重新下载代码和资源
                  └─> 如果校验通过,则更新对应流程的代码和资源
    切换流程 -> 设置下一次启动时要运行的流程
    确认切换 -> 验证切换是否成功
    结束

    在这个流程中,首先检查当前运行的流程是A还是B。然后根据当前的流程,下载对应流程的代码和资源。下载完成后,对代码和资源进行校验,确保其完整性和合法性。如果校验失败,则重新进行代码和资源下载。校验通过后,更新对应流程的代码和资源。接下来,设置下一次启动时要运行的流程。最后确认切换是否成功。若切换成功,流程结束;若切换失败,则需要重新进行代码和资源下载和切换操作。

  5. 双引导程序切换方案
    开始 -> 检查当前运行的引导程序
          └─> 如果当前运行的是引导程序A,则下载引导程序B的映像文件
          └─> 如果当前运行的是引导程序B,则下载引导程序A的映像文件
    下载映像文件 -> 校验映像文件完整性和合法性
                 └─> 如果校验失败,则重新下载映像文件
                 └─> 如果校验通过,则在合适的存储介质中保存映像文件
    切换引导程序 -> 设置下一次启动时要运行的引导程序
    确认切换 -> 验证切换是否成功
    结束

    在这个流程中,首先检查当前运行的引导程序是A还是B。然后根据当前的引导程序,下载对应的引导程序的映像文件。下载完成后,对映像文件进行校验,确保其完整性和合法性。如果校验失败,则重新进行映像文件下载。校验通过后,将映像文件保存到适当的存储介质中(例如硬盘或闪存)。接下来,设置下一次启动时要运行的引导程序。最后确认切换是否成功。若切换成功,流程结束;若切换失败,则需要重新进行映像文件下载和切换操作。

三、A/B面OTA实现

  1. 双系统切换方案
    // A面MCU代码
    
    // 定义A面固件的功能函数
    void executeFirmwareA() {
        // TODO: 实现A面固件的功能逻辑
    }
    
    int main() {
        // 检测是否需要升级A面固件
        if (isFirmwareUpdateNeededForA()) {
            // 下载待升级的固件到A面MCU
            downloadFirmwareForA();
            
            // 执行固件切换操作,切换到A面固件
            switchToFirmwareA();
        }
        
        // 执行A面固件的功能
        executeFirmwareA();
        
        // 正常运行其他逻辑...
    }
    
    // B面MCU代码
    
    // 定义B面固件的功能函数
    void executeFirmwareB() {
        // TODO: 实现B面固件的功能逻辑
    }
    
    int main() {
        // 检测是否需要升级B面固件
        if (isFirmwareUpdateNeededForB()) {
            // 下载待升级的固件到B面MCU
            downloadFirmwareForB();
            
            // 执行固件切换操作,切换到B面固件
            switchToFirmwareB();
        }
        
        // 执行B面固件的功能
        executeFirmwareB();
        
        // 正常运行其他逻辑...
    }

    在实际应用中,需要根据具体的MCU芯片和开发环境进行相应的配置和编程。代码示例中的"isFirmwareUpdateNeededForA()"、"downloadFirmwareForA()"、"switchToFirmwareA()"、"isFirmwareUpdateNeededForB()"、"downloadFirmwareForB()"、"switchToFirmwareB()"等函数需要根据具体需求实现,用于检测是否需要升级固件、下载固件到MCU芯片并执行固件切换操作。同时,根据实际需求,还可以添加其他必要的功能和逻辑代码。

  2. 双分区切换方案
    // 定义A面固件的功能函数
    void executeFirmwareA() {
        // TODO: 实现A面固件的功能逻辑
    }
    
    // 定义B面固件的功能函数
    void executeFirmwareB() {
        // TODO: 实现B面固件的功能逻辑
    }
    
    int main() {
        // 检测当前运行的固件分区
        int activePartition = getActivePartition();
        
        // 根据当前分区选择执行对应的固件
        if (activePartition == 0) {
            executeFirmwareA();
        } else {
            executeFirmwareB();
        }
        
        // 正常运行其他逻辑...
    }
    
    // 获取当前活动的固件分区
    int getActivePartition() {
        // TODO: 从存储器中读取当前活动的分区标识
        
        // 假设分区标识为0或1
        return readPartitionFlag();
    }

    在实际应用中,需要根据具体的MCU芯片和存储器配置来实现双分区切换方案。代码示例中的"executeFirmwareA()"和"executeFirmwareB()"分别表示A面和B面固件的功能函数,可以根据实际需求进行相应的实现。函数"getActivePartition()"用于获取当前活动的固件分区,可以根据存储器中的分区标识进行判断。

    另外,在固件升级时,需要注意更新非活动分区的固件,并在合适的时机切换活动的固件分区。具体的固件管理、切换和升级逻辑需要根据实际需求进行完善和调试。

  3. 双镜像切换方案
    // 定义镜像A的功能函数
    void executeImageA() {
        // TODO: 实现镜像A的功能逻辑
    }
    
    // 定义镜像B的功能函数
    void executeImageB() {
        // TODO: 实现镜像B的功能逻辑
    }
    
    int main() {
        // 检测当前运行的镜像
        int activeImage = getActiveImage();
        
        // 根据当前镜像选择执行对应的功能
        if (activeImage == 0) {
            executeImageA();
        } else {
            executeImageB();
        }
        
        // 正常运行其他逻辑...
    }
    
    // 获取当前活动的镜像
    int getActiveImage() {
        // TODO: 从存储器中读取当前活动的镜像标识
        
        // 假设镜像标识为0或1
        return readImageFlag();
    }

    在实际应用中,需要根据具体的MCU芯片和存储器配置来实现双镜像切换方案。代码示例中的"executeImageA()"和"executeImageB()"分别表示镜像A和镜像B的功能函数,可以根据实际需求进行相应的实现。函数"getActiveImage()"用于获取当前活动的镜像,可以根据存储器中的镜像标识进行判断。

    同时,在镜像更新时,需要将新镜像加载到存储器中,并在合适的时机切换活动的镜像。具体的镜像管理、切换和更新逻辑需要根据实际需求进行完善和调试。

  4. 双流程切换方案
    // 定义流程A的函数
    void executeProcessA() {
        // TODO: 实现流程A的功能逻辑
    }
    
    // 定义流程B的函数
    void executeProcessB() {
        // TODO: 实现流程B的功能逻辑
    }
    
    int main() {
        // 检测当前运行的流程
        int activeProcess = getActiveProcess();
        
        // 根据当前流程选择执行对应的流程
        if (activeProcess == 0) {
            executeProcessA();
        } else {
            executeProcessB();
        }
        
        // 正常运行其他逻辑...
    }
    
    // 获取当前活动的流程
    int getActiveProcess() {
        // TODO: 从存储器中读取当前活动的流程标识
        
        // 假设流程标识为0或1
        return readProcessFlag();
    }

    在实际应用中,需要根据具体的MCU芯片和存储器配置来实现双流程切换方案。代码示例中的"executeProcessA()"和"executeProcessB()"分别表示流程A和流程B的功能函数,可以根据实际需求进行相应的实现。函数"getActiveProcess()"用于获取当前活动的流程,可以根据存储器中的流程标识进行判断。

    同时,在流程切换时,需要判断当前流程的完成状态,并在合适的时机切换到下一个流程。具体的流程管理和切换逻辑需要根据实际需求进行完善和调试。

  5. 双引导程序切换方案
    // 定义引导程序A的函数
    void executeBootloaderA() {
        // TODO: 实现引导程序A的功能逻辑
    }
    
    // 定义引导程序B的函数
    void executeBootloaderB() {
        // TODO: 实现引导程序B的功能逻辑
    }
    
    int main() {
        // 检测当前运行的引导程序
        int activeBootloader = getActiveBootloader();
        
        // 根据当前引导程序选择执行对应的引导逻辑
        if (activeBootloader == 0) {
            executeBootloaderA();
        } else {
            executeBootloaderB();
        }
        
        // 正常运行其他逻辑...
    }
    
    // 获取当前活动的引导程序
    int getActiveBootloader() {
        // TODO: 从存储器中读取当前活动的引导程序标识
        
        // 假设引导程序标识为0或1
        return readBootloaderFlag();
    }

    在实际应用中,需要根据具体的MCU芯片和存储器配置来实现双引导程序切换方案。代码示例中的"executeBootloaderA()"和"executeBootloaderB()"分别表示引导程序A和引导程序B的功能函数,可以根据实际需求进行相应的实现。函数"getActiveBootloader()"用于获取当前活动的引导程序,可以根据存储器中的引导程序标识进行判断。

    同时,在引导程序切换时,需要根据特定条件或者外部触发来切换到另一个引导程序,例如按下某个特定的按键、通过通信接口接收到特定指令等。具体的引导程序管理和切换逻辑需要根据实际需求进行完善和调试。

四、A/B面OTA优缺点

OTA分类 优点 缺点
双系统切换方案 实现简单可靠,硬件资源独立,故障隔离能力强 需要双份硬件资源,增加了成本和体积
双分区切换方案 硬件成本相对较低,利用单个MCU的存储空间进行分区划分 固件管理复杂,对存储器需求较高
双镜像切换方案 切换过程实时性较好,具备一定的容错能力 存储空间需求较高,需要额外的引导程序来管理镜像切换
双流程切换方案 可以实现较细粒度的控制和灵活的切换 设计和开发难度较高,对MCU的资源要求较高
双引导程序切换方案 系统开销较低,切换效率较高 需要引导程序支持切换操作,对MCU的启动流程有一定要求

标签:--,OTA,流程,校验,切换,镜像,MCU,固件,下载
From: https://www.cnblogs.com/liuqiongcn/p/17576524.html

相关文章

  • 实习微信机器人API开发
    现在网络上资源聚集复杂,当我们想要实现一个功能时,我们已经没有必要像前辈们那样来进行繁重的造轮子的工作。目前,随着人教育体系的提高,培养出专业性人才,为解决繁重的工作带来质的飞越,也就是微信机器人的开发,帮我们抵抗了绝大部分繁重的压力。接下来向大家介绍的一所微信机器人其功......
  • Appium-启动App
    Appium-启动App0.前言:上一篇已经记录了环境准备的笔记,这一篇记启动app一、安装完成后,启动Appium,host和port默认的即可,然后设置AndroidSDk和JavaJDK  点击StartServer按钮 二、真机连接测试1.连接手机打开开发者模式,USB线连接手机和电脑,并且在开发者选项当中,开启......
  • N1nEmAn-2023集训wp&&后续pwn-wp
    week12022-12-28WP0x00T1reverse3前几天没注意到要发wp,现在补一下。最近在学汇编,pwn题没做新的了。想到之前了解到hws的pwn会考花指令,听hjx他们说那是re的内容,就特意去做了点re。题目来源是buuctf的reverse3。0x01wp第一步,查壳没壳,32位,准备丢ida第二步,反编译观察到......
  • java笔记_11_JVM调优参数(转载)
    -Xms2048m//设置jvm的初始内存。这个值最好设置的跟-Xmx相同,以避免每次垃圾回收完成后JVM都要重新分配内存-Xmx2048m//JVM最大可用内存-XX:PermSize=256M//设置持久代大小-XX:MaxPermSize=512M//设置最大持久代大小-XX:+PrintGCDetails-XX:+PrintGCDat......
  • 第十章 特殊类(内部类、枚举及注解)
    1.内部类1.1内部类的基本概念当一个类的定义出现在另外一个类的类体中时,那么这个类叫做内部类(Inner),而这个内部类所在的类叫做外部类(Outer)。类中的内容:成员变量、成员方法、构造方法、静态成员、构造块和静态代码块、内部类。1.2实际作用当一个类存在的价值仅仅是为某一......
  • Pandas学习笔记之Series
    一、Series基本概念及创建1.基本概念#Series数据结构#Series是带有标签的一维数组,可以保存任何数据类型(整数,字符串,浮点数,Python对象等),轴标签统称为索引#导入numpy、pandas模块importnumpyasnpimportpandasaspds=pd.Series(np.random.rand(5))print(s)#......
  • 网络并发每日习题解释版
    网络并发每日习题解释版1.软件开发架构类别软件开发架构类别:软件开发架构是指在软件设计和开发过程中,用于组织和管理软件系统的基本结构。常见的软件开发架构类别包括:分层架构(LayeredArchitecture):将软件系统划分为多个相互独立的层,每个层都有特定的功能和责任。客户端......
  • 网络并发每日习题
    网络并发每日习题1.软件开发架构类别2.osi七层及各自功能3.谈谈你对tcp三次握手和四次挥手的理解4.描述粘包现象5.写出解决粘包现象的思路6.struct模块如何使用7.如何开启进程、进程类中的参数及方法有哪些?8.如何开启多进程,如何让所有子进程先执行完毕再执行主进程9.使......
  • 数据库每日习题
    数据库每日习题1.库、表、记录的概念2.写出针对库的SQL语句3.写出制作系统服务的流程及相关命令4.写出针对表的基本sql语句5.聊聊MySQL的存储引擎,有哪几个,什么特征6.你知道的MySQL中数据类型有哪些,分别写写7.MySQL中有哪些约束条件,其中,主键有什么特点,怎么使用8.查询关键字......
  • QT jom: Makefile [debug] Error
    电脑上原本安装有QT5.15.0+VS2015+VS2008QtCreator正常使用安装vs2019后报错jom:Makefile[debug]Error1jom:Makefile[debug]Error2lnk1158:cannotrunrc.exe解决方法:找到rc.exe路径(C:\ProgramFiles(x86)\WindowsKits\8.1\bin\x64),添加到环境变量,重启QT......