STM32串口IAP升级

STM32串口IAP升级

1.分区

L073RZ 192K + 6K

分区大小
Bootloader64K
APP72K
Backup72K
Memory6K

分区 | 大小 | 备注 |
Bootloader | 64K | 引导程序 |
APP | 72K | App运行 |
Backup | 72K | APP备份 |
Memory | 6K | 数据存储 |


2.工程创建

1)BOOT

a.IR0M1
Bootloader的起始地址: 0x8000000
Bootloader的Size: 0x9000

b.定义

#define APPLICATION_ADDRESS     (uint32_t)0x801E000   		/* Start user code address */  
#define BACKUP_APPADDRESS		(uint32_t)0x800C000			/* Backup code : APP2 */

c.APP跳转

pFunction JumpToApplication;
uint32_t JumpAddress = 0;
void ExecApplication(void)
{ __disable_irq(); /* 在跳转APP之前,关闭中断。 *//* Test if user code is programmed starting from address "APPLICATION_ADDRESS" */if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000){/* Jump to user application */JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);JumpToApplication = (pFunction) JumpAddress;/* Initialize user application's Stack Pointer */__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);JumpToApplication();}	
}

d.需启用CRC校验

2)APP

设置中断向量表偏移地址:

#include "system_stm32l0xx.c"/*!< Uncomment the following line if you need to relocate your vector Table inInternal SRAM. */
/* #define VECT_TAB_SRAM */
#ifdef SOTA_APP1
#define VECT_TAB_OFFSET  0X0C000U#else
#ifdef	SOTA_APP2
#define VECT_TAB_OFFSET  0X1E000U#else
#define VECT_TAB_OFFSET  0x00U /*!< Vector Table base offset field.This value must be a multiple of 0x100. */
#endif			
#endif	

keil的bin文件生成

C:\Keil_v5\ARM\ARMCC\bin\fromelf.exe --bin -o ./Objects/@L.bin ./Objects/@L.axf
其中,./Objects为当前文件下的Objects文件夹

APP1
a.IR0M1
Bootloader的起始地址: 0x801E000
Bootloader的Size: 0x12000
b.APP1作为更新区,更新的固件存在此处并运行。

APP2
a.IR0M1
Bootloader的起始地址: 0x801E000
Bootloader的Size: 0x12000
b.APP2作为备份区,单片机一上电进入的是APP2,如果进行了固件升级则上电进入APP1,APP2一直不变。

3.总体流程

Bootloader程序设计思路:
单片机上电进入Bootloader,先判断升级标志是否需要升级固件,不需要则判断APP2中断向量表是否正确,后跳转至APP2即备份区;需要就进入等待接收文件状态。
接收完更新文件后,将数据写入APP1地址,清除标志,重启单片机进入APP1。

APP程序设计思路:
系统初始化后,调用__enable_irq();打开中断总开关,因为Bootloader里面关闭了中断总开关。在while(1)中等待接收串口升级的标志。

注意: 在往flash里写数据之前,应先关闭中断__disable_irq();,写完后再开启;
在进入跳转函数之前,将用到的外设反向初始化。

4.FLASH擦除写入过程过程

		关中断			__disable_irq(); 解锁			HAL_FLASH_Unlock(); 计算页数		页擦除/写入		HAL_FLASHEx_Erase / HAL_FLASH_Program上锁			HAL_FLASH_Lock();开中断			__enable_irq();

5.Ymodem协议

YModem是一种文件传输的协议,每包数据可以达到1024字节。文件大于32K建议使用STX(1024)。字符	ASCII码16进制
SOH		0x01
STX		0x02
ACK		0x06
NAK		0x15
EOT		0x04
C		0x43

1).起始帧
SOH + 00 + FF + filename + filesize + NULL + CRCH + CRCL

起始帧是文件传输发送端发的第一条重要消息.
filename表示传输文件的文件名.
filesize表示需要传输文件的大小.
CRCH + CRCL 表示整条帧(去掉前三个字节)的CRC16校验.

2).数据帧格式
STX/SOH + [编号] + 编号的反码 + data[0] + data[1] + data[2] + … + CRCH + CRCL

SOH 表示有128个字节, 有的也只用SOH传输数据.
STX 表示有1024个字节.

CRCH + CRCL 表示整条帧(去掉前三个字节)的CRC16校验.
如果传输最后一条字节不足128个字节, 则用1A填充

3).结束帧的数据格式
SOH + 00 + FF + NULL + NULL + … + NULL + CRCH + CRCL

