STM32 Bootloader开发记录 2

news/2024/5/15 4:02:49/文章来源:https://blog.csdn.net/duapple/article/details/127833851

在《stm32 bootloader开发记录.md》文档中,已经实现了Bootloader下的升级功能。可以在Bootloader启动时,进入升级模式,使用串口传输数据,来下载固件到flash中。

但是,在实际应用中,一般是在应用运行过程中进行升级,而不是在Bootloader中进行升级。一般只有在开发阶段才需要在Bootloader中进行升级。所以,接下来,我将实现在app中进行升级操作,并且添加签名验签功能,保证升级过程中固件的安全性和完整性。

1. 分区划分

分区划分使用前面文档所说的flash map。应用分区有App1和App2,这里使用App1作为我们的应用分区,应用只会在App1中启动。而App2是固件存储分区,用来在App1运行过程中存储升级固件,固件下载到App2完成后,重启到Bootloader,然后让Bootloader把固件复制到App1中运行。

(当然,也可以不拷贝App2到App1,可以直接从Bootloader启动App2,这种方式可以增加flash的使用寿命,并且升级过程较快。这里不使用这种方式的原因是,我们的固件有修改过中断向量表,如果可以在App2中启动,那么我们需要对每个固件是在哪个分区启动要提前知道,并设置正确的终端向量表地址。为了不这么麻烦,这里使用前面所述的复制固件到固定地址运行的方式。)

image-20221014102840942

2. 升级原理

在App1中,我们依然使用串口接收数据,数据通信格式和Bootloader保持一致,这样,基本上可以不用修改dfu server程序的功能,就能完成升级了。在App1中接收固件,并将固件存储到App2分区,接收完成后,写入升级标致,然后重启。Bootloader在启动时,读取升级表示,识别到是App需要升级时,将App2分区的固件拷贝到App1分区中,如果复制过程没有问题了,清除写入标识,然后跳转到App1中运行新固件。

针对Bootloader,基本上也不需要修改什么,加上一个识别升级标识的代码,然后增加一个拷贝固件的功能就够了。

(签名验签功能, 需要使用到加密校验库,后面移植了mbedtls库再在拷贝固件的过程中加入验签即可。)

应用程序,在串口接收到"ota_start"字符串后,进入升级模式,开始使用之前定义的通信格式进行通信。dfu server加入一个发送"ota_start"的App 升级模式即可。

3. 代码

参考代码地址。

3.1 bootloader

拷贝固件

void ota_copy_app()
{uint32_t page_num = ota_info.header.firmware_size / 2048 + 1;uint8_t buffer_2k[2048] = {0};int i = 0, j = 0;uint32_t app2_addr = 0x8042000;uint8_t is_first = 1;flash_erase(FLASH_BANK_1, 32, 96);flash_erase(FLASH_BANK_2, 256, 4);for (; i < page_num; i++){memcpy(buffer_2k, (uint32_t *)(app2_addr + i * 2048), 2048);flash_write_fw(buffer_2k, 2048, is_first);is_first = 0;}ota_info.status = OTA_NONE;ota_info_write(&ota_info);
}

App升级模式

int main(void)
{HAL_Init();......if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) == GPIO_PIN_SET) {boot_to_ota = 1;printf("start ota\r\n");}ota_info_read(&ota_info);ota_info_print(&ota_info);HAL_UART_Receive_IT(&huart1, uart_rx.data, 1);printf("start uart IT receive\r\n");if (boot_to_ota == 0 && ota_info.status == OTA_READY){ota_copy_app();goto_application();}......
}

3.2 Application

串口接收

void ota_uart_receive_it(UART_HandleTypeDef *huart)
{HAL_UART_Receive_IT(&huart1, uart_rx.data + (++uart_rx.pos), 1);if (!ota_start_flag) {if (uart_rx.pos == 8) {uart_rx.pos = -1;}else if (uart_rx.pos == 0){char ota_start[] = "ota_start";if (strncmp((char *)uart_rx.data, ota_start, strlen(ota_start)) == 0){ota_start_flag = 1;HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);}}return;}if (uart_rx.pos > 256) {uart_rx.pos = -1;} else if (uart_rx.pos == 4) {uart_rx.data_size = uart_rx.data[2] | uart_rx.data[3] << 8;}else if (uart_rx.data_size + 8 == uart_rx.pos) {uart_rx_size = uart_rx.pos + 1;is_recv_frame_ok = 1;uart_rx.pos = -1;}
}uint8_t ota_start_flag_get(void)
{return ota_start_flag;
}

主业务逻辑

int main()
{......while (1){if (ota_start_flag_get() && start_ota() == 0) {HAL_Delay(100);HAL_NVIC_SystemReset();}}
}

3.3 dfu server

