[技术讨论] 【Cortex-Mx系列的SCB关键寄存器浅谈】之三:VTOR寄存器

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

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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

评论

[url=home.php?mod=space&uid=760190]@21小跑堂[/url] 管理员,你好,求原创审核哦!  发表于 2025-8-1 14:55
您需要登录后才可以回帖 登录 | 注册

本版积分规则

109

主题

1165

帖子

22

粉丝
快速回复 在线客服 返回列表 返回顶部