Ymodem协议解释来自:
https://blog.csdn.net/weixin_41294615/article/details/104652105

ST官方例程
https://www.st.com/content/st_com/zh/products/embedded-software/mcu-mpu-embedded-software/stm32-embedded-software/stm32cube-expansion-packages/x-cube-iap-usart.html

解读一下例程:
两个工程 IAP_Binary_Template、IAP_Main,IAP_Binary_Template是APP程序,IAP_Main是BOOT。

BOOT的主函数主要是,判断是进入升级还是直接跳入APP

int main(void)
{ HAL_Init();/* Configure the system clock to 32 MHz */SystemClock_Config();/* Initialize Key Button mounted on STM32L073Z-EVAL board */BSP_PB_Init(BUTTON_TAMPER, BUTTON_MODE_GPIO);/* Test if Key push-button on STM32L073Z-EVAL Board is pressed */if (BSP_PB_GetState(BUTTON_TAMPER) == GPIO_PIN_SET)/* 判断按键是否为按下 */{ /* Initialise Flash */FLASH_If_Init();/* Execute the IAP driver in order to reprogram the Flash */IAP_Init();/* 外设初始化 *//* Display main menu */Main_Menu ();/* 选择菜单 重要 */}/* Keep the user application running */else{/* Test if user code is programmed starting from address "APPLICATION_ADDRESS" */if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000){/* Jump to user application */JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);JumpToApplication = (pFunction) JumpAddress;/* Initialize user application's Stack Pointer */__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);JumpToApplication();}}while (1){}
}

6.使用SecureCRT工具进行Ymodem协议传输

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

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

相关文章

二叉树的性质、前中后序遍历【详细】

1. 树概念2.二叉树的概念1.2二叉树的性质 3.二叉树遍历3.2前序遍历3.2 中序遍历3.3 后序遍历 1. 树概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合&#xff0c;有二叉树&#xff0c;N叉树等等。 子树…

Node.js:实现遍历文件夹下所有文件

Node.js&#xff1a;实现遍历文件夹 代码如下 const fs require(fs) const path require(path)function traverseFolder(folderPath) {// 读取文件夹列表const files fs.readdirSync(folderPath)// 遍历文件夹列表files.forEach(function (fileName) {// 拼接当前文件路径…

安卓:实现复制粘贴功能

目录 一、介绍 &#xff08;一&#xff09;ClipboardManager介绍 1、ClipboardManager常用方法&#xff1a; 2、获取 ClipboardManager实例 &#xff08;二&#xff09;、ClipData介绍 1、创建ClipData对象&#xff1a; 2、获取ClipData的信息&#xff1a; 3、ClipData…

事务提交后,异步执行

背景&#xff1a; 有个业务是这样的&#xff0c;先执行导入操作&#xff0c;导入提交后再异步执行其他业务&#xff0c;数据依赖导入数据。 1. 主方法 Transactional(rollbackFor Exception.class)public void testA() {long begin System.currentTimeMillis();BrandInfo …

Linux使用mount挂载

authordaisy.skye的博客_CSDN博客-嵌入式,Qt,Linux领域博主 格式化分区 sudo mkfs -t ext4 /dev/mmcblk0p1 格式化分区 实际使用中推荐这个&#xff0c;它是 mkfs 命令的个变种&#xff0c;可以自动识别文件系统类型为 ext4&#xff0c;并使用 ext4 文件系统的默认参数来创建…

痞子衡嵌入式:借助i.MXRT10xx系列INIT_VTOR功能可以缩短程序热重启时间

大家好&#xff0c;我是痞子衡&#xff0c;是正经搞技术的痞子。今天痞子衡给大家分享的是借助i.MXRT10xx系列INIT_VTOR功能可以缩短程序热重启时间。 最近痞子衡写了篇文章 《i.MXRT从Serial NAND启动时间测量》&#xff0c;这篇文章详细测试了不同长度的 Non-XIP 程序在不同 …

uniapp使用空格占位符无效

uniapp文档&#xff1a; 错误写法&#xff1a; <text>筛 选</text> 正确写法&#xff1a; <text decode>{{ 筛 选 }}</text> //要加decode属性&#xff0c;且内容必须包裹在{{}}

Vue3 大屏数字滚动效果

父组件&#xff1a; <template> <div class"homePage"> <NumRoll v-for"(v, i) in numberList" :key"i" :number"v"></NumRoll> </div> </template> <script setup> import { onMounted, r…

C++ 多态性——虚函数

