IAP固件升级分几步?(Qt上位机、)
前言
这周一直想做一个IAP固件升级的上位机,然后把升级流程全都搞懂
有纰漏请指出,转载请说明。
学习交流请发邮件 1280253714@qq.com
IAP原理
IAP的原理我就不多赘述了,这里贴上几位大佬的文章
STM32CubeIDE IAP原理讲解,及UART双APP交替升级IAP实现-CSDN博客
STM32 IAP升级固件 + 上位机 例程 | 码农家园
IAR环境下STM32+IAP方案的实现
之前做过IAP,也讲解了一些存在的问题,参考之前我写的博客
单片机IAP升级的一些问题与经验_iap更新_TianYaKe-天涯客的博客-CSDN博客
Qt读取二进制文件
读取二进制文件,将内容放在binRawData里
void MainWindow::readFw()
{QFileDialog dlg(this);QString fileName = dlg.getOpenFileName(this, tr("Open"), "./", tr("Bin File(*.bin)"));if( fileName == "" ){return;}QFile file(fileName);QFileInfo fileInfo(fileName);fwFileLen = fileInfo.size();fwPackNum = fwFileLen/fwPackLength + 1;if(file.open(QIODevice::ReadOnly)){binRawData = file.readAll();ui->lineEdit_fwUpdateFile->setText(fileName);ui->textEdit_fwUpdateFile->append(binRawData.toHex());file.close();ui->pushButton_startFwUpdate->setEnabled(true);ui->pushButton_stopFwUpdate->setEnabled(false);}else{QMessageBox::warning(this, tr("Error"), tr("Fail to open file!"));}
}
将binRawData拆包,并调用串口发送
connect(fwUpdateTimer,&QTimer::timeout,[=](){if(fwUpdateState == 1){QByteArray fwSendBuff = binRawData.mid(fwPackIndex*fwPackLength+1,fwPackLength);fwPackIndex++;serialPort->write(fwSendBuff);if(fwPackIndex>fwPackNum){fwUpdateTimer->stop();fwUpdateState = 3;}}});

加上固件传输的协议

