STM32--IAP程序升级实验

1. STM32程序升级方法

1.1 ST-link / J-link下载

        将编译生成的hex文件使用ST-Link/J-Link工具直接下载进 Flash 即可。Keil中点击下载也能一键下载。下载后的代码会存放在Flash的起始地址0x0800 0000

简单补充一句,bin文件hex文件的区别:

  • bin文件不带地址信息,因此下载的时候需要指定下载地址。
  • hex文件自带地址信息,直接点击下载自己会找到要下载到的地址(默认0x0800 0000)。

ST-LINK/J-LINK方式支持在线调试

1.2 ISP(In System Programing) 

        我们常见的一键下载电路就是用的这种方式。这个是利用了 STM32 自带的 Bootloader 升级程序。可以通过USB转串口,再通过ISP软件导入程序

在用户参考手册中,可以看到下表,关于启动模式设置的。

ISP根据读取到的FLASH大小自动确定下载地址。

STM32启动模式

        ST公司在系统存储器中存放了BootLoader引导程序,通过BootLoader引导程序可完成自启动,并通过向量表跳转至用户APP程序。一般可通过USART1、USART3、CAN2、USB对Flash重新编程。系统BootLoader的起始地址0x1FFF F000,进入系统自带的BootLoader后可利用STM32CubeProgrammer更新程序

        不管通过何种方式,程序最后都是下载到主闪存存储器Flash里面的

可以这么理解:芯片出厂时,系统存储器中已经存储了一段程序,这段程序的功能是将串口1(固定的)收到的数据,放到主闪存存储器(Flash)中,从0x0800 0000地址处开始。

1.3 IAP(In Application Programing)

IAP 和 ISP 其实基本上是一样的,都是通过串口接收程序,存放到FLASH中的某段地址。

ISP 是由厂商已经提供好的,因此接口固定(串口1);

IAP可以自定义使用任何接口接收应用程序。因为这一点,用户可以用多种方式更新程序。

1.3.1 正常程序运行流程

正常情况下,程序从Flash启动时的流程如下:

1. 程序从Flash启动,根据中断向量表找到复位中断处理函数的地址。(0x0800 0004处是中断向量表的起始地址,也是中断向量表的起始,记录了复位中断处理函数的地址)。

2. 执行复位中断处理函数,初始化系统环境后跳转到main函数

3. 在main函数的死循环中运行,直到有中断发生

4. 中断发生时,跳转到中断向量表起始处,根据中断信号源跳找到相应的中断处理函数

5. 中断处理函数执行完后返回到main函数继续运行。

1.3.2 IAP时程序运行流程

引入IAP后的启动流程如下图所示。在Flash中存储了两套程序:

Bootloader程序:自举程序。负责接收数据(APP应用程序代码)并将其存储到Flash中。

APP应用程序:我们真正的应用程序。

  1. 程序从Flash启动,根据中断向量表找到复位中断处理函数的地址。
  2. 执行复位中断处理函数后,跳转到Bootloader的main函数。该函数检查并保存新的APP程序到Flash,然后跳转到第二套程序运行。
  3. 一旦进入新的APP程序,根据中断向量表找到复位中断处理函数,进入App程序的main函数运行。
  4. 为确保中断能正确跳转到APP程序的中断处理函数,需要在APP程序中修改中断向量表的偏移,确保中断发生时能正确执行APP程序的中断处理函数

ISPIAP
在系统存储器中存储了一套接收串口1数据的程序IAP是将Flash分成了两份,在第一份中存储了一套接收某个接口的程序
使用硬件BOOT引脚设置进行跳转使用软件(直接修改PC指针)进行跳转
仅能使用芯片厂商设置好的接口(串口1)用户自定义,理论上只要能接收数据的接口都可以用

2. STM32 Bootloader实现

bootloader基本概念

首先贴上参考文献,这位老哥开源了自己测试的代码,大家可以直接下载,此处做个补充完善

STM32深入系列02——BootLoader分析与实现_stm32 bootloader-CSDN博客文章浏览阅读3.3k次,点赞34次,收藏96次。stm32 bootloader功能分析与实现_stm32 bootloaderhttps://blog.csdn.net/weixin_46253745/article/details/135321134先说BootLoader的思想,对于新手来讲认识的编译后的程序就是.HEX文件,常见做法就是各种下载器或者usb转串口用ISP程序进行烧录,但是企业场景不可能每个设备挨个拿串口去传输,我要远程升级怎么办?

答案就是.BIN文件和BOOTLOADER自举思路。

在 默认方式下,我们的嵌入式程序是以连续二进制的方式烧录到 STM32 的可寻址 Flash 区域上 的。如果我们用的 Flash 容量大到可以存储两个或多个的完整程序,在保证每个程序完整的情 况下,上电后的程序通过修改 MSP 的方式,就可以保证一个单片机上有多个有功能差异的嵌 入式软件,这就是我们要讲解的 IAP 的设计思路。

