把微控制器向量表统称为“一列中断函数地址”,会遗漏表开头的一项特殊内容。Arm的CMSIS-Core v6.0.0文档在Vector Table及Processor Exceptions连续说明中,先定义异常和中断的入口地址,随后明确指出:向量表开头包含初始栈值,以及处理器的异常向量。[1] 首项与后续入口并没有被赋予同一种角色。

文档例表将最前一项标为初始栈值,并以注释说明它用于栈顶初始化;接下来才是Reset_Handler、NMI_Handler等处理程序入口。[1] 因而,“位于同一张表”不能使首项也变成另一段处理函数。对开发文档的解释应保留这项次序关系,否则把所有表项一律称为handler,会使栈值在摘要中失去自己的含义。

表本身也有地址。该节用__Vectors表示启动代码中的向量表地址,并说明VTOR保存表的起始地址。[1] 这是整张表位于哪里,与表内某个异常处理程序的入口在哪里,属于不同层次。一个是容纳各项资料的表位置,另一个是其中某个处理入口,不能只因二者都写成地址就合为一个对象。

处理器异常之后,文档又列出器件专有中断向量。[1] 这让表的构成带有两种来源:处理器所具有的异常,以及具体器件增加的中断。前面示例采用Armv8-M Mainline处理器,并提醒其他处理器变体可能具有更少的向量。读者因此不能把一份示例的名字数量,直接当作所有Cortex-M器件统一具有的完整集合。

相邻Description还解释了模板与具体器件的关系。Arm为所支持的编译器提供启动模板,芯片供应商需要据具体器件补入相应中断向量;文档把各处理程序的默认定义联系到弱定义的占位处理程序。[1] 这里保留的是文档对象由通用模板进入具体器件的来源关系,本文不转录启动代码,也不教替换处理程序。

另一个明确条件是TrustZone。文档说,实现TrustZone的Armv8-M具有Secure与Non-Secure两张向量表,分别对应两类处理程序。[1] 这个前提是定义的一部分,不能删去后概括成所有Cortex-M都有两张表。表的数量与所属实现条件相连,而非仅由“向量表”这个总名决定。

对整理微控制器资料的人,可以沿着表位置、首项栈值、处理器异常入口、器件中断入口这条顺序理解原文。它具体回答了表里各项为何不同,也避免把某一内核的例表扩成所有器件的规格。本篇限定CMSIS 6的v6.0.0入口与所述连续文字,首次发布日期未知;未采用图形或配置示例,没有设置寄存器、重映射向量、烧录启动文件或作控制安全判断。

资料:[1] https://arm-software.github.io/CMSIS_6/v6.0.0/Core/group__NVIC__gr.html

信息来源

本文基于上述公开资料整理,未使用来源页面的图片、视频或嵌入媒体。