没有任何事先设置的硬件中断如何触发软件处理程序[关闭]

Posted

技术标签:

【中文标题】没有任何事先设置的硬件中断如何触发软件处理程序[关闭]【英文标题】:How does a hardware interrupt trigger software handlers without any prior setup [closed] 【发布时间】:2018-09-21 02:36:02 【问题描述】:

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

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

问题 1

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

问题 2

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

void EIC_Handler() 
  // Code to handle interrupt

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

编辑#1:

我对包含拇指代码的向量表有误。向量表包含异常处理程序的地址。

编辑#2:

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

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

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

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

【问题讨论】:

您急需一本教科书或当地大学的一门好课程。抱歉,堆栈溢出不是一个教程站点;你的问题太宽泛了。好消息是所有信息都可以在文档中找到。不要尝试仅从 youtube 视频等不起眼的在线网站学习。 感谢您的评论,但我不同意这个问题过于宽泛。这是关于中断和向量表具体在 Cortex M0 和 SAM 库中如何工作的两个问题。 需要查看arm cortex-m0+技术参考手册和armv6-m架构参考手册。向量表覆盖在那里。是的,它是指向代码的地址列表。让工具链为您完成工作。通常用汇编语言制作一个标签列表,但它只是一个数据列表,而不是真正的代码。然后该工具会为您填写地址。处理程序需要“处理”中断。解决问题。清除整个处理器的中断,通常是处理器外围。 @old_timer 感谢您的评论!是的,继续前进,我肯定会让工具链完成繁重的工作,但我想了解并了解幕后发生的事情。 你有一个粗略的想法。正如 arm 所记录的,向量表是已知位置的地址列表(例如,重置处理程序地址 0x00000004)。必须设置 lsbit,因此地址 0x1000 处的处理程序需要一个条目 0x1001,正确使用工具,他们会这样做(回到 arm/thumb 互通寻址)。中断对于 arm/cortex-m 并不特殊。每种架构(arm、mips、8051、x86 等)都有自己的细微差别,更糟糕的是,对于购买的内核(如 arm mips)或自制软件(如 8051 和 z80),芯片供应商可能会围绕每个芯片供应商不同的内核进行更多封装。 【参考方案1】:

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

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

当有 POP 指令从异常处理程序中加载 PCBX 指令时,处理器从异常处理程序返回,它将被压入的堆栈帧解栈并继续执行它停止的地方。这个过程在Cortex M0+ User Guide - Exception Entry And Exit中有说明

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

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

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

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

【讨论】:

关于 Q2,向量表经常出现在一些不起眼的链接器文件中,既不是用 C 语言编写的,也不是用汇编程序编写的,而是在一些自定义的链接器脚本语法中。 我已经看到了一些基于 MIPS 的 Microchip PIC,但我使用过的来自不同供应商的所有 ARM 都按照我的描述工作。我将保持原样,感谢您的评论,@Lundin,如果这是 OP 的情况,它将增加清晰度。 如果是 Atmel ARM(现为 Microchip),您会在一些 .c 文件“startup_samxxx.c”中找到向量表,它采用非标准的 gcc 风格的 C 语法。对于 NXP ARM(NXP-NXP 和 NXP-Freescale),通常是一些自定义链接器脚本。等等。它远非标准化。 我已经更新了我对问题 2 的回答,再次感谢您的 cmets,@Lundin @Colin 谢谢你的回答,它为我解决了这些问题。假设向量表没有重新映射/更改。向量表中的地址列表是什么?我似乎无法在 Cortex M0+ 文档中找到答案。这就是你说“确保你有一个合适的向量表”的原因吗?向量表是否有默认的“实现”,还是完全由处理器的用户来实现?

以上是关于没有任何事先设置的硬件中断如何触发软件处理程序[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

MCS-51系列单片机的有几个中断源?各中断标志是如何产生的?如何清除各中断标志?

操作系统的中断异常和系统调用

嵌入式Linux裸机开发——S5PV210中断处理流程

如何查看linux软中断信息

x86 硬件/软件 TSS 使用情况

计算机组成原理--中断系统