stm32 向量表

今天在看代码的时候,看到有这么几行:

//配置向量表

#ifdef  VECT_TAB_RAM        //向量表位于SRAM区
     MY_NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

#else       //向量表位于CODE(FLASH)区
     MY_NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);

#endif

其函数实现如下:

//设置向量表偏移地址

//NVIC_VectTab:基址

//Offset:偏移量

void MY_NVIC_SetVectorTable(u32 NVIC_VectTab, u32 Offset)

{
     SCB->VTOR = NVIC_VectTab | (Offset & (u32)0x1FFFFF80);      //设置NVIC的向量表偏移寄存器
     //用于标识向量表是在CODE区还是在RAM区

}

这里的疑问是:为什么要&上0x1FFFFF80?将1FFFFF80H=0001 1111 1111 1111 1111 1111 1000 0000B,即将bit[31:29]、bit[6:0]清零,而保留bit[28:7]位。可是为什么要这样呢?

带着这个疑问,查阅Cortex-M3编程手册(PM0056 PAGE 133),找到SCB_VTOR寄存器(向量表偏移寄存器)。这个寄存器只有bit[29:9]有用,其余Reserved。

bit[29:9]:TBLOFF[29:9]:向量表基本偏移字段。其中bit29决定了向量表位于Code区还是SRAM区。所以真正起到作用的是bit[28:9]。将bit[28:9]置一,其余位置零,得到32位2进制数0001 1111 1111 1111 1111 1110 0000 0000B=1FFFFE00H。所以我的理解是,对于stm32103,代码里的0x1FFFFF80替换为0x1FFFFE00也是可以的。

那这里又出来一个问题,为什么官方代码里使用了0x1FFFFF80,而不是0x1FFFFE00呢?

原来,这和向量表的起始地址有关。在Cortex-M3权威指南page113有这么一段话:向量表的起始地址是有要求的:必须先求出系统中共有多少个向量,再把这个数字向上增大到是 2 的整次幂,而起始地址必须对齐到后者的边界上。例如,如果一共有 32 个中断,则共有 32+16(系统异常) =48 个向量,向上增大到 2 的整次幂后值为 64,因此地址地址必须能被 64*4=256 整除,从而合法的起始地址可以是: 0x0, 0x100, 0x200 等。

对应到stm32f103,一共有16个内核中断+60个中断=76个中断,向上增大到2的整次幂后为128,因此向量表的起始地址必须能被128*4=512整除,从而合法的起始地址可以是0x0,0x200,0x400,0x800等。除去0x0不谈,最小的合法地址是0x200,其bit9=1,后面全是0,&上0x1FFFFE00是完全没有问题的,不会造成地址丢失。

但是,要想到极端一些的情况,比如一个芯片,它用了16个内核中断+15个中断=31个中断,向上增大到2的整次幂后为32,因此向量表起始地址必须能被32*4=128整除,从而合法的起始地址可以是0x0,0x80,0x100,0x200等。同样的,除去0x0不谈,最小的合法地址是0x80,其bit7=1,后面全是0,这时为了保证bit[28:7]地址不丢失,就不能用0x1FFFFE00相与,只能用0x1FFFFF80相与。

到这里,官方代码为什么使用了0x1FFFFF80,而不是0x1FFFFE00的疑问就顺理成章的解决了:为了代码更好的兼容性,能够兼顾到低配的stm32系列。

时间: 2024-08-24 17:37:28

stm32 向量表的相关文章

STM32向量表详细分析

预备知识: DCD指令:用于分配一片连续的字存储单元(32bit),并将表达式的值初始化给该字存储单元,类似于C中定义数组并初始化.比如: DCD 0 的意思是:分配一个字存储单元,并将该单元初始化为0. 分析: 在STM32的启动文件中可以看到有如下代码: EXPORT __Vectors __Vectors DCD __initial_sp ; Top of Stack DCD Reset_Handler DCD NMIException DCD HardFaultException DCD

我的RTOS 之一 --S5PV210 异常向量表基址和软中断测试

1.异常向量表基址 s5pv210 默认指定了异常向量基址0xD003_4700, 当异常比如中断触发时,会自动跳转到基址查找异常处理函数s5pv210 默认指定了异常向量基址0xD003_4700, 当异常比如中断触发时,会自动跳转到基址查找异常处理函数 通过代码可以这样实现,通过代码可以这样实现, #define _Exception_Vector 0xD0037400 #define pExceptionRESET ( *((volatile unsigned long *)(_Excep

u-boot分析(四)---设置异常向量表|设置SVC模式

u-boot分析(四) 通过前三篇的分析,我们对u-boot已经有了整体的认识和掌握,但是我们仍然对于其部分硬件是如何初始化的不太清楚,所以接下来几篇博文我将会对我们在http://www.cnblogs.com/wrjvszq/archive/2015/01/10/4215627.html一文中总结出的u-boot的工作流程中的重要环节,结合文档加以分析. 今天我们会用到的文档: 1.        ARM Architecture Reference Manual:http://downlo

20.核心初始化之异常向量表

20.核心初始化之异常向量表 一.异常向量表: 包含:1.异常定义 ???? 2.异常类型 ???? 3.异常入口 ???? 4.向量表 首先异常定义,在ARM Architecture Reference Manual.pdf文档中,2.Programmers' Model的2.6.Exceptions异常: 异常:因为内部或外部的一些事件,导致处理器停下来正在处理的工作,转而去处理这些发生的事件. 2.异常类型 当一种异常发生的时候,ARM处理器会跳转到对应该异常的固定地址去执行异常处理程序

[国嵌笔记][032][异常向量表]

异常定义: 因为内部或外部的一些事件,导致处理器停下正在处理的工作,转而去处理这些发生的事件 异常类型: 1.reset 0x00000000 2.undefine instructions 0x00000004 3.software interrupt(swi) 0x00000008 4.prefetch bort(instruction fetch memory abort)   0x0000000C 5.data abort(data access memory abort) 0x0000

5.1异常向量表

异常:因为内部或者外部的一些事件,导致处理器停下正在处理的工作,转而去处理发生的事件 异常向量:7个异常向量及异常向量处理函数跳转关系,组合在一起即为异常向量表 Reset 复位异常 Undefined interrupt 未定义指令异常 Software interrupt软中断 Prefetch Abort预取指令异常 Data Abort 数据异常 Not used 没有使用 IRQ 中断异常 FIQ 快速中断异常

Part5核心初始化_lesson1---异常向量表

1.1异常 异常向量: 异常向量表: 代码的编写 start.S文件 gboot.lds链接器脚本文件 makefile工程文件:

ARM基础:MMU 异常向量表 重映射

/******************************************************************************************************************参考:说明:在学习裸机中断时重新遇到这个几个词,这次就要搞明白了. *****************************************************************************************************

异常向量表设计

在ARM Architecture Reference Manual-A2.6章节给了明确的定义 异常:因为内部或者外部的一些事件,导致处理器停下正在处理的工作,转而去处理这些发生的事件 异常向量:当一种异常发生的时候,ARM处理器会跳转,到对应该异常的固定地址去执行异常处理程序,而这个固定的地址,就称异常向量 起始文件start.c .text .global _start _start: b reset ldr pc, _undefined_instruction ldr pc, _soft