Cortex-M处理器中断向量表

本文详细解读了Cortex-M3的中断向量表结构,包括向量地址重定向、中断优先级控制、服务程序定位及中断处理流程。通过实例解析,展示了如何从BIN文件中读取和理解中断向量表,以及中断优先级的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 这是Cortex-M3手册里面截取出来的中断向量表:

系统复位后中断向量表始终是在0x00000000地址。
系统启动后可以对中断向量表进行重定向:
SCB->VTOR = vector_addr;

中断向量表可以看做一个uint32_t类型的数组,数组长度取决于芯片厂商定义多少个中断。
从IRQ0开始属于芯片厂商自定义的中断。

Cortex-M0最多32个中断
Cortex-M3/M4/M7最多240个中断

系统上电时:
第1个成员用于初始化SP寄存器
第2个成员用于初始化PC寄存器
其余成员都指向对应的中断处理程序的地址。

当发生中断的时候,MCU从中断向量表中找到该中断服务程序的地址,跳转过去。
跳转之前,MCU会自动完成部分寄存器的入栈,入栈顺序如下图所示。
中断服务程序返回时,MCU自动完成这部分寄存器的出栈。


关于中断优先级:

中断最多可以用8bit来控制优先级,且数值越小优先级越高
有三个特殊值:HardFault = -1、NMI=-2、RESET=-3
这8个bit又可以分成2组:抢占优先级和子优先级。
下图是优先级的分组方式:

抢占优先级高的,可以打断正在执行的低优先级中断,先执行高优先级中断。
抢占优先级相同的情况下,子优先级之间不会发生抢占。

当多个中断同时发生时,按照以下顺序比较优先级:
抢占优先级 -> 子优先级 -> 中断号


中断向量表实例:

中断向量表是在start.s里面定义好的,编译器会把它放到BIN文件的起始位置。
随便打开一个编译出来的BIN文件进行查看:

因为Cortex-M一般是小端格式,所以每4个字节要倒过来。
前4个字节就是0x1000EA68,它表示上电后的SP值。
接下来4个字节是0x00000101,它表示ResetHandler,它表示上电后的PC值。
PC=0x00000101,所对应的第一条指令就是0x5088F64E。

备注:
PC最低位为1表示是Thumb模式,并不是真实的地址偏移。
指令0x5088F64E的第[15:11]位为11110B,表示这是一条32位Thumb指令。

从这个文件我们还能反向推断出其它的信息:
ROM起始地址是0x00000000
RAM起始地址(可能)是0x10000000
目标MCU肯定不是Cortex-M0
这段代码可能使用了RTOS

<think>好的,我需要帮助用户了解Cortex-M0中断向量表的偏移配置方法及原因。首先,我需要回忆一下Cortex-M0的中断处理机制,以及与其他系列如M3/M4的区别。根据提供的引用资料,Cortex-M0没有SCB->VTOR寄存器,而M3/M4有,因此M0中断向量表重映射方法不同。 首先,用户提到的参考文章指出,M0中断向量表在复位后固定在0x00000000地址,无法通过寄存器直接重定位。这意味着需要其他方法来实现偏移,比如在bootloader和应用程序中手动处理。 接下来,我需要整理配置步骤。根据引用1和2,bootloader需要将应用程序的中断向量表复制到RAM的特定地址,并可能设置栈顶指针。而应用程序则需要修改启动文件,将向量表定位到RAM,并在MDK或IAR中配置相应的RAM地址。此外,链接脚本需要调整,确保向量表正确偏移。 关于原因,用户可能想知道为什么需要这样做。主要是因为M0缺乏VTOR寄存器,无法动态重定位向量表,因此在多应用程序环境(如bootloader和app)中,必须手动调整向量表的位置,以确保中断处理程序正确指向当前应用的入口。 还需要注意一些关键点,比如中断向量表必须位于RAM起始位置,应用程序的起始地址需要与偏移后的向量表对齐,以及不同工具链的配置差异。这些细节需要清晰地传达给用户,避免配置错误导致的中断无法响应问题。 最后,生成相关问题需要考虑用户可能进一步探究的方向,比如与M3/M4的区别、bootloader与app的协作机制,以及常见错误和调试方法。这些问题可以帮助用户更深入理解中断向量表配置的重要性和实际应用中的注意事项。 总结来说,我需要分步骤解释配置方法,阐明原因,并列举注意事项,确保用户能够理解并正确实施中断向量表偏移配置。</think>### Cortex-M0中断向量表偏移配置方法及原因分析 #### 一、配置方法 由于Cortex-M0**没有SCB->VTOR寄存器**,无法通过寄存器直接重定位中断向量表,需采用以下步骤实现偏移: 1. **Bootloader处理** - 在RAM中预留固定区域(如`0x20000000`),将应用程序的中断向量表**完整复制到该区域**。 - 执行`__set_MSP(*(__IO uint32_t*)APP_VECTOR_TABLE)`设置主栈指针[^1]。 2. **应用程序处理** - **修改启动文件**(如`startup_*.s`),将向量表定位到RAM地址: ```assembly AREA RESET, DATA, READONLY EXPORT __Vectors __Vectors DCD __initial_sp ; 栈顶地址 DCD Reset_Handler ; 复位中断 DCD NMI_Handler ; NMI中断 ... ; 其他中断向量 ``` - **MDK/IAR工程配置**: - MDK:`Options for Target -> Linker -> R/O Base`设置为RAM地址(如`0x20000000`) - IAR:修改链接脚本`.icf`文件,添加`define symbol __ICFEDIT_region_ROM_start__ = 0x20000000;`[^2] #### 二、配置原因 1. **多程序协作需求** 在Bootloader+App架构中,App的中断向量表必须**脱离Bootloader的Flash地址空间**,否则中断会跳转到Bootloader的中断服务程序[^3]。 2. **硬件限制** Cortex-M0中断向量表**固定映射到0x00000000**,但可通过**重映射存储器控制器**(如STM32的SYSCFG寄存器)将Flash/RAM映射到该地址。 3. **动态加载特性** 当App需要**热更新**时,RAM中的向量表可实现运行时动态修改,而Flash中的向量表需擦写整个扇区。 #### 三、关键注意事项 1. **向量表对齐** 向量表必须满足**128字节对齐**,例如STM32F0的向量表总长0xC0(192字节),需保证`APP_VECTOR_TABLE % 128 == 0`。 2. **中断响应延迟** RAM中的向量表访问速度比Flash快,但**复制操作会增加启动耗时**,典型延迟公式: $$ T_{delay} = N_{vectors} \times t_{memcopy} + t_{stack\_init} $$ 3. **调试陷阱** 若未正确配置`.icf`或`.ld`链接脚本,可能导致**HardFault**,可通过以下方法验证: ```c printf("Vector table addr: 0x%08X\n", SCB->VTOR); // M0读取无效,M3/M4有效 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值