硬件中断如何在没有任何事先设置的情况下触发软件处理程序
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 不包含拇指代码,它是一个函数地址列表,这些函数是您的异常处理程序的实现。
当处理器得到异常时,它首先将堆栈帧(xPSR
、PC
、LR
、R12
、R3-R0
)压入当前活动的堆栈指针(MSP
或 PSP
),然后它从向量 table 中获取异常处理程序的地址,然后从该位置开始 运行 代码。
当存在从异常处理程序中加载 PC
的 POP
指令或来自异常处理程序的处理器 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,并且它位于一个合理的位置。
我目前正在学习处理器中断,并且 运行 遇到了一些困惑。据我了解,处理器有一组用于外围设备的外部中断。这样制造商就可以提供一种通过自己的外围设备中断处理器的方法。我知道对于这个特定的处理器(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 不包含拇指代码,它是一个函数地址列表,这些函数是您的异常处理程序的实现。
当处理器得到异常时,它首先将堆栈帧(xPSR
、PC
、LR
、R12
、R3-R0
)压入当前活动的堆栈指针(MSP
或 PSP
),然后它从向量 table 中获取异常处理程序的地址,然后从该位置开始 运行 代码。
当存在从异常处理程序中加载 PC
的 POP
指令或来自异常处理程序的处理器 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,并且它位于一个合理的位置。