当前位置: 首页 > news >正文

STM32补充——IAP

0 前置知识:

FLASH相关内容:前往STM32补充——FLASH

STM32三种烧录方式(看看就行):

1.ISP:In System Programming(在系统编程)
执行芯片厂商的 Bootloader 程序进入 ISP 模式,进入ISP 模式后,用户可选择官方提供的烧录通信接口(如:串口),并配合ISP 编程工具(如:FlyMcu)对闪存进行烧录。

2.ICP:In Circuit Programing(在线编程)
使用IDE并通过JTAG/SWD接口对闪存进行烧录。

3.IAP:In Application Programming(在应用编程)
使用用户的应用程序(也称为:Bootloader程序)对闪存进行烧录。该应用程序需要通过一种通信接口(如:IO口\USB\CAN\UART\I2C\SPI等)对闪存进行烧录(即把APP程序烧录到闪存)。IAP 通常被开发者用作远程升级的手段。


1.IAP原理介绍

1.1 程序正常运行过程:

①跳转到复位中断服务函数
②跳转到main函数
③发生中断时,会强制跳转到中断向量表
④根据中断源,跳转到对应的中断服务函数
⑤执行中断服务程序后,回到main函数原来的位置执行  

 

1.2 加入IAP后程序运行过程

①执行复位中断服务函数后,跳转到IAP程序main函数
②执行IAP过程,跳转到APP中断向量表
③跳转到APP的main函数
④发生中断时,会强制跳转到地址为0x08000000的中断向量表
⑤根据设置的中断向量表偏移量,跳转到APP对应的中断服务函数
⑥执行中断服务程序后,回到main函数原来的位置执行 


2.APP的生成步骤

  1. 设置APP程序的起始地址和存储空间大小
  2. 设置中断向量表偏移量(设置SCB->VTOR的值即可)
  3. 设置MDK编译后运行fromelf.exe,生成.bin文件(在User选项卡,设置编译后调用fromelf.exe,根据.axf文件生成.bin文件,用于IAP更新)

注意:APP程序的起始地址可在Keil上直接设置,但中断向量表偏移量需要另外手动设置


 

2.1 设置APP程序的起始地址和存储空间大小

设置APP起始地址要注意的点:
1,APP要在BootLoader后面
2,内存不能出现重叠
3,偏移量是0x200的倍数


FLASH_APP:


SRAM_APP:


①Bootloader程序运行预留4KB SRAM
②存放APP程序预留48KB SRAM
③APP程序运行预留12KB SRAM
 

2.2 设置中断向量表偏移量 

APP存放在FLASH中的设置方法:

SCB->VTOR = FLASH_BASE | 0x10000;

 

APP存放在SRAM中的设置方法:

SCB->VTOR = SRAM_BASE | 0x1000;

2.3 设置MDK编译后运行fromelf.exe,生成.bin文件

D:\MDK5.36\ARM\ARMCC\bin\fromelf  --bin -o ..\..\Output\@L.bin  ..\..\Output\%L


3. 代码

iap模块:

iapfun jump2app;
uint16_t g_iapbuf[1024];       /* 2K字节缓存 *//*** @brief       IAP写入APP BIN* @param       appxaddr : 应用程序的起始地址* @param       appbuf   : 应用程序CODE* @param       appsize  : 应用程序大小(字节)* @retval      无*/
void iap_write_appbin(uint32_t appxaddr, uint8_t *appbuf, uint32_t appsize)
{uint16_t t;uint16_t i = 0;uint16_t temp;uint32_t fwaddr = appxaddr; /* 当前写入的地址 */uint8_t *dfu = appbuf;for (t = 0; t < appsize; t += 2){temp = (uint16_t)dfu[1] << 8;temp |= (uint16_t)dfu[0];dfu += 2;               /* 偏移2个字节(FLASH每次写入两个字节) */g_iapbuf[i++] = temp;if (i == 1024){i = 0;stmflash_write(fwaddr, g_iapbuf, 1024);fwaddr += 2048;     /* 偏移2048  16 = 2 * 8  所以要乘以2 */}}if (i){stmflash_write(fwaddr, g_iapbuf, i);  /* 将最后的一些内容字节写进去 */}
}/*** @brief       跳转到应用程序段(执行APP)* @param       appxaddr : 应用程序的起始地址* @retval      无*/
void iap_load_app(uint32_t appxaddr)
{if (((*(volatile  uint32_t *)appxaddr) & 0x2FFE0000) == 0x20000000)     /* 检查栈顶地址是否合法.可以放在内部SRAM共64KB(0x20000000) */{/* 用户代码区第二个字为程序开始地址(复位地址) */jump2app = (iapfun) * (volatile uint32_t *)(appxaddr + 4);/* 初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址) */sys_msr_msp(*(volatile uint32_t *)appxaddr);/* 跳转到APP */jump2app();}
}

 