增加一个发送"ota_start"字符串的步骤。

    while (1){if (app_ota) {std::cout << "start app ota mode" <<std::endl;boost::system::error_code ec;char ota_start[] = "ota_start";port.write_some(boost::asio::buffer(ota_start, strlen(ota_start)), ec);}size_t n = port.read_some(boost::asio::buffer(data, sizeof(data)));if (n > 0 && !dfu_start){std::cout << "recv: " << std::string(data) << std::endl;dfu_start = true;sleep(2); //等待MCU启动

4. 测试

下载Bootloader、Application固件到开发板中。下载前,对整个flash进行擦除,防止升级标识错误导致测试失败。将PB2引脚拉低,防止Bootloader进入到下载模式。下载完成后,应用正常启动,应用版本号是5

----------------------------------------stm32l475 bootloader start
----------------------------------------
firmware size: -1
major: 0xff
minor: 0xff
status: OTA_RUNNING
start uart IT receive
haven't ota event
starting application
jump to application----------------------------------------stm32l475 application start
----------------------------------------
firmware version: 0x05
hardware version: 0x01
firmware size: -1
major: 0xff
minor: 0xff
status: OTA_RUNNING
start uart IT receive

这个开启dfu server,进行应用升级。开启前,先关闭串口助手的串口,防止串口占用导致dfu server打开串口失败。

.\dfu_server.exe G:\stm32\alentek_stm32l475_application\MDK-ARM\alentek_stm32l475_application\firmware6.bin COM4 app_ota

升级成功。

ff ff ff ff jump to application----------------------------------------stm32l475 application start
----------------------------------------
firmware version: 0x06
hardware version: 0x01

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_224040.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于单片机的指纹门禁设计

功能&#xff1a; 研究内容&#xff1a;本课题以单片机为核心采用C语言来开发一指纹电子密码锁。系统拟在Altium Designer9开发平台上设计原理图&#xff0c;并绘制PCB并制成单片机开发板&#xff0c;然后根据原理图将相关元器件焊接到开发板上。软件部分在Keil uVision4开发…

餐饮美食网页设计(HTML+CSS+JavaScript)

&#x1f380; 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

目标检测算法——自动驾驶开源数据集汇总2(附下载链接)

>>>深度学习Tricks&#xff0c;第一时间送达<<< 目录 一、Highway Driving 二、Mapillary Vistas 三、Cityscapes 四、CamVid >>>一起交流&#xff01;互相学习&#xff01;共同进步&#xff01;<<< 近期&#xff0c;小海带在空闲之余…

【FPGA】FPGA实现IIC协议读写EEPROM(二) -----EEPROM读写控制模块实现

EEPROM读写控制模块实现一、模块功能分析二、输入/输出信号三、EEPROM读写控制模块状态机四、EEPROM读写控制模块实现五、仿真测试写在前面&#xff1a; FPGA实现IIC协议读写EEPROM相关文章&#xff1a; IIC通信协议 【FPGA】FPGA实现IIC协议读写EEPROM&#xff08;一&#xff…

Kafka消费者之相关参数及分区分配再平衡

一、消费者重要参数 深刻的理解这些参数有利于大家在面对自己的项目场景上对配置文件有更好的把握&#xff01; 参数名称描述bootstrap.servers向 Kafka 集群建立初始连接用到的 host/port 列表。key.deserializer 和value.deserializer指定接收消息的 key 和 value 的反序列…

Spring--基于注解管理bean

基于注解管理bean 实验一&#xff1a;标记与扫描 注解 和 XML 配置文件一样&#xff0c;注解本身并不能执行&#xff0c;注解本身仅仅只是做一个标记&#xff0c;具体的功能是框架检测到注解标记 的位置&#xff0c;然后针对这个位置按照注解标记的功能来执行具体操作。 本质…

【ASM】字节码操作 工具类与常用类 asm-utils 与 asm-commons

1.概述 本章节主要是对 ASM中的 工具类与常用类 ,包asm-utils 与 asm-commons 两个包中的一些类进行讲解的介绍。 2. asm-util 在asm-util.jar当中,主要介绍CheckClassAdapter和TraceClassVisitor类。在TraceClassVisitor类当中,会涉及到Printer、ASMifier 和Textifier类。…

Vue中 引入使用 element-resize-detector 监听 Dom 元素 宽度、高度 变化

1. 前言 很多做pc端平台的小伙伴都遇到过这样一个问题&#xff1a;在做侧边栏菜单时会有一个收缩和展开的一个功能&#xff0c;在伸缩的过程中右边的页面的宽度就会随之改变。我上网查了查 &#xff0c;也动手试了试 window.onresize ()>{}。却不尽人意&#xff0c;因为它…

进程管理命令 动态监控进程 rpm yum

学习视频:074_韩顺平Linux_服务管理(2)_哔哩哔哩_bilibili 目录 进程管理命令基本介绍 PS命令 显示系统执行的进程 终止进程kill和killall 查看进程树pstree 服务管理 服务管理 打开或者关闭指定端口 动态监控进程 监控网络状态 …

数字IC手撕代码-XX公司笔试真题(脉冲密度调制)

前言&#xff1a; 本专栏旨在记录高频笔面试手撕代码题&#xff0c;以备数字前端秋招&#xff0c;本专栏所有文章提供原理分析、代码及波形&#xff0c;所有代码均经过本人验证。 目录如下&#xff1a; 1.数字IC手撕代码-分频器&#xff08;任意偶数分频&#xff09; 2.数字I…

nginx之https加密网站

目录 一、密钥算法 二、SSL虚拟主机 一、密钥算法 常见密钥算法&#xff1a; 对称加密&#xff1a;AES、DES 非对称加密&#xff1a;RSA、DSA 【注】对称加密的加密和解密使用的是同一把钥匙&#xff0c;非对称加密的加密和解密使用的不是一把钥匙&#xff0c;在对网…

0093 二分查找算法,分治算法

/* * 二分查找算法 * 前提&#xff1a;数组必须有序 * 1.确定该数组的中间值下标 mid(leftright)/2 * 2.让需要查找的数target和arr[mid]比较 * * 非递归算法 * 递归算法 */ public class BinarySearch_ { public static void main(String[] args) { int[…

【Python】常量和变量类型

目录 1.常量和表达式 2. 变量和类型 2.1 变量是什么 2.2 变量的语法 2.3 变量的类型 2.4 动态类型特性 1.常量和表达式 我们可以把Python当成一个计算器&#xff0c;来进行一些算式运算&#xff0c;如 print(1 2 - 1) print(1 2 * 2) print(1 2 / 2) 注&#xff1a;在…

pta-sql补题(2)

目录​​​​​​​ 插入insert&#xff1a; 两种语法形式&#xff1a; 插入记录&#xff08;一&#xff09; 表结构: 表样例 输出 插入记录&#xff08;二&#xff09; 表结构: 表样例 结果判定: 更新update 语法 更新记录&#xff08;一&#xff09; 表结构: …

Python——正则表达式的应用

文章目录前言正则表达式方法re.search方法group方法re.match方法re.findall方法re.finditer方法re.split方法re.sub方法正则表达式的应用前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 正则表达式是字符串处理的有力工具和技术。 使用正在表达式的目的…

Hackthebox系列 Starting point Tier0 Meow记录

免责声明&#xff1a;本教程仅限学术讨论使用&#xff0c;请勿作用于非法用途&#xff01;&#xff01;&#xff01;如有用于非法用途&#xff0c;本人概不负责。 目录题目来源题目TASK 1TASK 2TASK 3TASK 4TASK 5TASK 6NMAP端口扫描TASK 7Telnet访问TASK 8TASK 9参考题目来源 …

【RPC框架、RPC框架必会的基本知识、手写一个RPC框架案例、优秀的RPC框架Dubbo、Dubbo和SpringCloud框架比较】

一.RPC框架必会的基本知识 1.1 什么是RPC&#xff1f; RPC&#xff08;Remote Procedure Call ——远程过程调用&#xff09;&#xff0c;它是一种通过网络从远程计算机程序上请求服务&#xff0c;而不需要了解底层网络的技术。 一次完整的RPC同步调用流程&#xff1a; 服务…

rust编程语言(chapter 1)

目录 1. rust安装 2. Hello Rust 3. Cargo包管理器 3.1 cargo简介 3.2 cargo创建项目 3.3 构建和运行项目 3.4 debug和release版本构建 1. rust安装 rust提供了一个命令行的工具rustup&#xff0c;可以用来管理和安装rust的版本以及相关的工具集。 那么首先&#xff0c…

python游戏库pygame经典教程

目录 一.Pygame程序基本搭建过程 1.初始化化程序 2.创建Surface对象 3.事件监听 4.游戏循环 二.Pygame Display显示模块详解 1.将Surface对象粘贴至主窗口上 2.设置窗口主窗口 3.填充主窗口背景&#xff0c;参数值RGB 4.设置窗口标题 5.更新屏幕内容 6.pygame.display其他方…

java家政服务中心网站mysql

目 录 第一章 绪论 5 1.1 课题开发背景 5 1.2 课题研究意义 5 1.3 本课题主要工作 5 第二章 相关技术介绍 6 2.1 JSP技术 6 2.2 MyEclipse 6 2.3 MySQL数据库 7 2.4 J2EE 技术 8 2.5 B/S架构 9 第三章 系统分析 12 3.1 系统可行性分…