首页 > 解决方案 > 硬件中断如何在没有任何事先设置的情况下触发软件处理程序

问题描述

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

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

问题 1

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

问题2

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

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

我很困惑如何在没有设置或在我的实际 c 代码中明确引用它的情况下调用这个函数。程序如何从向量表查找到调用这个函数?

编辑#1:

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

编辑#2:

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

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

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

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

标签: embeddedmicrocontrolleratmelmicrochipfirmware

解决方案


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

当处理器遇到异常时,它首先将堆栈帧 ( xPSR, PC, LR, R12, R3-R0) 推送到当前活动的堆栈指针 (MSPPSP),然后从向量表中获取异常处理程序的地址,然后从该位置开始运行代码.

当有一条POP指令加载PC, 或BX从异常处理程序中返回的指令时,处理器从异常处理程序返回,它解栈被压入的堆栈帧,并从它停止的地方继续执行。Cortex M0+ 用户指南 - 异常进入和退出中解释了此过程

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

根据您使用的工具集/库,有不同的方法来定义向量表,并说明它应该存在于内存中的哪个位置。

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

我没有使用基于 Atmel 的 ARM 的经验,但评论中的@Lundin 说向量表位于“startup_samxxx.c”文件中。如果您是从头开始,则由您来确保您拥有合适的向量表,并且它位于合理的位置。


推荐阅读