参考博客:STM32 BootLoader升级固件_cyang's blog-CSDN博客

STM32固件升级详解(BootLoader)_EmbeddedOsprey-CSDN博客_stm32升级bootloader

一、关于BootLoader

  • 1、BootLoader就是单片机启动时候运行的一段小程序,这段程序负责单片机固件的更新,也就是单片机选择性的自己给自己下程序。可以更新,也可以不更新,更新的话,BootLoader更新完程序后,跳转到新程序运行;不更新的话,BootLoader直接跳转到原来的程序去运行。
  • 2、BootLoader更新完程序后并不擦除自己,下次启动后依然先运行BootLoader程序,又可以选择性的更新或者不更新程序,所以BootLoader就是用来管理单片机程序的更新。
  • 3、在实际的单片机工程项目中,如果加入了BootLoader功能,就可以给单片机日后升级程序留出一个接口,方便日后单片机程序更新。当然,这就需要创建两个工程项目,一个为BootLoader工程,一个为APP工程。
  • 4、BootLoader工程生成的.hex或者.bin文件通常下载到ROM或Flash中的首地址,这样可以保证上电后先运行BootLoader程序。而APP工程生成的.hex或者.bin文件则下载到ROM或Flash中BootLoader后面的地址中。也就是说,存在ROM/Flash中的内容是分为两部分的。
  • 5、要实现在同一个ROM/Flash中保存两段程序,并且保证不能相互覆盖,则需要在下载程序时指定地址。如在Keil下,可以进行如下的调整

(版权声明:本文为CSDN博主「cyang812」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011303443/article/details/53378602)

二、OTA升级方式:(涉及到BootLoader的编写)

1.全量升级:

完整的下载新版本固件,下载完成后将固件搬运到APP程序运行的位置。(一般来说是将APP从片外flash搬运到片内flash上)。搬运完成后校验通过后重启APP。

2.差分升级:

利用算法,做出原版APP和新版APP程序的差分包,将差分包下载到flash,内部的BootLoader程序在利用算法将新版APP合成,合成后在搬运,搬运后校验,重启。
一般制作出来的差分包只有原包的5%左右。省空间!

服务器端: 生成差分包,bsdiff算法

1.对old文件中所有子字符串形成一个字典;

2.对比old文件和new文件,产生diff string        和extra string;

3.将diff string 和extra string 以及相应的控制        字用zip压缩成一个patch包。

设备端: 生成new File,bspatch算法

1.接收patch包;

2.解压patch包;

3.还原new文件。

3.原地升级:

相比差分升级,合包的过程,直接搬运。

容错率低。

4.AB面升级:

如图所示:

A/B 系统更新可带来以下好处:

  • OTA 更新可以在系统运行期间进行,而不会打断用户。用户可以在 OTA 期间继续使用其设备。在更新期间,唯一的一次宕机发生在设备重新启动到更新后的磁盘分区时。
  • 更新后,重新启动所用的时间不会超过常规重新启动所用的时间。
  • 如果 OTA 无法应用(例如,因为刷机失败),用户将不会受到影响。用户将继续运行旧的操作系统,并且客户端可以重新尝试进行更新。
  • 如果 OTA 更新已应用但无法启动,设备将重新启动回旧分区,并且仍然可以使用。客户端可以重新尝试进行更新。
  • 任何错误(例如 I/O 错误)都只会影响未使用的分区组,并且用户可以进行重试。由于 I/O 负载被特意控制在较低水平,以免影响用户体验,因此发生此类错误的可能性也会降低。
    更新包可以流式传输到 A/B 设备,因此在安装之前不需要先下载更新包。流式更新意味着用户没有必要在 /data 或 /cache 上留出足够的可用空间来存储更新包。
  • 缓存分区不再用于存储 OTA 更新包,因此无需确保缓存分区的大小要足以应对日后的更新。
  • dm-verity 可保证设备将使用未损坏的启动映像。如果设备因 OTA 错误或 dm-verity问题而无法启动,则可以重新启动到旧映像。(Android 验证启动不需要 A/B 更新。)

几种OTA方式的对比:

优点

缺点

差分升级

1.差分包小(5%),下载更快,节省OTA流程的时间。

1.一个差分包只能由特定的原包升级到特定的新包。2.保证基础包的一致性。若原包数据损毁,得到差分包也无法升级。

