硬件中断如何在没有任何事先设置的情况下触发软件处理程序

How does a hardware interrupt trigger software handlers without any prior setup

我目前正在学习处理器中断,并且 运行 遇到了一些困惑。据我了解,处理器有一组用于外围设备的外部中断。这样制造商就可以提供一种通过自己的外围设备中断处理器的方法。我知道对于这个特定的处理器(ARM Cortex M0+),一旦外部中断线被触发,它将转到它的向量 table 和相应的中断请求偏移量,并且(我在这里可能是错的)将执行 ARM thumb该地址的代码。

如果我理解正确的话,一些处理器会查看上述 IRQ 地址的值,该地址将指向中断处理程序的地址。

问题一

在了解 ARM Cortex M0+ 向量时 table,thumb 代码在那个地址做什么?我假设它正在做一些事情,比如将 PC 寄存器设置为中断处理程序地址,但这只是在黑暗中刺伤。

问题二

到目前为止,我发现处理 EIC 中断的唯一方法是使用以下代码片段

void EIC_Handler() {
  // Code to handle interrupt
}

我很困惑如何在我的实际 C 代码中没有设置或明确引用它的情况下调用此函数。程序如何从 vector table 查找到调用此函数?

编辑#1:

关于包含拇指代码的矢量 table 我错了。向量 table 包含异常处理程序的地址。

编辑#2:

尽管得到了我正在寻找的答案,但我的问题显然不够具体或者 "off-topic",所以让我澄清一下。

虽然 reading/learning 从 多个资源 了解如何在软件中处理外部中断,但我注意到每个来源都说只需添加上面的代码片段。我很好奇中断是如何从硬件一直到调用我的 EIC_Handler() 的,除了定义函数和 EIC 之外,我没有设置任何东西。所以我研究了什么是矢量 table 以及当不同的中断发生时处理器将如何转到它的某些部分。这仍然没有回答我的问题,因为我没有自己设置向量 table,但我的 EIC_Handler() 函数仍在被调用。

所以不知何故在编译时,必须创建向量 table 并且相应的 IRQ 句柄指向我的 EIC_Handler()。我搜索了 大量的 SAML22 和 Cortex M0+ 文档(并且误读向量 table 包含拇指代码)但是找不到关于向量 table 是如何设置的任何信息,这就是为什么我决定在这里寻找答案。我得到了一个!

我发现 IDE (Atmel studio) 和我选择的项目配置附带了一个定义弱函数的小文件、重置处理程序的实现和向量 table。还有一个自定义链接描述文件获取函数的地址并将它们放入向量 table,如果实现了一个弱函数,它将指向该实现并在适当的中断请求发生时调用它。

对于 Cortex M0(和其他皮质?corticies?)向量 table 不包含拇指代码,它是一个函数地址列表,这些函数是您的异常处理程序的实现。

当处理器得到异常时,它首先将堆栈帧(xPSRPCLRR12R3-R0)压入当前活动的堆栈指针(MSPPSP),然后它从向量 table 中获取异常处理程序的地址,然后从该位置开始 运行 代码。

当存在从异常处理程序中加载 PCPOP 指令或来自异常处理程序的处理器 returns 的 BX 指令时,它拆栈被压入的栈帧并从它停止的地方继续执行。 Cortex M0+ User Guide - Exception Entry And Exit

中解释了此过程

对于问题2,CortexM0/M0+中的向量table通常位于地址0x00000000。某些 Cortex M0/M0+ 实现允许使用系统控制块中的向量 table 偏移寄存器重新映射向量 table,其他实现允许您重新映射地址 0x00000000 处可用的内存。

根据您使用的工具 set/library,定义向量 table 并说明它在内存中的位置有不同的方法。

通常有微控制器可用异常名称的弱链接函数,当您在源文件中实现它们时,链接而不是弱函数,它们的地址被放入向量中table.

我没有使用基于 Atmel 的 ARM 的经验,但@Lundin 在评论中说向量 table 位于 "startup_samxxx.c" 文件中。如果您是从头开始,您需要确保拥有一个 suitable 向量 table,并且它位于一个合理的位置。