STM32中断向量表的偏移量设置方法

STM32中断向量偏移

总结一下在IAP升级中APP程序的中断向量表的偏移

讲解中断偏移之前先看一下程序的启动流程

STM32F4 的内部闪存( FLASH )地址起始于 0x08000000 ,一般情况下,程序文件就从此
地址开始写入。此外 STM32F4 是基于 Cortex-M4 内核的微控制器,其内部通过一张“中断向
量表”来响应中断,程序启动后,将首先从“中断向量表”取出复位中断向量执行复位中断程
序完成启动,而这张“中断向量表”的起始地址是 0x08000004 ,当中断来临, STM32F4 的内
部硬件机制亦会自动将 PC 指针定位到“中断向量表”处,并根据中断源取出对应的中断向量
执行中断服务程序。
在图 55.1.1 中, STM32F4 在复位后,先从 0X08000004 地址取出复位中断向量的地址,并
跳转到复位中断服务程序,如图标号①所示;在复位中断服务程序执行完之后,会跳转到我们
main 函数,如图标号②所示;而我们的 main 函数一般都是一个死循环,在 main 函数执行过
程中,如果收到中断请求(发生重中断),此时 STM32F4 强制将 PC 指针指回中断向量表处,
如图标号③所示;然后,根据中断源进入相应的中断服务程序,如图标号④所示;在执行完中
断服务程序以后,程序再次返回 main 函数执行,如图标号⑤所示。

 

 

1. 关于APP程序的中断向量表地址偏移(三种方法,stm32F2与F4系列通用。三种方法本质一样只是看到网上的各种例程的表现形式不一样)

① 直接操作寄存器

之前我们讲解过,在系统启动的时候,会首先调用 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;

 

 

在APP程序的main函数的开头设置中断向量表偏移

SCB->VTOR = FLASH_BASE | 0x10000;

其中0x10000是偏移量。。也就是前面的IAP程序所占用的空间大小,要是你的main函数中有SystemInit();的话要在SystemInit();之后添加。

其中

#define FLASH_BASE ((uint32_t)0x08000000) /*!<FLASH base address in the alias region */

#define SRAM_BASE ((uint32_t)0x20000000) /*!< SRAM baseaddress in the alias region */

 

 

 

对应keil设置中的(这是一般程序默认的,IAP升级中APP程序的这个地方还得根据中断偏移量改)

 

 

 

② 使用库函数设置偏移量

在库文件中有专门的一个函数

在APP程序初始化时调用函数NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x10000);

 

其中/* Vector Table Base----------------------------------*/

#define NVIC_VectTab_RAM ((u32)0x20000000)

#define NVIC_VectTab_FLASH ((u32)0x08000000)

 

 

/***********************************************************************

Function Name : NVIC_SetVectorTable

* Description : Sets the vector table location andOffset.

* Input : - NVIC_VectTab: specifies if thevector table is in RAM or

* FLASH memory.

**********************************************************************/

void NVIC_SetVectorTable (u32NVIC_VectTab, u32 Offset)

{

/* Check the parameters */

assert_param(IS_NVIC_VECTTAB(NVIC_VectTab));

assert_param(IS_NVIC_OFFSET(Offset));

 

SCB->VTOR = NVIC_VectTab | (Offset & (u32)0x1FFFFF80);

}

 

③修改库文件(不建议使用)

直接修改固件库里面的数值。在void SystemInit(void)下的

/* Configure the Vector Table location add offsetaddress ------------------*/

#ifdefVECT_TAB_SRAM

SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;/* Internal SRAM */

#else

SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;/* Internal FLASH */

#endif

 

直接修改

#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field.

This valuemust be a multiple of 0x200. */

#define VECT_TAB_OFFSET 0x10000 /*!< Vector Table base offsetfield.

This valuemust be a multiple of 0x200. */

 

 

2.关于IAP程序与APP程序keil中的设置

Stm32的flash都是从0x8000000开始的,结束地址看片子的flash大小

Stm32的sram都是从0x2000000开始的,结束地址看片子的sram大小

 

IAP程序基本默认就行,跟普通程序一样

在APP程序中需要设置一下偏移量

 

默认的条件下,图中IROM1的起始地址(Start)一般为0X08000000,大小(Size)为0X100000,即从0X08000000开始的1M空间为我们的程序存储(因为我们的STM32F4的FLASH大小是1M)。而图中,我们设置起始地址(Start)为0X08010000,即偏移量为0X10000(64K字节),因而,留给APP用的FLASH空间(Size)只有0X100000-0X10000=0XF0000(960K字节)大小了。设置好Start和Szie,就完成APP程序的起始地址设置。

这里的64K字节,需要大家根据Bootloader程序大小进行选择,比如我们本章的Bootloader程序为22K左右,理论上我们只需要确保APP起始地址在Bootloader之后,并且偏移量为0X200的倍数即可(相关知识,请参考:http://www.openedv.com/posts/list/392.htm)。这里我们选择64K(0X10000)字节,留了一些余量,方便Bootloader以后的升级修改。

注意:设置的起始地址要与程序中设置的中断向量表的偏移量对应起来(如果给IAP程序64k的空间则APPkeil中起始地址为0x8010000相应的程序中中断向量偏移0x10000)我用的1M flash大小的片子。。具体的大小设置,看自己的片子。。

,不过也需要注意,保证偏移量为 0X200 的倍数(我们这里为 0X1000 )。
 
  • 43
    点赞
  • 222
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值