全量升级

1.拿到新的包就能升级。不需要指定原包。2.不需保证基础包的一致性。

1.全量包的size更大,下载相比差分包需要更长时间。

AB面升级

1.容错率高,更能避免固件升级出错

2.OTA过程中不影响用户APP程序的运行

3.下载完成后不需要搬运,不需要差分包还原

1.需要最多的flash空间的OTA方式。

原地升级

1.最节省flash空间的方式,不需要合包存储,直接根据差分包搬运到APP的位置

2.容错率低,若搬运过程中断电,则设备变砖

关于差分升级的缺点,如图所示,你懂得(懒得打字了......)

三、编写BootLoader

1.外设驱动-----CubeMX工具生成代码:GPIO uart(debug uart) SPI flash

2.md5库添加 、w25q80驱动文件添加

3.Boot_Start()函数

bootloader.h

#ifndef BOOTLOADER_H
#define BOOTLOADER_H#include <stdio.h>
#include <stdint.h>
#include "flash.h"#define MD5_CHECK_MSG_FLAG                "firmware-header"
#pragma pack(1)
typedef struct {uint8_t project_id;uint16_t vendor_id;uint16_t software_version;uint16_t hardware_version;uint32_t buildtime;uint32_t filesize;uint8_t  md5[16];
} mcu_update_info_t;
#pragma pack()#define APP_START_ADDRESS   (0x08008000) //APP main   //map ResetHandle :0800825d  //0x08008000
#define MCU_OTA_FLAG        (0xA8A8A8A8)//printf boot:
void boot_message_print();//boot_start    : main调用这个函数
void boot_start(void);//check bin file
void check_bin_file(void);//update bin file
uint8_t update_bin_file(uint32_t addr, HDC01_ota_info_t *params);//go to main
void go_to_app_main(uint32_t address); //APP_START_ADDRESS 实参//
bool firmware_verify(uint32_t start_address, uint32_t end_address);

bootloader.c

