打印
[STM32F7]

STM32F7 中断向量地址偏移问题

[复制链接]
2593|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zchong|  楼主 | 2017-1-19 14:50 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
STM32F7与以往的芯片不同,上电启动的时候,由boot管脚和BOOT_ADD[15..0]共同决定取址地址,这里仅讨论boot管脚为0,BOOT_ADD0[15..0]=0x00200000的情况,
这种情况下0x00200000地址就是内部flash的起始地址(从ITCM-FLASH方向看),也就是0x08000000(从AXIM接口看),而且ST已经做好了,程序中并不需要对中断向量表进行偏移,
我的问题是,如果使用了IAP,那么我的APP如果位于0x00300000,即偏移了0x00100000,那么我的中断向量表是不是设置成偏移量为0x00100000即可,还是要设置成0x00300000?
沙发
feelhyq| | 2017-1-19 15:14 | 只看该作者
offset 偏移量为0x100000,  但是SCB_VTOR寄存器中应该设置成实际地址,即0x00300000

使用特权

评论回复
板凳
huangcunxiake| | 2017-1-19 17:17 | 只看该作者

我们也知道怎么跳到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



使用特权

评论回复
地板
zchong|  楼主 | 2017-1-19 18:40 | 只看该作者
feelhyq 发表于 2017-1-19 15:14
offset 偏移量为0x100000,  但是SCB_VTOR寄存器中应该设置成实际地址,即0x00300000

看了一下,CPU复位以后VTOR的值是0x00200000,看来这个值只是CPU自己填进去的,如果自己设置的话,根据具体地址设置就可以了,如果偏移了0x00100000,那就设置成0x00300000即可。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

50

主题

1746

帖子

4

粉丝