程序升级bootloader

文章目录

      • 概述
      • 什么是bootloader?为什么用?
      • bootloader启动流程图
        • 步骤
      • 下载过程
      • 代码
        • 获取本地配置信息
        • 获取主机传过来的配置信息
        • bootloader发送2给上位机,上位机发送文件给bootloader
        • 根据网站复制CRC
      • 烧写flash
        • erase
        • 启动
        • 编译问题

概述

用keil编写app,来用bootloader更新app,完成灯闪烁指令,升级app的新版本就是灯闪烁的更快了;
通过usb直接传输更新的配置给开发板,然他自己启动bootloder,擦除原来的app和配置信息,烧录新的app和配置信息;
image.png
image.png

什么是bootloader?为什么用?

运行时,bootloader会先启动,如果有程序升级,bootloader从RAM里面下数据烧录到flash的一块空间上面,就是app;
其中突然断电没烧录完也没事,bootloader等下次启动又会重新烧录,如果没有bootloader,app不是完整的也不能直接启动,就不能用了;
原本没有bootloader怎么运行的:
RAM如果很小,里面不会去在复制一个app进去,问题就是此时上点时是flash的app程序在从RAM下载烧录数据到flash的app,这直接把自己覆盖了呀,那会出错的;
image.png
RAM如果很大,那RAM存一个APP,运行是就用RAM的APP,然后把升级的app数据下载烧录到flash上把他覆盖,这样就不会出现上面的问题了,但是断电就会导致flash上的APP没烧录完整,下次通电先打开flash就打不开了;
通电先执行flash;
image.png
image.png

bootloader启动流程图

STM32H563RIV
image.png
image.png

cpu是ARM公司生产的,他们设定只能从0开始读,因此要设置映射关系,让cpu一开始在flash的地址0x0800 0000;
1、cpu从0开始读4个字节存入sp寄存器;
2、cpu从4这个地址读到4个字节存入pc寄存器
image.pngimage.png

发生中断时:
硬件会做的事:在异常向量表里面找到函数,执行
我们需要操作的是:告诉cpu异常向量表的基地址
image.png
下图为有无bootloader的异常向量表的首地址
image.png
要把这个//,因为这个是异常向量表,是flash开头的异常向量表
image.png
把flash开始烧录的地址移到0804000,前面的给bootloader;
image.png

步骤

image.png
传进来的参数是存在寄存器R0里面的;
把R0的数据写入寄存器VTOR
把R0的数值存入R1所指向的位置;
VTOR保存的是异常向量表的基地址;
image.png
从R0这里读取R1;
把R1的数值写给栈SP寄存器;
image.png
跳转到R0+4的位置

下载过程

1、bootloader发送“1”字符给上位机,请求固件信息;
2、上位机给bootloader发送固件信息:先发同步字符;
image.png
上位机发送的固件信息
a、长度信息
b、加载地址
c、校验码
d、文件名
e、版本号
image.png
3、bootloader决定升级
发送0x02给上位机;
4、上位机发送bin文件给bootloader
收到后bootloader会(1)计算CRC校验码,(2)与之前收到的固件信息比较;
5、bootloader开始烧写,同时可以发送烧写进度给上位机

生成设备信息
用这个create_firemware_info来生成脚本
image.png

代码

获取本地配置信息

#define CFG_OFFSET 0x081FE000//设备地址

file_len是判断配置信息有没有写
image.png

获取主机传过来的配置信息

image.png
先是usb传输发送1;
接收上机回应信号5个0x5a;
接收上机设备配置信息32个寄存器;
image.png

bootloader发送2给上位机,上位机发送文件给bootloader

上位机发送文件时就会发送一系列的数据,超时时间*10,给上位机充分时间发送
image.png

根据网站复制CRC

image.png

bootloaderTask
这里任务要等待一会
因为usb插到电脑上,要等电脑识别出来usb,才能进行传输,
image.png

获取固件失败的原因?
数据丢失,上位机发送数据给bootloader,是不是数据没有接收全,数据覆盖了,数据丢失了;
先看是不是数据接收不全,怎么看呢,我们是创建队列来接收的,队列初始化时的大小看一下,能不能装得下;
找到usb传输的队列只有200bit,但是传输的数据有5kb ,5x1024bit,把队列改成10kb=10240bit
image.png
image.png
BootTask整体流程:
无标题.png

