【固件升级】中断向量表(一)

stm32F1 SCB->VTOR开机默认是0,如何理解? 1.使用stm32cubemx生成新的f1工程,SystemInit函数中默认没有设置SCB->VTOR,则SCB->VTOR默认为0,程序正常运行。 2.在设计IAP的时候,为社么在app程序中需要设置SCB->VTOR,而bootloader中不需要? 3.程序的SCB->VTOR = 0x0800 0000 | offset; 4.那么对于bootloader来说,只是offset = 0而已,为什么连0x0800 0000都可以不设了呢? 5.想请教各位大佬,这个应该怎么理解 阅读详情
AI摘要

本文详细解析了STM32微控制器的中断向量表工作原理,包括正常向量表与升级向量表的区别,APP程序起始地址设置方法,以及如何设置中断向量表偏移等关键技术细节。

使用STM32举例说明:

1. 正常向量表

STM32F1 的内部闪存(FLASH)地址起始于 0x08000000,一般情况下,程序文件就从此地址开始写入
STM32F1 是基于 Cortex-M3 内核的微控制器,其内部通过一张“中断向量表”来响应中断
程序启动后,将首先从“中断向量表”取出 复位中断向量 执行 复位中断程序 完成启动
“中断向量表”的起始地址是 0x08000004
当中断来临,STM32F1 的内部硬件机制亦会自动将 PC 指针定位到“中断向量表”处
并根据中断源取出对应的中断向量执行中断服务程序

  1. STM32F1 在复位后,先从 0X08000004 地址取出复位中断向量的地址,跳转到复位中断服务程序
  2. 在复位中断服务程序执行完之后,会跳转到我们的 main 函数
  3. (见下代码)
  4. 而我们的 main 函数一般都是一个死循环
  5. 在 main 函数执行过程中,如果收到中断请求(发生重中断)此时 STM32F1 强制将 PC 指针指回中断向量表处
  6. 根据中断源进入相应的中断服务程序
  7. 在执行完中断服务程序以后,程序再次返回 main 函数执行
  • 从下面可以清晰的看到是从复位中断函数跳转到主函数
; Reset handler
Reset_Handler   PROC                          ; 定义处理器复位中断服务程序
                EXPORT  Reset_Handler           ; 导出此复位处理函数,使其在链接器脚本和其他文件中可见
                [WEAK]                        ; 标记为弱符号,允许其他地方重定义或覆盖此符号
                IMPORT  __main                 ; 引入主函数__main的声明,以便调用
                IMPORT  SystemInit             ; 引入系统初始化函数SystemInit的声明
                LDR     R0, =SystemInit        ; 加载SystemInit函数的地址到寄存器R0
                BLX     R0                     ; 调用SystemInit函数进行系统初始化,BLX指令同时将状态寄存器切换到Thumb状态
                LDR     R0, =__main            ; 加载主函数__main的地址到寄存器R0
                BX      R0                     ; 调用主函数__main开始执行应用程序,BX指令将状态寄存器切换到ARM状态
                ENDP                           ; 结束过程

在这里插入图片描述

2. 升级向量表

  1. STM32F1 复位后,还是从 0X08000004 地址取出复位中断向量的地址,并跳转到复位中断服务程序
  2. 在运行完复位中断服务程序之后跳转到 IAP 的 main 函数
  3. 在执行完 IAP 以后
  4. (即将新的 APP 代码写入 STM32F1灰底部分。新APP的复位中断向量起始地址为 0X08000004+N+M)
  5. 跳转至新写入程序的复位向量表
  6. 取出新APP的复位中断向量的地址
  7. 并跳转执行新程序的复位中断服务程序
  8. 随后跳转至新程序的 main 函数
  9. main 函数为一个死循环
  10. 注意到此时 STM32F1 的 FLASH,在不同位置上,共有两个中断向量表
  11. 在 main 函数执行过程中,
  12. 如果 CPU 得到一个中断请求
  13. PC 指针仍强制跳转到地址0X08000004 中断向量表处,而不是新APP的中断向量表
  14. 程序再根据我们设置的中断向量表偏移量,跳转到对应中断源新的中断服务程序中
  15. 在执行完中断服务程序后,程序返回 main 函数继续运行

