当前位置: 首页 > news >正文

STM32:Bootloader(AB备份,自动回滚)

目录

  • 1.STM32的升级方式
  • 2.IAP升级
  • 3.代码逻辑展示
    • 3.1 划分存储区域
    • 3.2 IAP的状态
  • 4.源码分析
    • 4.1 记录IAP的状态
    • 4.2 APP代码异常判断
    • 4.3 IAP状态的切换以及异常的处理逻辑
    • 4.4 完整的逻辑代码

1.STM32的升级方式

1、ICP:In Circuit Programing,简单说就是在单片机开发时使用烧录器升级程序,比如使用J-Link烧录单片机程序。
2、ISP:In System Programing,在单片机内部实现了基于通信接口(如串口、I2C、SPI等等)的FLASH引导程序,配合厂家提供的烧录软件工具或自行开发的软件实现程序烧录。
3、IAP:In applicating Programing,是指单片机程序开发好之后在运行过程中由外部用户发起的在线升级,这种升级方式一般由用户自行设计升级方案,方案灵活性和自由度较高,在智能家居、汽车电子、物联网设备中常用的OTA(Over The Air)即空中下载技术原理也与之类似。

2.IAP升级

ICP和ISP需要连接才能更新固件,实际的交付客户的产品肯定不行,需要用到IAP,STM32的IAP升级,需要用到Bootloader,需要两段代码一段boot,一段app,boot区域负责更新app区域的代码,而app区域是项目的逻辑实现和功能实现。
STM32 IAP (In-Application Programming) 介绍STM32 IAP(In-Application Programming)是一种允许应用程序在运行时更新或编程内部Flash存储器的技术。通过IAP,您可以在不使用外部编程器的情况下,直接从应用程序代码中对STM32的内部Flash进行读取、写入和擦除操作。这对于实现固件升级、数据存储等功能非常有用。

  1. IAP 的应用场景
    •固件升级:通过IAP,您可以实现OTA(Over-The-Air)固件升级,允许设备在运行时从网络或其他来源下载并安装新的固件版本。
    •数据存储:IAP可以用于将用户数据、配置参数等存储到Flash中,确保数据在断电后不会丢失。
    •多应用管理:某些应用可能需要在同一片Flash中存储多个应用程序,并根据需要切换运行不同的应用程序。
  2. IAP 的工作原理IAP的核心是通过调用STM32 HAL库或标准外设库中的Flash编程函数来操作Flash存储器。STM32的Flash存储器分为多个扇区(Sector),每个扇区可以独立进行擦除和写入操作。IAP通常包括以下几个步骤:
    •解锁Flash:在对Flash进行任何操作之前,必须先解锁Flash以允许编程操作。
    •擦除Flash:在写入新数据之前,必须先擦除目标扇区。注意,擦除操作是以扇区为单位的,不能只擦除单个字节或字。
    •写入数据:将新数据写入指定的Flash地址。写入操作是以半字(16位)或字(32位)为单位进行的。
    •锁定Flash:完成所有操作后,重新锁定Flash以防止意外修改。
  3. IAP 的实现方式IAP可以通过以下几种方式实现:3.1 Bootloader + Application 结构这是最常见的IAP实现方式。系统启动时,首先运行Bootloader程序,Bootloader负责检查是否有新的固件需要更新。如果有,则将新固件写入应用程序区域,然后跳转到应用程序执行。如果没有新固件,则直接跳转到应用程序。
    •优点•
    •Bootloader和应用程序分离,互不影响。
    •可以实现安全的固件升级,避免损坏整个系统。
    •支持多种升级方式(如UART、USB、SPI、Ethernet等)。
    •缺点•
    •需要额外的空间来存储Bootloader。
    •Bootloader和应用程序之间的通信需要设计良好的协议。

3.代码逻辑展示

3.1 划分存储区域

把下载的固件存储到一个固定位置,另外还需要把原先APP区的代码进行备份,避免升级过程中出现异常导致生成砖