main函数:

int main(void)
{uint8_t t;uint8_t key;uint32_t oldcount = 0;      /* 老的串口接收数据值 */uint32_t applenth = 0;      /* 接收到的app代码长度 */uint8_t clearflag = 0;HAL_Init();                                 /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟, 72Mhz */delay_init(72);                             /* 延时初始化 */usart_init(115200);                         /* 串口初始化为115200 */led_init();                                 /* 初始化LED */lcd_init();                                 /* 初始化LCD */key_init();                                 /* 初始化按键 */lcd_show_string(30,  50, 200, 16, 16, "STM32", RED);lcd_show_string(30,  70, 200, 16, 16, "IAP TEST", RED);lcd_show_string(30,  90, 200, 16, 16, "ATOM@ALIENTEK", RED);lcd_show_string(30, 110, 200, 16, 16, "KEY_UP: Copy APP2FLASH!", RED);lcd_show_string(30, 130, 200, 16, 16, "KEY1: Run FLASH APP", RED);lcd_show_string(30, 150, 200, 16, 16, "KEY0: Run SRAM APP", RED);while (1){if (g_usart_rx_cnt){if (oldcount == g_usart_rx_cnt)   /* 新周期内,没有收到任何数据,认为本次数据接收完成 */{applenth = g_usart_rx_cnt;oldcount = 0;g_usart_rx_cnt = 0;printf("用户程序接收完成!\r\n");printf("代码长度:%dBytes\r\n", applenth);}else oldcount = g_usart_rx_cnt;}t++;delay_ms(100);if (t == 3){LED0_TOGGLE();t = 0;if (clearflag){clearflag--;if (clearflag == 0){lcd_fill(30, 190, 240, 210 + 16, WHITE);    /* 清除显示 */}}}key = key_scan(0);if (key == WKUP_PRES)   /* WKUP按下,更新固件到FLASH */{if (applenth){printf("开始更新固件...\r\n");lcd_show_string(30, 190, 200, 16, 16, "Copying APP2FLASH...", BLUE);if (((*(volatile uint32_t *)(0X20001000 + 4)) & 0xFF000000) == 0x08000000)  /* 判断是否为0X08XXXXXX */{iap_write_appbin(FLASH_APP1_ADDR, g_usart_rx_buf, applenth);            /* 更新FLASH代码 */lcd_show_string(30, 190, 200, 16, 16, "Copy APP Successed!!", BLUE);printf("固件更新完成!\r\n");}else{lcd_show_string(30, 190, 200, 16, 16, "Illegal FLASH APP!  ", BLUE);printf("非FLASH应用程序!\r\n");}}else{printf("没有可以更新的固件!\r\n");lcd_show_string(30, 190, 200, 16, 16, "No APP!", BLUE);}clearflag = 7; /* 标志更新了显示,并且设置7*300ms后清除显示 */}if (key == KEY1_PRES)   /* KEY1按键按下, 运行FLASH APP代码 */{if (((*(volatile uint32_t *)(FLASH_APP1_ADDR + 4)) & 0xFF000000) == 0x08000000) /* 判断FLASH里面是否有APP,有的话执行 */{printf("开始执行FLASH用户代码!!\r\n\r\n");delay_ms(10);iap_load_app(FLASH_APP1_ADDR);/* 执行FLASH APP代码 */}else{printf("没有可以运行的固件!\r\n");lcd_show_string(30, 190, 200, 16, 16, "No APP!", BLUE);}clearflag = 7; /* 标志更新了显示,并且设置7*300ms后清除显示 */}if (key == KEY0_PRES)   /* KEY0按下 */{printf("开始执行SRAM用户代码!!\r\n\r\n");delay_ms(10);if (((*(volatile uint32_t *)(0x20001000 + 4)) & 0xFF000000) == 0x20000000)   /* 判断是否为0X20XXXXXX */{iap_load_app(0x20001000);   /* SRAM地址 */}else{printf("非SRAM应用程序,无法执行!\r\n");lcd_show_string(30, 190, 200, 16, 16, "Illegal SRAM APP!", BLUE);}clearflag = 7; /* 标志更新了显示,并且设置7*300ms后清除显示 */}}
}

 

相关文章:

STM32补充——IAP

0 前置知识&#xff1a; FLASH相关内容&#xff1a;前往STM32补充——FLASH STM32三种烧录方式&#xff08;看看就行&#xff09;&#xff1a; 1.ISP&#xff1a;In System Programming&#xff08;在系统编程&#xff09; 执行芯片厂商的 Bootloader 程序进入 ISP 模式&…...