在这里插入图片描述

  • 新程序必须在 IAP 程序之后的某个偏移量为 x 的地址开始
  • 必须将新程序的中断向量表相应的移动,移动的偏移量为 x
  • 并且偏移量为 0X200的倍数即可

3. .APP 程序起始地址设置方法

在这里插入图片描述
默认的条件下,图中 IROM1 的起始地址(Start)一般为 0X08000000,大小(Size)为 0X80000,
即从 0X08000000 开始的 512K 空间为我们的程序存储区。
而图中,我们设置起始地址(Start)为 0X08010000,即偏移量为 0X10000(64K 字节),
因而,留给 APP 用的 FLASH 空间(Size)只有 0X80000-0X10000=0X70000(448K 字节)大小了。
设置好 Start 和 Szie,就完成 APP 程序的起始地址设置。
理论上我们只需要确保 APP 起始地址在 Bootloader之后,并且偏移量为 0X200
的倍数即可(相关知识,请参考:http://www.openedv.com/posts/list/392.htm)。这里我们选择 64K
(0X10000)字节,留了一些余量,方便 Bootloader 以后的升级修改

4. 中断向量表设置偏移

/**
  * @brief  Setup the microcontroller system                  // 设置微控制器系统
  *         Initialize the Embedded Flash Interface, the PLL // 初始化嵌入式闪存接口和PLL
  *         and update the SystemCoreClock variable.         // 更新SystemCoreClock变量
  * @note   This function should be used only after reset.   // 注意: 此函数仅应在复位后使用
  * @param  None                                             // 没有参数
  * @retval None                                             // 没有返回值
  */
void SystemInit (void)
{
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG) // 如果是STM32F1系列中的某些型号
  #ifdef DATA_IN_ExtSRAM // 如果数据存储在外部SRAM中
    SystemInit_ExtMemCtl(); // 初始化外部内存控制
  #endif /* DATA_IN_ExtSRAM */
#endif 

  /* Configure the Vector Table location -------------------------------------*/ // 配置向量表位置
#if defined(USER_VECT_TAB_ADDRESS) // 如果用户自定义了向量表地址
  SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; // 设置SCB的VTOR寄存器以重定位向量表到内部SRAM
#endif /* USER_VECT_TAB_ADDRESS */
}

系统启动的时候,会首先调用 SystemInit 函数初始化时钟系统
SystemInit 还完成了中断向量表的设置,我们可以打开 SystemInit 函数
看看函数体的结尾处

#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;
/* Vector Table Relocation in Internal SRAM. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; 
/* Vector Table Relocation in Internal FLASH. */
#endif

VTOR 寄 存 器 存 放 的 是 中 断 向 量 表 的 起 始 地 址
默 认 的 情 况
VECT_TAB_SRAM 是没有定义,
所以执行
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET
对于 FLASH APP,
我们设置为 FLASH_BASE+偏移量 0x10000,
所以我们可以在 SystemInit 函数里面修改 SCB->VTOR 的值
当然为了尽可能不修改系统级别文件,
我们可以也可以在 FLASH APP 的 main 函数最开头处添加如下代码
实现中断向量表的起始地址的重设

SCB->VTOR = FLASH_BASE | 0x10000;

以上是 FLASH APP 的情况,当使用 SRAM APP 的时候,我们设置起始地址为:
SRAM_BASE+0x1000,同样的方法,
我们在 SRAM APP 的 main 函数最开始处,添加下面代码:

SCB->VTOR = SRAM_BASE | 0x1000;
  • 第二种
    将中断向量表移动的方法是在程序中加入函数
    void NVIC_SetVectorTable(u32 NVIC_VectTab, u32 Offset);
    其中参数NVIC_VectTab为中断向量表起始位置,而参数Offset则为地址偏移量,
    如将中断向量表移至0x8002000处,则应调用该函数如下:
    void NVIC_SetVectorTable(0x8000000, 0x2000);
    同时有必要提醒
    此函数只会修改STM32程序中用于存储中断向量的结构体变量,
    而不会实质地改变中断向量表在闪存中的物理位置

