VTOR的对齐

发布时间:2026/10/29 11:08:30
VTOR的对齐 最近有一个问题会导致MCU不停的reset经过调试发现是由于中断向量表被意外篡改了那是什么原因导致中断向量表被意外篡改的呢主要原因是VTOR的对齐问题接下来详细介绍一下这个问题。一开始从call stack中发现在某个中断触发后会进入hardfault回溯hardfault的堆栈信息发现是一个无效的PC值导致了hardfault这个时候去查看0x0处中断向量表对应的地址发现并没有这个无效地址那么这个无效地址是从哪里来的呢此时脑海想到了VTOR这个寄存器所以去查看了一下这个寄存器的值果然有问题VOTR的值为0x20000200所以中断向量表被重定向到了0x20000200这个区域。并且通过调试器定位到向量表重定向发生在库函数Interrupt_Initialisation(nvic_servicedata)中。通过去查看0x20000200物理区域也发现确实存在这个无效地址。所以这个无效地址是怎么来的呢并且发现Interrupt_Initialisation(nvic_servicedata)调用完之后0x0处的中断向量表被拷贝在了0x20000280开始的表中这显然与VTOR中显示的0x20000200是有出入的。此时去查看map文件发现“nvic_servicedata 0x20000280 Data”nvic_servicedata占用了0x20000280为起始地址的ram区域再一看0x20000200-0x20000280这一块区域被分配给其他变量所以真相就是MCU认为的中断向量表的起始地址是0x20000200但是中断向量被拷贝到了预留的0x20000280的nvic_servicedata区域。但是在这里有产生一个问题那就是实际的中断向量表在物理地址0x20000280这个区域但是MCU因为VTOR中为0x20000200会认为向量表在0x20000200那么应该所有的中断函数都会有问题但实际上并没有这是什么原因呢原因是Interrupt_Initialisation(nvic_servicedata)之后紧接着调用了InterruptRegister()这个库函数初始化了除16个异常之外的中断服务函数好在这个InterruptRegister()在进行初始化时是以VTOR中的20000200为基址初始化的。因此只要你没有触发16个异常中的任何一个就暂时不会有问题。这里正好也可以解释为什么MCU会reset因为hardfault的异常入口地址被更改为了0x0所以hardfault产生时程序跑飞了最后导致了watchdog reset。通过Armv8-M Architecture Reference Manual.pdf可以发现确实VTOR的最小对齐为0x80所以这里有两种可能一供应商固化在flash里面的库函数Interrupt_Initialisation有bug把后8位mask掉了二芯片设计时硬件上就把后8位mask掉了。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询