当前位置:首页 > 电子 > 正文内容

STM32 中断向量表的位置 、重定向

admin8年前 (2017-08-25)电子5667

这篇文章已经说了STM32的启动过程:

https://feelsight.cn/post/39.html

我们也知道怎么跳到main函数了,那么,中断发生后,又是怎么跑到中断入口地址的呢?

从stm32f10x.s可以看到,已经定义好了一大堆的中断响应函数,这就是中断向量表,标号__Vectors,表示中断向量表入口地址,例如:

AREA    RESET, DATA, READONLY ; 定义只读数据段,实际上是在CODE区(假设STM32从FLASH启动,则此中断向量表起始地址即为0x8000000)
                EXPORT  __Vectors
IMPORT  OS_CPU_SysTickHandler
       IMPORT  OS_CPU_PendSVHandler

__Vectors       DCD     __initial_sp              ; Top of Stack
                DCD     Reset_Handler             ; Reset Handler
                DCD     NMI_Handler               ; NMI Handler
                DCD     HardFault_Handler         ; Hard Fault Handler
                DCD     MemManage_Handler         ; MPU Fault Handler
                DCD     BusFault_Handler          ; Bus Fault Handler
                DCD     UsageFault_Handler        ; Usage Fault Handler

这个向量表的编写是有讲究的,跟硬件一一对应不能乱写的,CPU找入口地址就靠它了,bin文件开头就是他们的地址,参考手册RM0008的10.1.2节可以看到排列。

我们再结合CORTEX-M3的特性,他上电后根据boot引脚来决定PC位置,比如boot设置为flash启动,则启动后PC跳到0x08000000。此时CPU会先取2个地址,第一个是栈顶地址,第二个是复位异常地址,故有了上面的写法,这样就跳到reset_handler。

那么这个reset_handler的实际地址是多少.?下面的一堆例如Nmi_handler地址又是多少呢?发生中断是怎么跑到这个地址的呢?下面挨个讲解。

1、我们可以通过反向来得知这些入口地址,查看工程下的map文件就可以看到了,这个地址跟keil里面设置的target->flash起始地址息息相关,实际上我们不太需要关心,让编译器分配,中断向量表放的就是他们的地址。

2、对比ARM7/ARM9内核,Cortex-M3内核则是固定了中断向量表的位置而起始地址是可变化的。

3、进到C语言后会先配置NVIC,NVIC_SetVectorTable()里面可以配置中断向量表的起始地址和偏移,主要是告诉CPU该向量表是位于Flash还是Ram,偏移是多少。例如设置为位于Flash内,偏移就是烧入的程序地址,可在Keil target中设置。这样CPU就知道入口地址了。

4、发生中断后,CPU找到中断向量表地址,然后根据偏移(对号入座)再找到中断地址,这样就跳过去了。

我们截一个图说明一下,map文件:

对应的bin文件,看是不是放的上面地址:

显然,200039c0就是栈顶地址,而08006F21就是reset_handler地址!

如何定位?以放到0x20000000为例

1、keil设置ram起始为0x20000100,我们在0x20000000~0x20000100放中断向量表,其他给程序用

2、设置NVIC_SetVectorTable(NVIC_VectTab_FLASH,0);

3、跳到C时把中断向量表拷贝到0x20000000


阅读剩余的17%

扫描二维码推送至手机访问。

版权声明:本文由视觉博客发布,如需转载请注明出处。

本文链接:https://feelsight.cn/post/40.html

“STM32 中断向量表的位置 、重定向” 的相关文章

内存堆和栈的区别

内存堆和栈的区别

在计算机领域,堆栈是一个不容忽视的概念,我们编写的C语言程序基本上都要用到。但对于很多的初学着来说,堆栈是一个很模糊的概念。 堆栈:一种数据结构、一个在程序运行时用于存放的地方,这可能是很多初学者的认识,因为我曾经就是这么想的和汇编语言中的堆栈一词混为一谈。我身边的一些编程的朋友以...

锂电池充电的原理

锂电池充电的原理

    锂离子电池的充电过程可以分为四个阶段:涓流充电(低压预充)、恒流充电、恒压充电以及充电终止。     锂电池充电器的基本要求是特定的充电电流和充电电压,从而保证电池安全充电。...

linux系统 硬盘自动挂载 自动格式化 脚本

mkdir /data1 mkdir /data2 mkdir /data3 mkdir /data4  mkfs.xfs /dev/sdb1 echo "/dev/sdb...

如何看懂电路图(二)-电源电路

如何看懂电路图(二)-电源电路

前 面介绍了电路图中的元器件的作用和符号。一张电路图通常有几十乃至几百个,它们的连线纵横交叉,形式变化多端,初学者往往不知道该从什么地方开始, 怎样才能读懂它。其实电子电路本身有很强的规律性,不管多复杂的电路,经过分析可以发现,它是由少数几个单元电路组成的。好象孩子们玩的积木,虽然只有十 来...

电源模块中隔离电压3000VDC有什么用?

电源模块中隔离电压3000VDC有什么用?

随着嵌入式行业的快速发展,在各种行业应用中电源要求也越来越高,为保证系统的稳定性,隔离电源应运而生。但隔离电源中关键指标——隔离电压指的是什么?与爬电距离有什么关系?本文将从隔离电源的原理为你揭晓。 微电子行业的高速发展,产品使用场合的电磁环境也越来越复杂,产品的稳定性也受到很大的...

如何看懂电路图(三)-三极管放大电路

如何看懂电路图(三)-三极管放大电路

能够把微弱的信号放大的电路叫做放大电路或放大器。例如助听器里的关键部件就是一个放大器。 放大电路的用途和组成 放大器有交流放大器和直流放大器。交流放大器又可按频率分为低频、中源和高频;接输出信号强弱分成电压放大、功率放大等。此外还有用集成运算放大器和特殊 晶体管作器件的...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。