在这里插入图片描述
在这里插入图片描述

STM32MP157A学习笔记 1、寄存器 1.1 SCR寄存器: SystemInit()函数操作SCB->VTOR重定位中断向量表,在STM32MP157参考手册中未找到相关寄存器。通过百度得知,这个寄存器定义需要参考《ARM+Cortex-M3与Cortex-M4权威指南》。通过查找该手册在“”4.6章节系统控制块”找到该寄存器描述信息。7.9.3章节 向量表偏移寄存器(VTOR)在不同版本的Cortex-M3和Cortex-M4有些区别但寄存器地址都为0xE000ED0C。 2、启动文件 startup_stm32mp15x 阅读详情

相关推荐

关于STM32的NVIC设置问题(转载、自己见解)

1、SCB->VTOR设置问题(转载):对程序:void MY_NVIC_SetVectorTable(u32 NVIC_VectTab, u32 Offset){SCB->VTOR = NVIC_VectTab|(Offset & (u32)0x1FFFFF80);//中断向量在RAM中0x20000000,即VTOR第29位为1;中断向量在Flash中0x08000000}...

u011696379的博客 7817

IAP实验笔记

ISP和IAP ISP:在系统编程。通过芯片上已经固化好的bootloader,从串口将代码写入内部的flash。这块bootloader位于系统存储区,置位boot引脚来选择系统存储器为启动区域。 IAP:在应用编程。用户根据自己需要将flash分成两个区域,一块用作bootloader,一块是我们正常运行的程序(app),而bootloader的作用和上面ISP的一样,将app代码引导至flash中。 IAP过程 stm32正常运行流程 从图中可以看到,在0x08000000处存放着程序的中断向

qq_45668408的博客 7828

STM32F103 AB_OTA实战:BootLoader双分区、固件升级与断电回滚

在嵌入式设备大规模部署中,固件升级的可靠性直接决定售后维护成本。传统IAP方案仅依赖单App分区,一旦升级过程出现断电或数据错误,设备极易变砖。AB_OTA作为一种双分区备份机制,通过将Flash划分为A/B两个独立App区,配合BootLoader引导与状态标志管理,实现升级失败后的自动回滚。在STM32F103这类Cortex-M3单片机上,合理规划Flash分区、设置中断向量表偏移、设计一包一ACK的串口传输协议,以及引入看门狗确认机制,是构建稳定OTA链路的关键。本文从分区设计、跳转边界检查、固件包

weixin_34335458的博客 344

STM32F0芯片IAP实现之中断向量表重映射(没有中断向量表偏移寄存器SCB->VTOR的应对方法)

问题背景 项目使用STM32F030,需要通过IAP进行固件升级,在FLASH里面要烧录两份代码:一个Boot loader,一个用户应用程序APP。在开发应用程序APP时,外设中断不能正确响应进到对应的中断函数。 解决方案 此原因是在Cortex-M3内核的MCU上可以通过设置SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;该寄存器的值来实现中断向量表的重定义。但在STM32F0xx系列以Cortex-M0为内核的单片机中却怎么也找不到这个设置中断向量表的寄存器,用

a只如初见的博客 1万+

IAP固件升级原理及实现详解

什么是IAP升级? IAP,即In Application Programming,IAP是用户自己的程序在运行过程中对User Flash的部分区域进行烧写。简单来说,就是开发者代码出bug了或者添加新功能了,能够利用预留的通讯接口,对代码进行升级 UART、SPI、IIC、USB等等,当然还有wifi、4G、蓝牙等无线通讯手段,都可以作为IAP升级的方式,今天主要介绍如何使用串口对固件进行升级 STM32的代码启动过程 要想设计IAP,首先需要对MCU的代码启动过程有个了解,先来看看STM32的

qq_16519885的博客 2万+

STM32三方库 - 固件升级/OTA

基于RT-Thread实现STM32的SD/HTTP固件升级(OTA)

dxf1971738522的博客 1762

华大HC32F460_IAP固件升级中断处理全解析

本文详细解析了华大HC32F460在IAP固件升级过程中遇到的中断死机问题,提供了中断向量表偏移设置和中断注册清除的解决方案。通过实际案例和代码示例,帮助开发者快速定位并解决类似问题,提升固件升级的稳定性和可靠性。

weixin_30387339的博客 544

stm32使用SD卡IAP固件升级笔记

最近开发了stm32用SD卡进行IAP固件升级用的bootloader,特整理一下笔记: 首先说一下升级原理,固件升级需要有2套程序,1套就是加载引导程序,也就是所谓的bootloader。另一套就是APP程序。 主要的难点就是bootloader程序了。下面讲解如何写基于SD卡的bootloader程序。 编写基于SD卡的固件升级bootloader,需要做...

qq_27726651的博客 3904

STM32固件升级之基础知识(一)

这里以KEIL开发环境和STM32F407为例。 上电时单片机首先进入复位中断 Reset_Handler,即汇编文件的复位中断处理函数。 并且有一个中断向量表默认存在于flash地址开始处。 为什么说是默认的呢?这是因为如果没有特殊要求我们一般很少回去修改中断向量表。实际上这个中断向量表是可以更改的。如果我们更改了中断向量表,在执行新的程序时,必须在地址开始处建立一个新的中断向量表,因为复位后,程序默认(硬件决定的)从flash开始的第一个字读取栈指针,第二字就是复位中断的入口,并根据该指针

weixin_41080308的博客 2521

IOT项目之固件升级

固件升级是指在设备已经投入使用后,通过修改设备上的固件程序,来对设备的功能、性能、安全等方面进行改进。设备的固件通常存储在非易失性存储器中,如Flash芯片。固件升级可以通过多种方式实现,如串口、USB、网络等。

技术小白的博客 1437

RS485接口的IAP固件升级工具

RS485接口的IAP固件升级工具 文章目录RS485接口的IAP固件升级工具前言一、概述二、IAP技术原理三、IAP编程实现1.bootloader程序2.APP程序四、上位机的编写五、总结 前言 当我们采用MCU设计的电子产品在出售后、安装在野外、固件存在BUG时或客户需求有变动, 都需要对固件进行维护和升级。由于距离远且需频繁调试测试, 不可能每次都安装人手去现场升级固件, 势必会造成巨大的成本开销, 这是非常不利于企业发展的。因此, 需要对产品可进行远程升级固件, 而远程升级固件就要使用到

chengzidun的博客 5934

mcu loader升级固件原理与实现

这样修改之后,app 模式下响应的中断,会跳转到 COMMON_IRQHANDLER 中断向量下执行程序。loader.bin 和h076_mcu_app.bin 合并成h076_mcu.bin,h076_mcu.bin 一共 64k(根据 MCU 的 flash 大小来调整,如果 flash 的大小为 32k,h076_mcu.bin 应设置为 32k), 其中loader.bin 在h076_mcu.bin 的前 6k 位置中,后 58 k 为h076_mcu_app.bin,如图所示。

weixin_49406449的博客 2680

【云隐】STM32F103C8T6实现串口IAP方式升级固件

首先下载官方STM32F10X的IAP Bootloader源码,STM32F10x_AN2557_FW_V3.3.0。 源码包地址:http://download.youkuaiyun.com/download/yunyin_link/10151170 用Keil4打开工程代码STM32F10x_AN2557_FW_V3.3.0\Project\IAP\MDK-ARM\IAP.uvproj 第一步:因...

yunyin_link的博客 1万+

STM32单片机IAP固件升级讲解

STM32 的 IAP 升级本质是通过 “Bootloader + 分区 Flash + 跳转机制” 实现的,核心是让设备在不拆壳、不接编程器的情况下,自己更新 App 程序。这种方式极大简化了嵌入式设备的维护和升级,是工业控制、物联网设备的必备功能。实际开发中,需重点关注 Flash 分区、跳转逻辑和固件校验这三个关键点。

shu1240的博客 1667

Cortex-M3:为什么 OTA 升级后程序跑飞?

OTA升级后程序跑飞的两大根源:中断向量表位置未重定位(VTOR设置问题)和链接脚本分区错误(错误基址、.data加载地址错误)。需要简洁概括。不要超过150字。</think>OTA升级后程序跑飞,根源有二:一是中断向量表位置未重定位,Bootloader跳转前未设置VTOR或App启动代码VTOR地址错误;二是链接脚本分区错误,App链接基址未改为实际分区地址,导致向量表和绝对地址错乱。修复需确保VTOR正确设置并128字节对齐,且链接脚本

内容主要在公众号OneChan讲Soc嵌入式上更新 92

STM32 BootLoader+App工程开发详解:Flash分区、跳转逻辑与固件升级

在嵌入式开发中,BootLoader是设备启动时最先运行的程序,它决定了固件升级的实现方式。其核心原理是通过合理的Flash分区规划、中断向量表重映射和跳转逻辑,在引导用户App前检查升级请求,并完成固件接收、校验与写入。这种机制让产品无需拆机即可通过串口、蓝牙或网络完成升级,大幅降低维护成本;采用AB双分区设计还能实现断电保护与版本回滚,保障设备可靠性。从STM32等MCU的IAP升级,到基于LabVIEW、C#或Python的上位机工具开发,再到蓝牙App控制ESP32实现无线升级,都是这一技术的典型应

weixin_33841503的博客 373

通过串口发送固件进行IAP升级

工作流程:系统启动后运行bootloader程序,按键检测是否有固件更新请求。若是有更新则通过串口接收新的固件,并将接收到的固件存储在指定Flash区域。最后,跳转到相应的地址运行APP程序。

2301_81406466的博客 1144

利用Arcgis提取nc数据并计算区域年均温

1.下载数据。2.解压数据至不含中文的路径中。打开工具箱中的多维分析工具-创建NetCDF栅格图层,导入数据。3.打开工具箱中的数据管理工具-图层和表视图-创建栅格图层,导入数据,对输出数据进行命名,得到月均温栅格数据。4.选择工具箱-Spatial Analyst工具(空间分析工具)-地图代数-栅格计算器,计算全国一年年均温。​5.将其导出为.tif格式数据,方便后期使用。6.选择工具箱-Spatial Analyst工具(空间分析工具)-区域分析--以表格显示分区统计,得到分区域的气温数据。

什么都学亿点点的博客 7992

STM32 如何生成升级固件

点击左上角的“关注”,定期更新 STM32 最新资讯,总有你想要的信息! STM32 如何生成升级固件 项目信息 处理芯片:STM32F407VET6(512KB Flash,192KB RAM) 升级接口:串口 升级通信协议:Ymodem 程序存储器:芯片内部 Flash Bootload 程序大小:31396 byte 升级固件大小:83452 byte 1. STM32 的程序运行流程 无 IAP 程序时的运行流程 图1 无 IAP 程序时 STM32 的运行流程   STM32...

Jesse_嘉伟的专栏 3657

Cocos Creator Android打包:NDK版本选择与配置全攻略

在Android原生开发中,NDK(Native Development Kit)是编译C/C++代码的核心工具链,它决定了代码如何被编译为不同CPU架构(如ARMv7、ARM64)的动态库。其工作原理在于提供了一套完整的交叉编译环境,将高级语言代码转化为设备可执行的二进制指令。这一技术对于游戏引擎和性能敏感型应用至关重要,因为它能直接调用硬件资源,提升运行效率。在实际工程中,NDK版本必须与Android Gradle插件(AGP)版本、项目依赖的C++标准库精密匹配,否则会导致编译失败或运行时崩溃。特别

weixin_33725270的博客 490

【sap2000】部分模型通过.s2k文件合并模型generating a global model through partial models by .s2k text file

现在需要通过选项File → Import → SAP2000 .s2k Text File → Add to existing model(如果使用其中一个部分模型作为基础)或New model(如果使用新文件)添加部分模型,并使用以下导入选项。模型A(阶段1/5) Model A (Phase 1/5)模型B(阶段2/5) Model B (Phase 2/5)模型C(阶段3/5) Model C (Phase 3/5)模型E(阶段5/5) Model E (Phase 5/5)

hmywillstronger的博客 1751
上一篇: 【随手笔记】三轴传感器
下一篇: 【固件升级】之IAP(二)
Long-Run
博客等级 码龄3年 4600粉丝 85原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值