#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os2.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "draw.h"
#include "stdio.h"
#include "draw.h"
#include "ux_api.h"
#include "modbus.h"
#include "errno.h"
#include "uart_device.h"
#include "semphr.h"#include "bootloader.h"#define UPDATE_TIMEOUT 1000//超时时间#define CFG_OFFSET 0x081FE000static struct UART_Device *g_pUpdateUART;static uint32_t BE32toLE32(uint8_t *buf)
{return ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) | ((uint32_t)buf[2] << 8) | ((uint32_t)buf[3] << 0);
}static int GetLocalFirmwareInfo(PFirmwareInfo ptFirmwareInfo)
{PFirmwareInfo ptFlashInfo = (PFirmwareInfo)CFG_OFFSET;if (ptFlashInfo->file_len == 0xFFFFFFFF)return -1;*ptFirmwareInfo = *ptFlashInfo;return 0;
}static int GetServerFirmwareInfo(PFirmwareInfo ptFirmwareInfo)
{uint8_t data = '1';uint8_t buf[sizeof(PFirmwareInfo)];/*send 0x01 cmd to pc*/if(0 != g_pUpdateUART->Send(g_pUpdateUART, &data, 1, UPDATE_TIMEOUT))return -1;/*wait for response*/while(1){if(0 != g_pUpdateUART->RecvByte(g_pUpdateUART, &data, UPDATE_TIMEOUT*10))return -1;if(data != 0x5a){buf[0] = data;break;}}for(int i = 1; i < sizeof(PFirmwareInfo); i++){if(0 != g_pUpdateUART->RecvByte(g_pUpdateUART, &buf[i], UPDATE_TIMEOUT))return -1;}ptFirmwareInfo->version = BE32toLE32(&buf[0]);ptFirmwareInfo->file_len = BE32toLE32(&buf[4]);ptFirmwareInfo->load_addr = BE32toLE32(&buf[8]);ptFirmwareInfo->crc32 = BE32toLE32(&buf[12]);strncpy((char *)ptFirmwareInfo->file_name, (char *)&buf[16], 16);return 0;}static int GetServerFirmware(uint8_t *buf, uint32_t len)
{uint8_t data = '2';/*send 0x01 cmd to pc*/if(0 != g_pUpdateUART->Send(g_pUpdateUART, &data, 1, UPDATE_TIMEOUT))return -1;/*上位机发送文件给bootloader*/for(int i = 0; i < len; i++){if(0 != g_pUpdateUART->RecvByte(g_pUpdateUART, &buf[i], UPDATE_TIMEOUT*10))return -1;}return 0;
}/* https://lxp32.github.io/docs/a-simple-example-crc32-calculation/ */
static int GetCRC32(const char *s,size_t n)
{uint32_t crc=0xFFFFFFFF;for(size_t i=0;i<n;i++) {char ch=s[i];for(size_t j=0;j<8;j++) {uint32_t b=(ch^crc)&1;crc>>=1;if(b) crc=crc^0xEDB88320;ch>>=1;}}return ~crc;
}void BootLoaderTask( void *pvParameters )	
{struct UART_Device *pUSBUART = GetUARTDevice("usb");FirmwareInfo tLocalInfo;FirmwareInfo tServerInfo;int err;int need_update = 0;uint8_t *firmware_buf;vTaskDelay(10000); /* wait for pc ready */pUSBUART->Init(pUSBUART, 115200, 'N', 8, 1);g_pUpdateUART = pUSBUART;while (1){/* read cfg info, to detect app's version */err = GetLocalFirmwareInfo(&tLocalInfo);if (err){/* update */need_update = 1;}else{pUSBUART->Send(pUSBUART, (uint8_t *)"GetLocalFirmwareInfo Failed\r\n", strlen("GetLocalFirmwareInfo Failed\r\n"), UPDATE_TIMEOUT);}err = GetServerFirmwareInfo(&tServerInfo);if (!err){/* compate version */if (tServerInfo.version > tLocalInfo.version){/* update */need_update = 1;}}else{need_update = 0;pUSBUART->Send(pUSBUART, (uint8_t *)"GetServerFirmwareInfo Failed\r\n", strlen("GetServerFirmwareInfo Failed\r\n"), UPDATE_TIMEOUT);}if (need_update){firmware_buf = pvPortMalloc(tServerInfo.file_len);if (!firmware_buf){/* error */pUSBUART->Send(pUSBUART, (uint8_t *)"Malloc Failed\r\n", strlen("Malloc Failed\r\n"), UPDATE_TIMEOUT);}err = GetServerFirmware(firmware_buf, tServerInfo.file_len);if (!err){/* calc CRC */                uint32_t crc = GetCRC32((const char *)firmware_buf, tServerInfo.file_len);if (crc == tServerInfo.crc32){/* OK *//* burn */pUSBUART->Send(pUSBUART, (uint8_t *)"Download OK\r\n", 13, UPDATE_TIMEOUT);}else{pUSBUART->Send(pUSBUART, (uint8_t *)"GetCRC32 Failed\r\n", strlen("GetCRC32 Failed\r\n"), UPDATE_TIMEOUT);}}else{pUSBUART->Send(pUSBUART, (uint8_t *)"GetServerFirmware Failed\r\n", strlen("GetServerFirmware Failed\r\n"), UPDATE_TIMEOUT);}}else{/* start app */}}
}