#include "bootloader.h"
#include "stm32f4xx_hal.h"
#include "flash.h"
#include "lib_md5.h"char version[] = {"V00.00"};typedef  void (*pFunction)(void);
pFunction JumpToApplication;void go_to_app_main(uint32_t address) //APP_START_ADDRESS 实参
{__IO uint32_t fun;fun = (*(__IO uint32_t *)APP_START_ADDRESS);// check the Vactor Table Head // 检查栈顶地址是否合法if ((fun & 0x2FFE0000) == 0x20000000) {fun = *(__IO uint32_t *)(APP_START_ADDRESS + 4);JumpToApplication = (pFunction)fun;// set Vactor Table address__set_MSP(*(__IO uint32_t *)APP_START_ADDRESS);printf("Set Vactor Table address ...\n");// start Jumping and go to App_mainprintf("Real Jump and go to App_main...\r\n\r\n");        //关闭 总中断__disable_irq();JumpToApplication();}else {// app file errorprintf("App Bin file size err 0x%8X...\r\n", fun);// go to startHAL_NVIC_SystemReset();}}//printf boot:
void boot_message_print(void )
{printf("Start Bootloader,version = %s...\n",version);}//boot_start : main use
void boot_start(void)
{boot_message_print();check_bin_file();go_to_app_main(APP_START_ADDRESS);
}//check bin file / updata bin
void check_bin_file(void)
{HDC01_ota_info_t params;//1. read firmware upadte flagflash_read(FLASH_TYPE_EXTERNAL,(uint8_t *)&params, HDC01_MCU_OTA_INFO_START_ADDR,sizeof(HDC01_ota_info_t));//2.check the bin file exception flagif (params.magic == MCU_OTA_FLAG) {// Need updateport_trace("We need update the new firmware. len:%d\n", params.firmware_len);// update the bin fileupdate_bin_file(HDC01_MCU_OTA_DATA_START_ADDR, &params);//erase OTA flagflash_erase_sector(FLASH_TYPE_EXTERNAL, HDC01_MCU_OTA_INFO_SECTOR);} else {port_trace("Normal firmware start...\n");}
}//update the bin file
uint8_t buff[2048];
uint8_t check[2048];
uint8_t update_bin_file(uint32_t addr, HDC01_ota_info_t *params)
{bool ret;uint32_t remain_length = 0, write_num;uint32_t index = 0;uint32_t i = 0;uint32_t bin_length = 0;bin_length = params->firmware_len;if (bin_length > (224 * 1024)) {// error of bin file lengthport_trace("Read Firmware length err: 0x%8X\n", bin_length);return 0;}// erase all code segmentuint16_t sector_max_num = GetMaxSectorNum(bin_length);for (i = 2; i <= sector_max_num; i++) {port_trace("erase sector %d.\n", i);flash_erase_sector(FLASH_TYPE_INTERNAL, i);}// copy data from the extend flash to inner flashport_trace("Copy data Start\n");remain_length = bin_length;index = 0;while (1) {if (remain_length > 2048)write_num = 2048;elsewrite_num = remain_length;flash_read(FLASH_TYPE_EXTERNAL, buff, HDC01_MCU_OTA_DATA_START_ADDR + index, write_num);flash_write(FLASH_TYPE_INTERNAL, buff, APP_START_ADDRESS + index, write_num);// 写入后立刻读出,并与外部Flash中的数据做校验。flash_read(FLASH_TYPE_INTERNAL, check, APP_START_ADDRESS + index, write_num);for (i = 0; i < write_num; i++) {if (buff[i] != check[i]) {// 一旦出现问题,随后再次重启。HAL_NVIC_SystemReset();}}index = index + write_num;remain_length = remain_length - write_num;if (remain_length == 0)  break;}//ret = firmware_verify(APP_START_ADDRESS, APP_START_ADDRESS + params->firmware_len);
//      if (ret == false)
//      {
//          port_trace("md5 check fail.\n");
//          // 一旦出现问题,随后再次重启。
//          HAL_NVIC_SystemReset();
//      }
//      else
//      {
//          port_trace("md5 check success.\n");
//      }port_trace("Copy data finish.\n");return 1;
}/*check app validity
*/
static uint32_t boot_timeout_starting_time = 0;/* ------------------------------------------------------------------------ */
/* @Description: check app validity* @parameters:start_address: app start addrend_address:   app end addr */
/* ------------------------------------------------------------------------ */
bool firmware_verify(uint32_t start_address, uint32_t end_address)
{uint8_t md5_check_flag_size = sizeof(MD5_CHECK_MSG_FLAG) - 1;if ((start_address >= end_address) || ((end_address - start_address) <= md5_check_flag_size)) {return false;}end_address -= md5_check_flag_size;for (; end_address > start_address; end_address--) {if (memcmp(MD5_CHECK_MSG_FLAG, (uint8_t *)end_address, md5_check_flag_size) == 0) {mcu_update_info_t *md5_and_size = (mcu_update_info_t *)(end_address + md5_check_flag_size);if (md5_and_size->filesize == (end_address - start_address)) {MD5_CTX md5;uint8_t md5_value[16] = {0};port_trace("......APP_buildtime-->%d\n", md5_and_size->buildtime);port_trace("......firmware_size-->%d\n", md5_and_size->filesize);port_trace("find_md5-->");//port_dump(md5_and_size->md5, 16);MD5Init(&md5);MD5Update(&md5, (uint8_t *)start_address, md5_and_size->filesize);MD5Final(md5_value, &md5);port_trace("flash_md5-->");//port_dump(md5_value, 16);if (memcmp(md5_value, md5_and_size->md5, 16) == 0) {return true;}}}}port_trace("......No_find_APP_flag-->error\n");return false;
}

完整工程:CSDN下载:stm32f407-BootLoader程序_stm32f407bootloader跳转-嵌入式文档类资源-CSDN下载

百度云网盘:链接:https://pan.baidu.com/s/1dwrG1nA5voIhGBAimJgKDg 
提取码:yls4 
复制这段内容后打开百度网盘手机App,操作更方便哦

【STM32】BootLoader介绍、编写 以及 OTA常见方案分析(差分升级 全量升级 AB面升级)相关推荐

  1. OTA常见方案分析(差分升级 全量升级 AB面升级 Recovery系统升级)

    1.全量升级:   完整的下载新版本固件,下载完成后将固件搬运到APP程序运行的位置.(一般来说是将APP从片外flash搬运到片内flash上).搬运完成后校验通过后重启APP. 2.差分升级:   ...

  2. 企业级MySQL数据库备份方案:增量备份、全量备份、逻辑备份

    一份好的备份方案无非包括以下几点: 为什么需要备份? 备份的方式有哪些? 某几种备份方式的区别在哪? 备份实战操作概述 恢复实战操作概述 其它备注信息 那么,此文将从以上几个角度,结合一些实际的实战经 ...

  3. stm32 esp8266 ota升级-自建mqtt和文件服务器全量升级

    stm32 esp8266 ota系列文章: stm32 esp8266 ota-快速搭建web服务器之docker安装openresty stm32 esp8266 ota升级-tcp模拟http ...

  4. clickhouse集群部署方案分析

    常见的三种集群架构方案 注:本文摘自网上内容,原文地址:https://zhuanlan.zhihu.com/p/161242274 ClickHouse分布式集群常见方案一:MergeTree + ...

  5. 常见bootloader介绍

    一.BootLoader简介 在专用的嵌入式板子运行操作系统已经变得越来越流行.一个嵌入式系统从软件的角度看通常可以分为三个层次: 1. 引导加载程序.包括固化在固件(firmware)中的Boote ...

  6. STM32构建BootLoader实现多系统OTA

    STM32构建BootLoader实现多系统OTA 目录 STM32构建BootLoader实现多系统OTA 引言 一.基本概念 二.基础参考 三.认识STM32内置存储器扇区分布 四.构建BootL ...

  7. 新手必看的编程介绍,帮你推荐学习方案!

    新手必看的编程介绍,帮你推荐学习方案! VB是什么? ) y0 {6 G# G; j3 B VB 是Visual Basic编程语言 * B. O2 G# z) O1 |- g8 `4 ^ 编写计算机 ...

  8. STM32学习笔记 第二章 STM32资源介绍

    第二章 STM32资源介绍 2.1 芯片选型 STM32-F1系列(如图2-1): 基础型,主频为72M(内核为cortex-M3),CPU位数=32. 我们所用的芯片是STM32F103vet6 S ...

  9. Stm32 Bootloader整理

    Stm32 Bootloader整理 一.        基本概念 1.IAP IAP是In Application Programming的首字母缩写,IAP是用户自己的程序在运行过程中对User ...

最新文章

  1. python之钉钉机器人编程
  2. python编程内置函数使用方法_Python内置函数 next的具体使用方法
  3. 67 个JavaScript和CSS实用工具、库与资源
  4. 批量替换文件夹下所有文件的内容
  5. MySQL常用数据类型
  6. asp.net中涉及子文件夹的母版页和相对路径文件引用问题(一)
  7. python将h264文件视频转为mp4格式
  8. 计算机算法基础:分治法
  9. 绍兴文理学院计算机网络期末,绍兴文理学院高频电子线路期末考试题.doc
  10. OGRE CG教程 (三): 渐隐效果
  11. bzoj 2959: 长跑 lct+并查集
  12. 大数据hadoop讲解
  13. Python学习笔记——入门(IDLE的使用、标准库和模块、测试和调试、虚拟编程环境)
  14. fastlane build 版本号自增
  15. 第六节NoSQL+时序数据库+RabbitMQ安装
  16. Python中find_elements以及presence_of_element_located的用法
  17. 中小企业如何才能招聘到合适的程序员?
  18. 人工客服为什么总是接不通?
  19. ECharts仪表盘(详细示例——附有具体注释)
  20. img图片在webpack中使用

热门文章

  1. weborder什么意思_hp web是什么意思
  2. COSOSWAP官网2.0升级——线上圆桌会议重点回顾
  3. unity3d 取锚点位置_《王者荣耀》破晓之心碎片在哪 破晓之心碎片位置介绍
  4. mysql 免安装版 启动_Windows下配置启动免安装版本mysql
  5. 自动写稿机器人下载,写稿机器人有哪些,写稿机器人软件下载
  6. lms全称是什么意思_LMS是什么意思
  7. 宏基因组组装神器-MEGAHIT使用及常见问题
  8. 微信小程序创建订单号思路(附将带其它符号字符串转换成纯数字字符串)
  9. 一文带你了解APS生产计划排程系统
  10. 项目介绍之论文格式的自动检测与修改系统