打印
[技术讨论]

【Cortex-Mx系列的SCB关键寄存器浅谈】之三:VTOR寄存器

[复制链接]
164|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dffzh|  楼主 | 2025-7-1 08:52 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
#申请原创#
@21小跑堂



在上一篇文章(链接:https://bbs.21ic.com/icview-3463182-1-1.html)中作者介绍了SCB的第二个关键寄存器ICSR,本文章将主要介绍SCB的第三个关键寄存器:VTOR。
VTOR,即Vector Table Offset Register,翻译为向量表偏移寄存器,主要用于指定向量表在内存中的位置。
查看core_cm4.h文件,可以看到与VTOR相关的宏定义如下所示:

从宏定义可以看到,VTOR的位域信息如下所示:
  
字段名
  
位域
读写类型
功能描述
TBLOFF
[31:7]
RW
向量表基地址的[31:7]位,必须对齐到向量表大小
/
[6:0]
/
保留位,必须为0
我们先来看看Keil的仿真运行时VTOR寄存器的值:
运行时,值为0x08000000,如下图:

那为什么是0x08000000呢?其实这个就是向量表基地址,在不考虑bootloader的时候,也就是MCU程序(以下称之为app)的起始地址,也就是Keil魔法棒配置里面的ROM起始地址,这个大家应该很熟悉吧:

打开芯片手册,也可以看到flash闪存的地址信息:

那我们可以如何应用VTOR寄存器呢?
使用VTOR最多的地方就是bootloader应用了。
我们现在的固件一般都会增加bootloader程序以方便后期固件执行OTA升级等,即发布固件包括bootloader程序+app程序。因为bootoader也会占用flash地址空间,因此app程序就不能再从默认的0x08000000开始了,需要增加偏移地址。那怎么样操作呢?
假如给bootoader分配闪存的一半空间,即128KB,也就是131072(0x20000)字节,偏移地址就是0x20000,即app程序的起始地址就是0x08000000+0x20000=0x08020000,大小也是128KB;在Keil魔法棒里面就需要按以下进行配置:

app代码的初始化配置还需要增加以下代码:
nvic_vector_table_set(NVIC_VECTTAB_FLASH,APP_VECTOR_OFFSET_ADDR);
如下图所示:

其中nvic_vector_table_set库函数如下:
/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  set the vector table location and offset.
  * @param  base
  *         this parameter can be one of the following values:  
  *         - NVIC_VECTTAB_RAM  
  *         - NVIC_VECTTAB_FLASH
  * @param  offset (vector table base offset field. this value must be a multiple of 0x200)
  * @retval none
  */
void nvic_vector_table_set(uint32_t base, uint32_t offset)
{
  SCB->VTOR = base | (offset & (uint32_t)0x1FFFFF80);
}
很明显,这个库函数就是将新的向量表基地址更新到VTOR寄存器里面,这里需要注意的一点是偏移地址值必须为0x200(512)的整数倍。
宏定义NVIC_VECTTAB_FLASH为库里面的flash基地址:
/*!< nvic vector table based ram address */
#define NVIC_VECTTAB_RAM     ((uint32_t)0x20000000)
/*!< nvic vector table based flash address */
#define NVIC_VECTTAB_FLASH   ((uint32_t)0x08000000)
宏定义APP_VECTOR_OFFSET_ADDR是自定义的,这里也就是0x20000:
#define APP_VECTOR_OFFSET_ADDR  ((uint32_t)0x00020000)
不同的MCU在具体操作上可能有所区别,但本质上是一样的。
总之,VTOR寄存器允许开发者将向量表重定位到内存中的任意位置,而不仅限于默认的地址(通常是0x8000000)。
另外,通过搜索VTOR,还可以看到可以通过读写VTOR寄存器来设置和读取NVIC的中断向量表:

不过作者没有实际操作过,目前不确定在什么场景下可以使用,后续如果有机会用上了再分享;如果有朋友实际用过,可以分享一下。
VTOR寄存器为ARMCortex-M系统提供了灵活的中断处理机制,是嵌入式系统开发中的重要组成部分。
下一篇文章作者将介绍AIRCR(Application Interrupt and ResetControl Register,应用中断和复位控制寄存器)。

使用特权

评论回复

相关帖子

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

本版积分规则

70

主题

885

帖子

16

粉丝