通常实现 IAP 功 能时,即用户程序运行中作自身的更新操作,需要在设计固件程序时编写两个项目代码,第一个项目代码通过USB、USART等方式接收更新程序并执行更新,第二个项目代码执行用户真正的功能。

我们将第一个项目代码称之为 Bootloader程序,第二个项目代码称之为 APP程序,他们存放在 STM32F429 FLASH 的不同地址范围。

bootloader原理

        我们知道的复位方式有三种:上电复位,硬件复位和软件复位。当产生复位,并且离开复位状态后,CM4 内核做的第一件事就是读取下列两个 32 位整数的值:

(1)从地址 0x0000 0000 处取出堆栈指针 MSP 的初始值,该值就是栈顶地址。

(2)从地址 0x0000 0004 处取出程序计数器指针 PC 的初始值,该值指向复位后执行的第 一条指令。下面用示意图表示,如图 9.1.1 所示。

上述过程中,内核是从 0x0000 0000 和 0x0000 0004 两个的地址获取堆栈指针 SP 和程序计数器指针 PC。事实上,0x0000 0000 和 0x0000 0004 两个的地址可以被重映射到其他的地址空间。

例如:我们将 0x0800 0000 映射到 0x0000 0000,即从内部 FLASH 启动,那么内核会从地址 0x0800 0000 处取出堆栈指针 MSP 的初始值,从地址 0x0800 0004 处取出程序计数器指针 PC 的初始值。CPU 会从 PC 寄存器指向的地址空间取出的第 1 条指令开始执行程序,就是开始执行复位中断服务程序 Reset_Handler。 将 0x0000 0000 和 0x0000 0004 两个的地址重映射到其他地址空间,就是启动模式选择。

理论上所有程序都是从虚拟地址0x0000 0000开始启动!!!所谓不同的启动模式就是将物理地址0x08000000/0x20000000/0x1FFFF000映射到了虚拟地址0x0000 0000!!!从而MSP取值和CP取值的地址不同!!

flash、sram等存储空间都被映射到4GB的虚拟地址上。

测试过程的碎碎念

注意,划分Flash的时候,注意App程序起始地址,根据芯片不同起始地址倍数关系也不同

STM32F1:地址必须是4的倍数,因为每次写入只能写入32位数据,即4个字节。
STM32F4:地址可以从任意地址开始,因为每次写入可以写入8位数据,每个地址就是1个字节。
STM32L4:地址必须是8的倍数,因为每次写入只能写入64位数据,即8个字节。

Stm32的flash都是从0x0800000开始的,结束地址看片子的flash大小

Stm32的sram都是从0x2000000开始的,结束地址看片子的sram大小

 

理论上我们只需要确保APP起始地址在Bootloader之后,并且偏移量为0X200的倍数即可(相关知识,请参考:NVIC的向量表偏移寄存器设置问题(已解决)-OpenEdv-开源电子网)

检查栈顶地址是否合法.0x20000000是sram的起始地址,也是程序的栈顶地址;

appxaddr存放的是用户程序Flash的首地址,(*(volatile u32*)appxaddr)的意思是取用户程序首地址里面的数据,这个数据就是用户代码的堆栈地址,堆栈地址指向RAM,而RAM的起始地址是0x20000000。

在保存了一个完整的 APP 到了对应的位置后,我们需要对栈顶进行检查操作,初步检查 程序设置正确再进行跳转。我们以 FlashAPP 为例,用 bin 文件查看工具(A 盘→6,软件资料 →1,软件→winhex),可以看到 bin 的内容默认为小端结构

中断向量表一个中断占4个字节,正好是一个指针的大小。

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

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

相关文章

ARM day1练习 求1~100内的和

题目要求:用ARM汇编语言实现1~100之间之和(5050 0x13BA) .text 声明以下内容是文本段的内容 .global _start .global声明_start标签是一个全局标签_start:mov r1,#0x0 r1 summov r2,#0x1 r2 ifun: 加法函数cmp r2,#100 r2中的值和100作比较add…

Matlab基础篇:数据输入输出

前言 数据输入和输出是 Matlab 数据分析和处理的核心部分。良好的数据输入输出能够提高工作效率,并确保数据处理的准确性。本文将详细介绍 Matlab 数据输入输出的各种方法,包括导入和导出数据、数据处理和数据可视化。 一、导入数据 Matlab 提供了多种方…

Go自定义数据的序列化流程

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

【计算机毕业设计】167校园失物招领微信小程序

🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板&#xff…

导出 S 参数扫描结果供 INTERCONNECT 使用

导出 S 参数扫描结果供 INTERCONNECT 使用 正文正文 有时候,对于 FDTD 无法直接进行仿真的大型仿真链路,我们需要使用 FDTD 针对单个小的模块进行仿真,再将得到的 S 参数结果导入到 INTERCONNECT 中使用,最终完成整个链路的仿真。通常完成 S 参数扫描后其状态如下图所示:…

QT拖放事件之八:通过全局剪切板中的接口QClipboard::mimeData()来获取MIME类型数据

