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

时间:2018-09-21 02:36:02

标签: embedded microcontroller atmel microchip firmware

我目前正在学习有关处理器中断的信息,并且遇到了一些混乱。据我了解,处理器具有一组用于外设的外部中断。这样制造商可以提供一种通过自己的外设中断处理器的方法。我知道使用这种特定的处理器(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句柄指向我的EIC_Handler()。我搜寻了 大量的SAML22和Cortex M0 +文档(并且误读了向量表包含缩略图代码),但是找不到关于如何建立向量表的任何信息,这就是为什么我决定在这里寻找答案的原因。我有一个!

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

1 个答案:

答案 0 :(得分:2)

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

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

当有一条POP指令加载PC或一条BX指令从异常处理程序中加载时,处理器从异常处理程序中返回,则将堆栈帧进行堆栈推动并从中断处继续执行。 Cortex M0+ User Guide - Exception Entry And Exit

中对此过程进行了说明

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

根据所使用的工具集/库,有不同的方法来定义向量表,并说出它在内存中的位置。

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

我没有使用基于Atmel的ARM的经验,但注释中的@Lundin表示向量表位于“ startup_samxxx.c”文件中。如果您是从头开始的,则要确保您有合适的向量表,并且该向量表位于明智的位置。