虚函数是动态绑定的基础。虚函数必须是非静态的成员函数。虚函数经过派生之后&#xff0c;在类族中就可以实现运行过程的多态。 根据类型兼容规则&#xff0c;可以使用派生类的对象代替基类的对象。如果基类类型的指针指向派生类对象&#xff0c;就可以通过这个指针来访问该对…

中级课程——XSS

文章目录 介绍挖掘思路分类反射型存储型dom类型 介绍 挖掘思路 注入点&#xff1a;各种输入框 测试代码&#xff08;poc&#xff09;&#xff1a;js语句 分类 反射型 存储型 dom类型

[JAVAee]网络通信基础

目录 IP地址 端口号 网络协议 五元组 TCP/IP五层模型 网络互连之间的目的就是为了相互通信,传输数据,是可以不同进程间的基于网络的数据传输. 而IP就可以确定网络通信的双方. IP地址 IP地址主要用于定位标识网络主机或其他网络设备的网络地址.(就像快递的收货地址一般…

《合成孔径雷达成像算法与实现》Figure3.5

clc clear all close all%参数设置 TBP 100; %时间带宽积 T 10e-6; %脉冲持续时间%参数计算 B TBP/T; %信号带宽 K B/T; …

python --windows获取启动文件夹路径/获取当前用户名/添加自启动文件

如何使用Python获取计算机用户名 一、Python自带的getpass模块可以用于获取用户输入的密码&#xff0c;但是它同样可以用来获取计算机用户名。 import getpassuser getpass.getuser() print("计算机用户名为&#xff1a;", user)二、使用os模块获取用户名 Python的…

[ubuntu]创建root权限的用户

一、创建新用户 1、创建新用户 sudo useradd -r -m -s /bin/bash 用户名 # -r&#xff1a;建立系统账号 -m&#xff1a;自动建立用户的登入目录 -s&#xff1a;指定用户登入后所使用的shell2、手动为用户设置密码 passwd 用户名 二、为用户增加root权限 1、添加写权限 ch…

【MySQL】sql字段约束

在MySQL中&#xff0c;我们需要存储的数据在特定的场景中需要不同的约束。当新插入的数据违背了该字段的约束字段&#xff0c;MySQL会直接禁止插入。 数据类型也是一种约束&#xff0c;但数据类型这个约束太过单一&#xff1b;比如我需要存储的是一个序号&#xff0c;那就不可…

ffmpeg SDL播放器--播放udp组播流

c调用ffmpeg api及SDL库播放播放udp组播流。 代码及工程见https://download.csdn.net/download/daqinzl/88168574 参考文档&#xff1a;https://blog.csdn.net/a53818742/article/details/109312740 开发工具&#xff1a;visual studio 2019 记得推送udp流&#xff0c;可采…

【JavaEE进阶】Spring创建与使用

文章目录 一. 创建 Spring 项目1.1 创建一个Maven项目1.2 添加Spring依赖1.4. 创建一个启动类 二. 将 Bean 对象存放至 Spring 容器中三. 从 Spring 容器中读取到 Bean1. 得到Spring对象2. 通过Spring 对象getBean方法获取到 Bean对象【DI操作】 一. 创建 Spring 项目 接下来使…

algebraic reconstruction technique(ART)

数值线性代数的Kaczmarz方法被Gordon&#xff0c;Bender&#xff0c;Herman引入至CT重建中&#xff0c;称为ART方法。 A x b Axb Axb A A A为 m n m\times n mn的稀疏矩阵。 A A A的元素 a i j a_{ij} aij​表示像素 j j j对射线 i i i投影的贡献。 A A A的行向量 a i T a…

【Fegin技术专题】「原生态」打开Fegin之RPC技术的开端,你会使用原生态的Fegin吗?(中)

你可以使用 Jersey 和 CXF 这些来写一个 Rest 或 SOAP 服务的java客服端。 你也可以直接使用 Apache HttpClient 来实现。但是 Feign 的目的是尽量的减少资源和代码来实现和 HTTP API 的连接。 *通过自定义的编码解码器以及错误处理&#xff0c;你可以编写任何基于文本的 HTT…

我开源的 c#+wpf 模仿网易云音乐播放器

MusicApp 介绍 gitee地址&#xff1a;https://gitee.com/liu_guo_feng/music-app 我开源的 c#wpf 模仿网易云音乐播放器 项目页面功能完成列表 首页(待完善) 每日推荐音乐 歌单详情 带播放列表 歌词页(待完善) 换肤功能(待完善) 系统托盘 … 预览 仅供学习使用 不作任何商业用…