1、演示效果 首先向剪切板写入数据,然后点击paste按钮进行从全局剪切板中 获取 MIME数据。。。 2、核心代码 void Widget::on_pasteBtn_clicked() {const QClipboard* clipBoard = QGuiApplication::clipboard()

非强化学习的对齐方法

在文章《LLM对齐“3H原则”》和《深入理解RLHF技术》中,我们介绍了大语言模型与人类对齐的“3H原则”,以及基于人类反馈的强化学习方法(RLHF),本文将继续介绍另外一种非强化学习的对齐方法:直接偏好优化&am…

kafka--发布-订阅消息系统

1. Kafka概述 1. kafka是什么 kafka是分布式的、高并发的、基于发布/订阅模式的消息队列软件系统。 kafka中的重要组件 Producer:消息生产者,发布消息到Kafka集群的终端或服务Consume:消费者,从Kafka集群中消费消息的终端或服…

安达发|生产制造业怎么做好一体化生产计划排产?

在生产制造业中,一体化生产计划排产是确保生产效率和产品质量的关键。要实现这一目标,企业需要采用高级排产软件(APS)来优化生产流程。以下是如何利用APS软件做好一体化生产计划排产的详细步骤和建议: 1. 需求分析与数…

1.2 DataX 数据同步工具详细教程

DataX 是阿里巴巴开源的一款高效的数据同步工具,旨在实现多种异构数据源之间的高效数据同步。以下是对 DataX 的详细介绍: 架构 DataX 的架构主要包括以下几个核心组件: DataX Core:负责任务调度、插件加载、日志管理等核心功能…

SSM爱心捐赠物资维护系统-计算机毕业设计源码09536

摘要 随着信息技术的快速发展,计算机应用已经进入成千上万的家庭。随着物资数量的增加,物资库存管理也存在许多问题。物资数据的处理量正在迅速增加,原来的手工管理模式不适合这种形式。使用计算机可以完成数据收集、处理和分析,减…

从0搭建一个vue项目,不使用脚手架从html到vue

前言 从最开始学习web网页开始,搭建一个网页只需要创建一个html文件对其进行编写dom标签语言即可;后来分离了html,css和js,搭建一个网页开始需要文件夹,文件夹包含了这3类文件以及静态文件,图片&#xff0c…

常见的跨域场景

我们在解决一个问题的时候应该先去了解这个问题是如何产生的,为什么会有跨域的存在呢?其实,最终的罪魁祸首都是浏览器的同源策略,浏览器的同源策略限制我们只能在相同的协议、IP地址、端口号相同,如果有任何一个不通&a…

【学习笔记】CSS

CSS 1、 基础篇 1.1、选择器 1.2、长度单位 1.3、CSS2 常用属性 1.4、盒模型 1.5、浮动 1.6、定位 position2、 CSS3 2.1、新增长度单位 2.2、新增颜色表示 2.3、新增选择器 2.4、新增盒子属性 2.5、新增背景属性 …

DDP(Differential Dynamic Programming)算法举例

DDP(Differential Dynamic Programming)算法 基本原理 DDP(Differential Dynamic Programming)是一种用于求解非线性最优控制问题的递归算法。它基于动态规划的思想,通过线性化系统的动力学方程和二次近似代价函数,递归地优化控制策略。DDP的核心在于利用局部二次近似来…

04 Shell编程之正则表达式与文本处理器

目录 4.1 正则表达式 4.1.1 正则表达式概述 1. 正则表达式的定义 2. 正则表达式用途 4.1.2 基础正则表达式 1. 基础正则表达式示例 1. 查找特点字符 2. 利用中括号"[]"来查找集合字符 3. 查找行首"^"与行尾字符"$" 4. 查找任意一个字符".&…

强化学习-RLHF-PPO入门

一、定义 强化学习微调分类RM模型 数据集格式训练流程Reward 模型训练流程(分类模型,积极为1,消极为0) AutoModelForSequenceClassificationReward 模型训练案例PPO模型训练流程PPO模型训练案例 二、实现 强化学习微调分类 RLHF:基于人类反馈对语言模型…

实战案例:如何用ChatGPT生成适合不同领域的高质量文章

随着人工智能技术的飞速发展,生成高质量文章已经不再是难题。特别是OpenAI开发的ChatGPT,更是为写作工作带来了极大的便利。那么,如何用ChatGPT生成适合不同领域的高质量文章呢?本文将通过实战案例,为大家详细讲解这一…

JavaScript的学习之事件的简介

目录 一、事件是什么 二、如何处理事件 一、事件是什么 定义:事件就是浏览器和用户之间的交互行为。 例如:点击按钮、鼠标移动、关闭窗口等。 二、如何处理事件 我们可以在对应的事件属性中设置一些JS行为,当事件触发的时候会将这些代码执行…

C++11基础

一、C11简介 在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1),使得C03这个名字已经取代了 C98称为C11之前的最新C标准名称。不过由于C03(TC1)主要是对C98标准中的漏洞 进行修复,语言的核心部分则没有改动,因此人们习惯性的把两个标准合…