烧写flash

对比flash上面的版本比主机发过来的版本小,或者flash上面的配置信息坏了,就启动升级:
1、erase 擦除flash
2、烧写

flash有两个栈区,bank1和bank2 128个栈区x 每个栈区8k
把中间蓝色圈APP擦除再烧录,只是更新APP,以及把配置文件的信息改成对应的最新的;
image.png

erase

image.png
1、擦除app并烧录
擦除bank1和bank2的APP的,APP的长度可能延伸到了bank2有if进行判断,传入的地址是bootloader后的,也就是APP开头地址
3.png
2、擦除配置文件并烧录
image.png
3、bootloadertask
下载完成主机发送过来的配置文件就用1、2这两个函数进行擦除烧录;
image.png

启动

触发软件复位
1.png
复位最终会调用main
image.png
如果是复位的话就会得到flash上面这个应用程序的基地址,然后调用这个汇编函数start_app来启动程序
2.png
注意:
image.png

编译问题

non-ASCLL表示引入了中文字符
image.png

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

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

相关文章

声明队列和交换机 + 消息转换器

目录 1、声明队列和交换机 方法一&#xff1a;基于Bean的方式声明 方法二&#xff1a;基于Spring注解的方式声明 2、消息转换器 1、声明队列和交换机 方法一&#xff1a;基于Bean的方式声明 注&#xff1a;队列和交换机的声明是放在消费者这边的&#xff0c;这位发送的人他…

Dynamic Web Module facet version问题

The default superclass, "javax.servlet.http.HttpServlet", according to the projects Dynamic Web Module facet version (3.1), was not found on the Java Build Path. 1.右键项目 2.点击Properties 3.点击Java Build Path&#xff0c;右边找到Libraries&…

大模型在营销领域的探索及创新

1 AIGA介绍 2 AIGA在营销领域的 应用和探索 3 总结与展望

docker-compose Install gitlab 17.1.1

gitlab 前言 GitLab 是一个非常流行的开源 DevOps 平台,用于软件开发项目的整个生命周期管理。它提供了从版本控制、持续集成/持续部署(CI/CD)、项目规划到监控和安全的一系列工具。 前提要求 Linux安装 docker docker-compose 参考Windows 10 ,11 2022 docker docker-c…

(ECCV,2022)Mask-CLIP:从CLIP中提取自由密集标签

文章目录 Extract Free Dense Labels from CLIP相关资料摘要引言方法Mask-CLIPMask-CLIP 实验 Extract Free Dense Labels from CLIP 相关资料 代码&#xff1a;https://github.com/chongzhou96/MaskCLIP 论文&#xff1a;https://arxiv.org/abs/2112.01071 摘要 对比语言-…

SprongBoot及其基础应用全套部署脚本和配置

POM.xml配置 </dependencies> <!--skywalking日志监控依赖--><dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-logback-1.x</artifactId><version>8.5.0</version></dependency&g…

【周末闲谈】AI“抢饭碗”?绝对不是危言耸听

AI是在帮助开发者还是取代他们? 在软件开发领域,生成式人工智能(AIGC)正在改变开发者的工作方式。无论是代码生成、错误检测还是自动化测试,AI工具正在成为开发者的得力助手。然而,这也引发了对开发者职业前景和技能需求变化的讨论。AI究竟是在帮助开发者还是取代他们?…

2024组装一台能跑AI大模型的电脑

title: 2024组装一台能跑AI大模型的电脑 tags: [组装电脑, AI大模型] categories: [其他, 电脑, windows] 这里不写组装步骤&#xff0c;哪里接线&#xff0c;购买什么品牌网上一大堆。 这里只写如何根据你自己的需求&#xff0c;选择合适的、兼容的配件。 概述 需求&#xff…