//1M start
#define USER_FLASH_FIRST_PAGE_ADDRESS 0x000000 //
#define USER_FLASH_LAST_PAGE_ADDRESS  0x0FFFFF //
#define USER_FLASH_END_ADDRESS 0x0FFFFF
//1M end//3M start
#define APP_FLASH_BACKUP_FIRST_PAGE_ADDRESS 0x200000 //
#define APP_FLASH_BACKUP_LAST_PAGE_ADDRESS  0x27FFFF //
#define APP_FLASH_BACKUP_END_ADDRESS 0x27FFFF//3M end

3.2 IAP的状态

//IAP STATUS
typedef enum iap_status_code{IAP_NO = 0,IAP_START = 1,IAP_COPY_APP_TO_BACKUP,  //拷贝APP区域代码到备份区域IAP_COPY_APP_TO_BACKUP_SUCCESS_STATUS, //拷贝APP区域代码 成功IAP_COPY_APP_TO_BACKUP_FAIL_STATUS, //拷贝APP区域代码 失败IAP_COPY_APP_TO_BACKUP_CHECK_MD5_FAIL_STATUS, //拷贝APP区域代码 MD5校验失败IAP_COPY_NEWBIN_TO_APP, //拷贝新的固件到APP区IAP_COPY_NEWBIN_TO_APP_NO_DATA_STATUS,//新固件存储区域没有数据IAP_COPY_NEWBIN_TO_APP_SUCCESS_STATUS,//成功IAP_COPY_NEWBIN_TO_APP_FAIL_STATUS,//失败IAP_COPY_NEWBIN_TO_APP_CHECK_MD5_FAIL_STATUS,//MD5校验失败	IAP_BACK_TO_BACKUP_OLDBIN,  //备份区域的旧固件恢复到APP区域IAP_BACK_TO_BACKUP_OLDBIN_NO_DATA_STATUS,//备份区域没有数据IAP_BACK_TO_BACKUP_OLDBIN_SUCCESS_STATUS,//成功IAP_BACK_TO_BACKUP_OLDBIN_FAIL_STATUS,//失败	IAP_BACK_TO_BACKUP_OLDBIN_CHECK_MD5_FAIL_STATUS,//MD5校验失败	IAP_ERROR_TO_APP, //IAP 升级失败 跳转到APP区运行IAP_END_TO_APP,  //IAP 升级成功 跳转到APP区运行}IAP_STATUS;#define IAP_COPY_APP_SIZE   409600  //(400*1024)  (448*1024)

为了避免升级过程中出现异常,需要对下载的文件进行MD5校验,此外未预防OTA文件有问题,添加多少次没有进入APP区域,代码自动回滚到上一个版本

4.源码分析

4.1 记录IAP的状态

记录上一次IAP的状态,避免中途断电,断网等异常导致OTA流程被打断后无法正常OTA

	//读取OTA过程中上一次的iap状态BSP_W25Qx_Read(&last_iap_status_flag,IAP_STATUS_FLAG_ADDRESS,1);if(last_iap_status_flag == 0xFF || last_iap_status_flag > 20){last_iap_status_flag = 0;BSP_GD25QXX_Write(&last_iap_status_flag,IAP_STATUS_FLAG_ADDRESS,1);}	

4.2 APP代码异常判断

Boot区和APP区进入次数进行比较,差异超过设定的次数,表示APP区域代码有问题,需要回滚到上一版本的代码

	in_boot_times_count();get_in_app_times();if(boot_app_times_compare() != 0){iap_status = IAP_BACK_TO_BACKUP_OLDBIN;	last_iap_status_flag = IAP_BACK_TO_BACKUP_OLDBIN;	LOG_INFO("in_boot_times.value - in_app_times.value >30 iap_status = IAP_BACK_TO_BACKUP_OLDBIN...\r\n");						}

4.3 IAP状态的切换以及异常的处理逻辑

		switch(iap_status){//不需要IAPcase IAP_NO:LOG_INFO("IAP_NO...jump to app --->\r\n"); HAL_Delay(1000);load_jump_to_app();break;//开始IAP的升级流程case IAP_START:LOG_INFO("IAP_START 1 : last_iap_status_flag = %d iap_status = %d\r\n",last_iap_status_flag,iap_status);if(last_iap_status_flag > IAP_START && last_iap_status_flag < IAP_ERROR_TO_APP){iap_status = last_iap_status_flag;}else{iap_status = IAP_COPY_APP_TO_BACKUP;				}LOG_INFO("IAP_START 2 : last_iap_status_flag = %d iap_status = %d\r\n",last_iap_status_flag,iap_status);break;//拷贝app区域的内容到外部flash的备份区域case IAP_COPY_APP_TO_BACKUP:{//把外部flash的备份区域的内容清空if(Erase_back_flash_Sector_to_backup_app_area() != 0){LOG_INFO("IAP_COPY_APP_TO_BACKUP Erase_back_flash_Sector_to_backup_app_area fail......\r\n");iap_status = IAP_COPY_APP_TO_BACKUP_FAIL_STATUS;}else{LOG_INFO("IAP_COPY_APP_TO_BACKUP Erase_back_flash_Sector_to_backup_app_area success......\r\n");error_code = copy_app_to_back_area(IAP_COPY_APP_SIZE);//LOG_INFO("copy_app_to_back_area error_code = %d\r\n",error_code);if(error_code == 0){calculate_app_area_md5(now_app_md5_value,IAP_COPY_APP_SIZE);LOG_INFO("IAP_COPY_APP_TO_BACKUP now_app_md5_value MD5: ");for(uint16_t i =0;i<16;i++){LOG_INFO("%02x",now_app_md5_value[i]);}LOG_INFO("\r\n");calculate_back_area_md5(back_md5_value,IAP_COPY_APP_SIZE);	LOG_INFO("IAP_COPY_APP_TO_BACKUP back_md5_value MD5: ");for(uint16_t i =0;i<16;i++){LOG_INFO("%02x",back_md5_value[i]);}LOG_INFO("\r\n");if(!compare_md5_2buff(now_app_md5_value,back_md5_value,16)){LOG_INFO("IAP_COPY_APP_TO_BACKUP_SUCCESS_STATUS......\r\n");BSP_GD25QXX_Write(back_md5_value,APP_FLASH_BACKUP_MD5_VALUE_ADDRESS,16); iap_status =  IAP_COPY_APP_TO_BACKUP_SUCCESS_STATUS;//BSP_GD25QXX_Write(&iap_status,IAP_STATUS_FLAG_ADDRESS,1);    							}else{LOG_INFO("IAP_COPY_APP_TO_BACKUP copy_app_to_back_area check is fail ---> BSP_Reset_system\r\n");HAL_Delay(100);iap_status = IAP_COPY_APP_TO_BACKUP_CHECK_MD5_FAIL_STATUS;	  							}}else{LOG_INFO("IAP_COPY_APP_TO_BACKUP copy_app_to_back_area copy is fail ---> BSP_Reset_system\r\n");HAL_Delay(100);iap_status = IAP_COPY_APP_TO_BACKUP_FAIL_STATUS;}}	}break;case IAP_COPY_APP_TO_BACKUP_SUCCESS_STATUS:{iap_status =  IAP_COPY_APP_TO_BACKUP_SUCCESS_STATUS;BSP_GD25QXX_Write(&iap_status,IAP_STATUS_FLAG_ADDRESS,1); iap_status = IAP_COPY_NEWBIN_TO_APP;}					 break;		case IAP_COPY_APP_TO_BACKUP_FAIL_STATUS:iap_copy_app_to_backup_error_cnt++;if(iap_copy_app_to_backup_error_cnt >= 10){iap_status =  IAP_COPY_APP_TO_BACKUP_FAIL_STATUS; BSP_GD25QXX_Write(&iap_status,IAP_STATUS_FLAG_ADDRESS,1); iap_status = IAP_ERROR_TO_APP;   				}else{iap_status = IAP_COPY_APP_TO_BACKUP;				}break;case IAP_COPY_APP_TO_BACKUP_CHECK_MD5_FAIL_STATUS:iap_copy_app_to_backup_error_cnt++;if(iap_copy_app_to_backup_error_cnt >= 10){iap_status =  IAP_COPY_APP_TO_BACKUP_CHECK_MD5_FAIL_STATUS; BSP_GD25QXX_Write(&iap_status,IAP_STATUS_FLAG_ADDRESS,1); iap_status = IAP_ERROR_TO_APP;   				<

相关文章:

STM32:Bootloader(AB备份,自动回滚)

目录 1.STM32的升级方式2.IAP升级3.代码逻辑展示3.1 划分存储区域3.2 IAP的状态4.源码分析4.1 记录IAP的状态4.2 APP代码异常判断4.3 IAP状态的切换以及异常的处理逻辑4.4 完整的逻辑代码1.STM32的升级方式 1、ICP:In Circuit Programing,简单说就是在单片机开发时使用烧录器…...

数独小游戏(Matlab)

基于Matlab制作的数独小游戏 &#xff08;完整源码和介绍&#xff09; 感兴趣可以随时联系博主噢~常在线能秒回&#xff01; “Matlab数独小游戏”程序设计的关键技术流程和核心算法如下&#xff1a; 1.图形用户界面(GUI):使用MATLAB的GUIDE工具创建和管理用户界面&#xff0…...

使用docker让项目持续开发和部署

大多人选择开发时在本地&#xff0c;部署时文件都在容器里&#xff0c;如果没有容器&#xff0c;那就本地开发&#xff0c;没有映射文件&#xff0c;如果部署环境到容器了&#xff0c;容器内部启动时设置执行命令&#xff0c;再将映射的文件进行编译&#xff0c;这就直接能实现…...

电子应用设计方案-45:智能火锅系统方案设计

智能火锅系统方案设计 一、引言 随着人们生活水平的提高和对饮食体验的追求&#xff0c;智能火锅系统应运而生。本方案旨在设计一款集智能化控制、高效加热、安全保障和个性化体验于一体的智能火锅系统。 二、系统概述 1. 系统目标 - 实现精准的温度控制&#xff0c;满足不同…...

windows在conda下安装nlpia库

最近在学习《自然语言处理实战》这本书&#xff0c;书中用了其自己的库nlpia&#xff0c;我一直装不上&#xff0c;网上也找不到教程遂放弃&#xff0c;看到现在第四章没办法了&#xff0c;需要用到库里的一些文本语料&#xff0c;又折腾了一天&#xff0c;终于装好了&#xff…...

分布式事务的前世今生-纯理论

一个可用的复杂的系统总是从可用的简单系统进化而来。反过来这句话也正确: 从零开始设计的复杂的系统从来都用不了&#xff0c;也没办法让它变的可用。 --John Gal 《系统学》 1975 1. 事务的概念 百科&#xff1a; 事务&#xff08;Transaction&#xff09;&#xff0c;一般是…...

apache部署若依前后端分离项目(开启SSL)

网站部署之后,大多数需要配置https,所以本章教程,介绍使用apache部署若依前后端项目的时候,如何开启SSL,以及如何配置SSL证书。 一、安装ssl模块 默认情况下,ssl模块是没有安装的。需要手动安装,否则直接配置SSL模块的时候,会报错。 sudo yum install mod_ssl二、查询s…...

Elasticsearch scroll 之滚动查询

Elasticsearch scroll 之滚动查询 Elasticsearch 的 Scroll API 是一种用于处理大规模数据集的机制&#xff0c;特别是在需要从索引中检索大量数据时。通常情况下&#xff0c;Elasticsearch 的搜索请求会有一个结果集大小的限制 (fromsize 的检索数量默认是 10,000 条记录)&am…...

MySQL 内存使用率常用分析语句

最近连续遇到MySQL内存占用过高导致服务器内存不足的问题&#xff0c;整理下收集到的常用分析语句 一、 OS层 首先需要确认是否是MySQL占用的内存 top -p $(pidof mysqld) -n 1 或者 cat /proc/$(pidof mysqld)/status 二、 DB层 1. 全局情况 各种buffer pool大小&#xf…...

L20.【LeetCode笔记】用栈实现队列(方法2)(★详解★)

目录 1.实现方法 过程详解 1.执行push 1->push 2->push 3->push 4 2.执行第一个pop 3.执行第二个pop 4.执行push 5->push 6 ​编辑 5.执行pop->pop->pop 代码实现 队列创建函数myQueueCreate 入队函数myQueuePush 出队函数myQueuePop 返回队列开头…...

PR蒙太奇

简介 蒙太奇是将不同的镜头鬓角在一起&#xff0c;已不同的时间、地点来表现人物、环境、情节等&#xff0c;有时会产生意想不到的想过。广义上来说&#xff0c;这种剪接做法就是蒙太奇&#xff0c;是由镜头组合构成的隐式语言。 含义 镜头组接技巧 叙事蒙太奇&#xff1a;…...

高中数学:计数原理-排列组合

文章目录 一、排列排列数例题 二、组合组合数例题 三、使用方法总结 一、排列 排列数 例题 二、组合 组合数 例题 三、使用方法总结 组合&#xff1a;从n个元素中抽取m个元素&#xff0c;不排序&#xff0c;则用组合计算 排列&#xff1a;从n个元素中抽取m个元素&#xff0c;再…...

pytorch中有哪些归一化的方式?

在 PyTorch 中&#xff0c;归一化是一种重要的操作&#xff0c;用于调整数据分布或模型参数&#xff0c;以提高模型的训练效率和性能。以下是常见的归一化方式及其应用场景&#xff1a; 1. 数据归一化 &#xff08;1&#xff09;torch.nn.functional.normalize 对输入张量沿…...

Next.js系统性教学:增量静态再生成 (ISR) 完全解析

更多有关Next.js教程&#xff0c;请查阅&#xff1a; 【目录】Next.js 独立开发系列教程-CSDN博客 目录 1. 什么是增量静态再生成 (ISR)? 1.1 传统的静态生成与挑战 1.2 增量静态再生成&#xff08;ISR&#xff09;的出现 2. 如何使用增量静态再生成&#xff08;ISR&…...

视频编辑技术的发展:AI技术在小咖视频混剪中的应用

随着数字技术的飞速发展&#xff0c;视频编辑领域也迎来了革命性的变化。AI技术的引入&#xff0c;使得视频编辑变得更加智能和高效。本文将探讨AI技术在视频混剪领域的应用&#xff0c;并介绍一些实用的工具&#xff0c;帮助用户提升视频编辑的效率和质量。 视频演示 AI技术在…...

【JVM】JVM基础教程(一)

目录 初识JVM JVM是什么&#xff1f; JVM的功能 解释、即时编译和运行 内存管理 常见的JVM JVM虚拟机规范 HotSpot的发展历程 JVM的组成 字节码文件详解 应用场景 以正确姿势打开字节码文件 ​编辑字节码文件的组成 基本信息 Magic魔数 主副版本号 常量池 接口…...

Python并发编程全解析

一、前言 在现代开发中,并发编程是提高性能、响应速度的关键技术之一。Python提供了多种实现并发的方式,如多线程、多进程和异步IO。本篇文章将逐一解析这些技术,探讨其适用场景,并通过代码示例帮助理解。 二、并发编程的核心概念 1. 并发与并行 并发:任务在时间片上交替…...

大语言模型应用Text2SQL本地部署实践初探

自从两年前OpenAI公司发布ChatGPT后&#xff0c;大模型(Large Language Model&#xff0c;简称LLM)相关技术在国内外可谓百家争鸣&#xff0c;遍地开花&#xff0c;在传统数据挖掘、机器学习和深度学习的基础上&#xff0c;正式宣告进入快速发展的人工智能(Artificial Intellig…...

每日十题八股-2024年12月7日

1.说说hashmap的负载因子 2.Hashmap和Hashtable有什么不一样的&#xff1f;Hashmap一般怎么用&#xff1f; 3.ConcurrentHashMap怎么实现的&#xff1f; 4.分段锁怎么加锁的&#xff1f; 5.分段锁是可重入的吗&#xff1f; 6.已经用了synchronized&#xff0c;为什么还要用CAS呢…...

VTK编程指南<三>:基于VTK入门程序解析来理解VTK基础知识

1、VTK入门程序 下面是一个完整的Vtk入门程序&#xff0c;我们基于这个程序来对VTK的基本知识进行一个初步了解。 #include <iostream>#include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL2);// VTK was built with vtkRenderingOpenGL2 VTK_MODULE_INI…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...