Jetson Xavier NX (ARM) 使用 PyTorch 安装 Open3D-ML 指南

由于 Jetson 为 ARM64 (aarch64) 的系统架构&#xff0c;所以不能用 pip install 直接安装&#xff0c;需要通过源码编译。 升级系统 JetPack 由于 Open3D-ML 目前只支持 CUDA 10.0 以及 CUDA 11.*&#xff0c;并且 JetPack 的 CUDA 开发环境只有10.2、11.4以及12.2&#xff0…...

【C++高并发服务器WebServer】-1:Linux中父子进程fork创建及关系、GDB多进程调试

本文目录 一、进程创建二、GDB多进程调试 一、进程创建 在Linux中输入man 2 fork可以查看man文档中的fork的相关函数信息。 fork的作用就是创建一个子进程。 通过fork我们可以知道&#xff0c;创建子进程的时候&#xff0c;复制父进程的信息。 我们看看翻译的man文档信息&am…...

C语言数组详解:从基础到进阶的全面解析

在C语言中&#xff0c;数组是一种基本的数据结构&#xff0c;用于存储多个相同类型的数据。数组的引入使得C语言能够高效地存储和操作大量数据。在任何一个C语言程序中&#xff0c;数组都发挥着极其重要的作用。无论是在算法实现、数据存储、还是在复杂程序的设计中&#xff0c…...

docker的前世今生

docker来自哪里&#xff1f; 从我们运维部署的历史来看&#xff0c;宿主机从最初的物理机到虚拟机&#xff0c;再到docker&#xff0c;一步步演进到现在。技术演进其实是为了解决当前技术的痛点&#xff0c;那我们来看看有哪些痛点以及如何克服痛点的。 物理机 一般来说&…...

python实现施瓦茨-克里斯托费尔【全网首个】根据用户输入推测函数

上代码&#xff1a; from sympy import symbols, integrate, simplify from sympy.plotting import plotn int(input("n:")) if n < 2:print("Error: Must n > 2") i 0 a [] aef [] A [] x, y symbols(x y) z, w symbols(z w)while i < n…...

c语言中的数组(上)

数组的概念 数组是⼀组相同类型元素的集合&#xff1b; 数组中存放的是1个或者多个数据&#xff0c;但是数组元素个数不能为0。 数组中存放的多个数据&#xff0c;类型是相同的。 数组分为⼀维数组和多维数组&#xff0c;多维数组⼀般⽐较多⻅的是⼆维数组。 数组创建 在C语言…...

Unity3D仿星露谷物语开发25之创建时钟界面

1、目标 在时钟界面显示当前时钟信息&#xff0c;同时设置特殊按钮可以快速推进时间用于测试。 2、创建GameClock.cs脚本 在Assets -> Scripts -> TimeSystem目录下创建GameClock.cs脚本。 代码如下&#xff1a; using System.Collections; using System.Collections…...

数据结构测试题1

一、选择题: 1&#xff0e;若长度为n的钱性表采用顺序存储结构&#xff0c;删除它的第i数据元素之前&#xff0c;需要先依次向前移动( )个数据元素。( C ) A .n-i B.ni C.n-i-1 D.n-i1 2.在单链表中&#xff0c;已知q指的结点是p指的结点的直接前驱结点&am…...

android wifi AsyncChannel(WifiManager和WifiP2pManager)