本地多卡(3090)部署通义千问Qwen2-72B大模型提速实践:从龟速到够用

最近在做文本风格转化&#xff0c;涉及千万token级别的文本。想用大模型转写&#xff0c;在线的模型一来涉及数据隐私&#xff0c;二来又不想先垫钱再找报销。本地的7-9B小模型又感觉效果有限&#xff0c;正好实验室给俺配了4卡3090的机子&#xff0c;反正也就是做个推理&#…

运维系列.Nginx配置中的高级指令和流程控制

运维专题 Nginx配置中的高级指令和流程控制 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/…

ssrf结合redis未授权getshell

目录 漏洞介绍 SSRF Redis未授权 利用原理 环境搭建 利用过程 rockylinux cron计划任务反弹shell 写公钥免密登录 ubuntu 写公钥免密登录 漏洞介绍 SSRF SSRF&#xff08;server side request forgrey&#xff09;服务端请求伪造&#xff0c;因后端未过滤用户输入&…

桂花网蓝牙网关X1000:引领物联网新时代的智能连接

在物联网技术飞速发展的今天&#xff0c;蓝牙网关作为连接蓝牙设备与互联网的关键设备&#xff0c;其性能与稳定性直接影响到物联网系统的整体运行效果。桂花网蓝牙网关X1000凭借其卓越的性能和广泛的应用场景&#xff0c;成为了物联网领域的佼佼者。 一、产品概述 桂花网蓝牙…

使用Ckman部署ClickHouse集群介绍

使用Ckman部署ClickHouse集群介绍 1. Ckman简介 ClickHouse Manager是一个为ClickHouse数据库量身定制的管理工具&#xff0c;它是由擎创科技数据库团队主导研发的一款用来管理和监控ClickHouse集群的可视化运维工具。目前该工具已在github上开源&#xff0c;开源地址为&…

Angluar 实现pdf页面预览以及编辑

之前用过一个pdf预览的lib&#xff0c;并且还支持在线编辑&#xff0c;和直接下载编辑之后的pdf和直接打印&#xff0c;还不错&#xff0c;记录下 PdfShowcase 首先安装依赖 npm install ngx-extended-pdf-viewer 然后引入 import { NgxExtendedPdfViewerModule } from &q…

硅纪元视角 | 中国电信“星辰大模型·软件工厂”,两分钟完成应用开发,效率飞跃!

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…

【数据结构】链表带环问题分析及顺序表链表对比分析

【C语言】链表带环问题分析及顺序表链表对比分析 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C语言学习之路 文章目录 【C语言】链表带环问题分析及顺序表链表对比分析前言一.顺序表和链表对比1.1顺序表和链表的区别1.2缓存利用率&#…

Linux基础: 二. Linux的目录和文件

文章目录 二. Linux的目录和文件1.1 目录概要1.2 目录详细说明 二. Linux的目录和文件 1.1 目录概要 command&#xff1a;ls / Linux的文件系统像一棵树一样&#xff0c;树干是根目录&#xff08;/&#xff09;&#xff0c;树枝是子目录&#xff0c;树叶是文件&#xff1b; …

亚信安全发布2024年6月威胁态势,高危漏洞猛增60%

近日&#xff0c;亚信安全正式发布《2024年6月威胁态势报告》&#xff08;以下简称“报告”&#xff09;&#xff0c;报告显示&#xff0c;6月份新增信息安全漏洞 1794个&#xff0c;高危漏洞激增60%&#xff0c;涉及0day漏洞占67.67%&#xff1b;监测发现当前较活跃的勒索病毒…

应用案例 | 基于物联网工控屏的工业离心机设备监控系统

案例概况 客户&#xff1a;博鲁班特&#xff08;BROADBENT&#xff09; 应用产品&#xff1a;宏集物联网工控屏 应用场景&#xff1a;离心机设备监控系统 一、前言 在现代工业生产中&#xff0c;离心机作为关键的分离设备&#xff0c;在生产过程中扮演着至关重要的角色。随…

谷粒商城学习笔记-17-快速开发-逆向工程搭建使用

文章目录 一&#xff0c;克隆人人开源的逆向工程代码二&#xff0c;把逆向工程集成到谷粒商城的后台工程三&#xff0c;以商品服务为例&#xff0c;使用逆向工程生成代码1&#xff0c;修改逆向工程的配置2&#xff0c;以Debug模式启动逆向工程3&#xff0c;使用逆向工程生成代码…