发送开始指令,发送固件包大小
void MainWindow::startFwUpdate()
{ui->pushButton_startFwUpdate->setEnabled(false);ui->pushButton_stopFwUpdate->setEnabled(true);fwUpdateState = fwStart;QByteArray startCmd;uchar startCmd1 = 0xAB;uchar startCmd2 = 0xf0;startCmd = loadTxMsg(startCmd1, startCmd2, &startCmd);serialPort->write(startCmd);delay_ms(1000);uchar cmd1 = 0xAB;uchar cmd2 = 0xf1;uchar uData[2];uint16_t u16FwPackNum = fwPackNum;*(uint16_t *)&uData[0] = *(uint16_t *)&u16FwPackNum;QByteArray txFwData;txFwData.append(uData[0]);txFwData.append(uData[1]);txFwData = loadTxMsg(cmd1, cmd2, &txFwData);serialPort->write(txFwData);fwUpdateTimer->start(100);
}
通过定时器逐帧传输,传输结束后发送结束信号
connect(fwUpdateTimer,&QTimer::timeout,[=](){if(fwUpdateState == fwStart){QByteArray fwSendBuff = binRawData.mid(fwPackIndex*fwPackLength,fwPackLength);fwSendBuff.insert(0,fwSendBuff.length());QByteArray fwSendProtocolBuff = loadFwPackData(&fwSendBuff);serialPort->write(fwSendProtocolBuff);fwPackIndex++;QString fwDataString = ByteArrayToHexString(fwSendProtocolBuff).toLatin1();ui->textEdit_fwInfo->clear();ui->textEdit_fwInfo->setWordWrapMode(QTextOption::WordWrap);ui->textEdit_fwInfo->insertPlainText(QString("["));ui->textEdit_fwInfo->insertPlainText(QString::number(fwPackIndex));ui->textEdit_fwInfo->insertPlainText(QString("] "));ui->textEdit_fwInfo->insertPlainText(fwDataString);if(fwPackIndex>=fwPackNum){fwUpdateState = fwComplete;fwUpdateTimer->stop();QByteArray stopCmd;uchar stopCmd1 = 0xAB;uchar stopCmd2 = 0xf3;stopCmd = loadTxMsg(stopCmd1, stopCmd2, &stopCmd);serialPort->write(stopCmd);}}});
STM32代码部分
iap.h
#ifndef __IAP_H
#define __IAP_H#include "includes.h"#define __APP_START_ADDR 0x08010000U
#define __APP_SIZE 0x10000Utypedef enum
{IAP_START,IAP_TRANFER,IAP_COMPLETE,
} IAP_Status;typedef struct
{u8 u8Length; // 当前接受到数据帧的帧长u8 u8Data[64]; // 当前接受到的数据
} RcvFrame_S;typedef struct
{IAP_Status state; // ipa升级当前状态RcvFrame_S stRcvFrame; // 接受到的数据u16 u16FwFrameNum; // 固件数据帧总量u16 u16FwFrameIndex; // 固件数据帧偏移u32 u32WriteAddrIndex; // 写地址偏移
} IAP_S;extern IAP_S stIap;
void IapRcvDataProc(u8 *MsgData);
typedef void (*Application)(void);
void JumpToApplication(void);
#endif //__IAP_H
iap.c
#include "includes.h"IAP_S stIap;void IapRcvDataProc(u8 *MsgData)
{u8 cmd = MsgData[3];u8 i = 0;switch(cmd){case 0xF1:EraseFwSpace(__APP_START_ADDR,__APP_SIZE/__FLASH_PAGE_SIZE);memcpy(&stIap.u16FwFrameNum, &MsgData[4], 2);break;case 0xF2:stIap.u16FwFrameIndex++;stIap.stRcvFrame.u8Length = MsgData[6]; memcpy(&stIap.stRcvFrame.u8Data, &MsgData[7], stIap.stRcvFrame.u8Length);for(i = 0; i < stIap.stRcvFrame.u8Length; i += 4) //一次写入是4个字节{FlashWriteWord(__APP_START_ADDR+stIap.u32WriteAddrIndex, *(u32 *)&stIap.stRcvFrame.u8Data[i]);stIap.u32WriteAddrIndex += 4; //写入的地址加4} break;case 0xF3:JumpToApplication();}}void JumpToApplication(void)
{ Application application;__set_FAULTMASK (1);application = (Application)(*(__IO u32*)(__APP_START_ADDR+4));__set_MSP(*(__IO u32*)(__APP_START_ADDR));SCB->VTOR = __APP_START_ADDR;application();
}
视频演示
IAP固件升级(Qt上位机)最初版0923_哔哩哔哩_bilibili
IAP固件升级(Qt上位机)最初版0923
相关文章:
IAP固件升级分几步?(Qt上位机、)
前言 这周一直想做一个IAP固件升级的上位机,然后把升级流程全都搞懂 有纰漏请指出,转载请说明。 学习交流请发邮件 1280253714qq.com IAP原理 IAP的原理我就不多赘述了,这里贴上几位大佬的文章 STM32CubeIDE IAP原理讲解,及U…...
Otter改造 增加springboot模块和HTTP调用功能
环境搭建 & 打包 环境搭建: 进入 $otter_home/lib 目录执行:bash install.sh 打包: 进入$otter_home目录执行:mvn clean install -Dmaven.test.skip -Denvrelease发布包位置:$otter_home/target 项目背景 阿里…...
Vue.js vs React:哪一个更适合你的项目?
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…...
Debian环境下搭建STM32开发环境
1. 安装交叉编译工具,解压gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2,并且把交叉编译环境添加到path路径。 2.安装下载工具驱动和下载工具 # 安装下载工具openocd sudo apt -y install openocd 3.下载测试 sudo openocd -f cmsis-dap.cfg -…...
如何防止商业秘密泄露(洞察眼MIT系统商业机密防泄密解决方案)
在当今的商业环境中,保护公司的商业秘密是至关重要的。商业秘密可能包括独特的业务流程、客户列表、研发成果、市场策略等,这些都是公司的核心竞争力。一旦这些信息被泄露,可能会对公司的生存和发展产生重大影响。本文将探讨如何通过使用洞察…...
题目 1062: 二级C语言-公约公倍
输入两个正整数m和n,求其最大公约数和最小公倍数。样例输入 2 3样例输出 1 6 这题一知半解的, 最小公倍数两数の积/最大公约数; 最大公约数通过迭代法求得(见其下), 作为a,b两数有一个属为有一个为0为无效数据时 《-----a%b等…...
【Leetcode】148.排序链表
一、题目 1、题目描述 给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。 示例1: 输入:head = [4,2,1,3] 输出:[1,2,3,4]示例2: 输入:head = [-1,5,3,4,0] 输出:[-1,0,3,4,5]示例3: 输入:head = [] 输出:[]提示: 链表中节点的数目在范围 [0, 5 …...
用《斗破苍穹》的视角打开C#多线程开发1(斗帝之路)
Thread.Start() 是的,我就是乌坦城那个斗之气三段的落魄少爷,在我捡到那个色眯眯的老爷爷后,斗气终于开始增长了。在各种软磨硬泡下,我终于学会了我人生中的第一个黄阶斗技——吸掌。 using System.Threading;namespace Framewo…...
图像处理与计算机视觉--第三章-颜色与纹理分析-6问
图像处理与计算机视觉--第三章-颜色与纹理分析-6问 1.哪些因素决定物体颜色的感知? 对于物体颜色的感知,主要取决于以下三个因素: 1.照射到物体表面光波长的分布 2.物体表面如何反射照射光 3.传感器或者视觉细胞的敏感性 除了上述的三个因素之外,…...
vue重修002
文章目录 版权声明一 指令修饰符1. 什么是指令修饰符?2. 按键修饰符3. v-model修饰符4. 事件修饰符 二 v-bind对样式控制的增强-操作class1. 语法:2. 对象语法3. 数组语法4. 代码练习 三 京东秒杀-tab栏切换导航高亮四 v-bind对有样式控制的增强-操作sty…...
[PowerQuery] PowerAutoMate 刷新PowerBI 数据
通过PowerBI Automate 进行PowerBI 数据刷新之前,需要有Power Automate 授权或者Power Automate 试用账户,可以通过如下的地址进行申请注册。 https://flow.microsoft.com/zh-cn/ 完成Power Automate 登录之后,选中计划的云端流后创建,图为创建计划的云端流的操作步骤。 …...
C语言中各种接口标准
1.POSIX(Portable Operating System Interface,可移植操作系统接口):是一个定义了操作系统接口标准的家族。它旨在提供一致的API(Application Programming Interface,应用程序编程接口)和环境&a…...
vscode常用插件
koroFileHeader: 设置详情, 文件头自动注释 code runner: 支持多语言编译运行 git lens: git 提交可视化查看工具 Markdown配套软件: Markdown All in One: Markdown文档工具集成Markdown PDF: Markdown文档导出为PDFMarkdown Preview Enhanced: 分屏查…...
代码随想录算法训练营day60|84.柱状图中最大的矩形 |完结撒花~
84.柱状图中最大的矩形 力扣题目链接 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩形的最大面积。 1 < heights.length <10^5 0 < heights[i] < 10^…...
在 android 上使用 adb client
adb tool 分为 adb 和 adbd。 adb 用作 host 使用,包含了client和server,adbd 则作为 device 端,在 android 源码目录下,共用一套源码。但 android 源码下的 adb,不支持把 adb 编译为 android 平台的 adb client。因此…...
竞赛选题 基于深度学习的视频多目标跟踪实现
文章目录 1 前言2 先上成果3 多目标跟踪的两种方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟踪过程4.1 存在的问题4.2 基于轨迹预测的跟踪方式 5 训练代码6 最后 1 前言 🔥 优质竞赛项目系列,今天要分享的是 基于深度学习的视频多目标跟踪实现 …...
分布式应用之监控平台zabbix的认识与搭建
一、监控系统的相关知识 1.1 监控系统运用的原因 当我们需要实时关注与其相关的各项指标是否正常,往往存在着很多的服务器、网络设备等硬件资源,如果我们想要能够更加方便的、集中的监控他们,zabix可以实现集中监控管理的应用程序 监控的…...
C语言大佬的必杀技---宏的高级用法
C语言大佬的必杀技—宏的高级用法 目录: 字符串化标记的拼接宏的嵌套替换多条语句防止一个文件被重复包含宏和函数的区别 可能大家在学习的时候用得比较少,但是在一些代码量比较大的时候,这样使用,可以大大的提高代码的可读性,…...
@Retryable和Guava retry
文章目录 一、spring的Retryable1.1 作用:1.2链接:https://www.cnblogs.com/EasonJim/p/7684649.html1.3 坑1.4 Recover补充依赖 二、Guava-retry:使用 一、spring的Retryable 1.1 作用: Retryable注解,被注解的方法…...
conda的安装和使用
参考资料: https://www.bilibili.com/read/cv8956636/?spm_id_from333.999.0.0 https://www.bilibili.com/video/BV1Mv411x775/?spm_id_from333.999.0.0&vd_source98d31d5c9db8c0021988f2c2c25a9620 目录 conda是啥以及作用conda的安装conda的启动conda的配置…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...