AynscChannel的讲解 [Android]AsyncChannel介绍-CSDN博客 WifiP2pManager里的channel的使用理解 WifiP2pManager.java public void createGroup(Channel c, ActionListener listener) {checkChannel(c);c.mAsyncChannel.sendMessage(CREATE_GROUP, WifiP2pGroup.NETWORK_ID_PE…...

【Image Captioning】DynRefer

DynRefer是由中国科学院大学于2024年提出的用于1种用于区域级多模态任务的模型。DynRefer 通过模拟人类视觉认知过程&#xff0c;显著提升了区域级多模态识别能力。通过引入人眼的动态分辨率机制&#xff0c; 能够以同时完成区域识别、区域属性检测和区域字幕生成任务。 文章链…...

Midjourney基础-常用修饰词+权重的用法大全

用好修饰词很关键 Midjourney要用除了掌握好提示词的写法&#xff0c;按照上一篇《做Midjourney最好图文教程-提示词公式以及高级参数讲解》画面主体 场景氛围 主体行为 构图方式 艺术风格 图像质量。 要画出有质感的内容我们必须要掌握好“修饰词”&#xff0c;这些修饰…...

没有屋檐的房子-023粪堆旁边的舞蹈

爱美是天性&#xff0c;贫苦的农村人也一样&#xff0c;贫苦的时代也一样。 本世纪&#xff0c;广场舞在华夏大地遍地开花&#xff0c;甚至都传到了外面。但是广场舞这种舞蹈形式并不是互联网时代的特产&#xff0c;也不是电声设备日益高级和普及时代的特产&#xff0c;更不是大…...

基于Docker的Kafka分布式集群

目录 1. 说明 2. 服务器规划 3. docker-compose文件 kafka{i}.yaml kafka-ui.yaml 4. kafka-ui配置集群监控 5. 参数表 6. 测试脚本 生产者-异步生产: AsyncKafkaProducer1.py 消费者-异步消费: AsyncKafkaConsumer1.py 7. 参考 1. 说明 创建一个本地开发环境所需的k…...

【博客之星】年度总结:在云影与墨香中探寻成长的足迹

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、年度回顾 1、创作历程 2、个人成长 3、个人生活与博客事业 二、技术总结 1、赛道选择 2、技术工具 3、实战项目 三、前景与展望 1、云原生未来…...

SpringBoot的Swagger配置

一、Swagger配置 1.添加依赖 <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>3.0.2</version> </dependency> 2.修改WebMvcConfig Slf4j Configurat…...

machine learning knn算法之使用KNN对鸢尾花数据集进行分类

通过导入必要的scikit-learn导入必要的库&#xff0c;加载给定的数据&#xff0c;划分测试集和训练集之后训练预测和评估即可 具体代码如下&#xff1a; import numpy as np from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split f…...

C语言练习(16)

猴子吃桃问题。猴子第一天摘下若干个桃子&#xff0c;当即吃了一半&#xff0c;还不过瘾&#xff0c;又多吃了一个。第二天早上又将剩下的桃子吃掉一半&#xff0c;又多吃了一个。以后每天早上都吃了前一天剩下的一半加一个。到第10天早上想再吃时&#xff0c;见只剩一个桃子了…...

SOAFEE 技术研讨会:汽车软件定义与自动驾驶技术探讨

在本次技术研讨会上&#xff0c;来自汽车与科技领域的专家们围绕汽车软件定义及自动驾驶技术展开了深入交流与探讨。从 SOAFEE 蓝图计划的创新性理念&#xff0c;到 Autoware 开源项目及 Open AD Kit 在实际应用中的探索&#xff0c;再到 Edge Workload Abstraction and Orches…...

R语言学习笔记之开发环境配置

一、概要 整个安装过程及遇到的问题记录 操作步骤备注&#xff08;包含遇到的问题&#xff09;1下载安装R语言2下载安装RStudio3离线安装pacman提示需要安装Rtools4安装Rtoolspacman、tidyfst均离线安装完成5加载tidyfst报错 提示需要安装依赖&#xff0c;试错逐步下载并安装…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录&#xff0c;不允许匿名访问&#xff0c;kefu只能访问/data/kefu目录&#xff0c;不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会

在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...

pycharm 设置环境出错

pycharm 设置环境出错 pycharm 新建项目&#xff0c;设置虚拟环境&#xff0c;出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...

Unity中的transform.up

2025年6月8日&#xff0c;周日下午 在Unity中&#xff0c;transform.up是Transform组件的一个属性&#xff0c;表示游戏对象在世界空间中的“上”方向&#xff08;Y轴正方向&#xff09;&#xff0c;且会随对象旋转动态变化。以下是关键点解析&#xff1a; 基本定义 transfor…...

加密通信 + 行为分析:运营商行业安全防御体系重构

在数字经济蓬勃发展的时代&#xff0c;运营商作为信息通信网络的核心枢纽&#xff0c;承载着海量用户数据与关键业务传输&#xff0c;其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级&#xff0c;传统安全防护体系逐渐暴露出局限性&a…...

Tauri2学习笔记

教程地址&#xff1a;https://www.bilibili.com/video/BV1Ca411N7mF?spm_id_from333.788.player.switch&vd_source707ec8983cc32e6e065d5496a7f79ee6 官方指引&#xff1a;https://tauri.app/zh-cn/start/ 目前Tauri2的教程视频不多&#xff0c;我按照Tauri1的教程来学习&…...

Axure Rp 11 安装、汉化、授权

Axure Rp 11 安装、汉化、授权 1、前言2、汉化2.1、汉化文件下载2.2、windows汉化流程2.3、 macOs汉化流程 3、授权 1、前言 Axure Rp 11官方下载链接&#xff1a;https://www.axure.com/downloadthanks 2、汉化 2.1、汉化文件下载 链接: https://pan.baidu.com/s/18Clf…...