功能与中断调用中的上下文切换?

标签 c linux multithreading interrupt-handling isr

<分区>

我从下面的 SE 问题中理解了函数调用和中断 (ISR) 跳转之间的基本区别。

difference between function call & ISR

但我仍然不清楚,在这两种情况下,哪些寄存器将被压入/弹出堆栈?在这两种情况下如何进行上下文切换?由于我们不知道什么时候会发生中断,在进入ISR之前我们需要保存什么(变量、PC、标志(PSW)、寄存器、上下文)?

我们如何在多线程环境中恢复原始上下文而不丢失任何数据。

最佳答案

我尝试用谷歌搜索它,并从中找到了所需的信息:

  1. Interrupts
  2. Context Switch

感谢@Drew McGowen

综上所述,中断的一般顺序如下:

Foreground code is running, interrupts are enabled
Interrupt event sends an interrupt request to the CPU
After completing the current instruction(s), the CPU begins the interrupt response
automatically saves current program counter
automatically saves some status (depending on CPU)
jump to correct interrupt service routine for this request
ISR code saves any registers and flags it will modify
ISR services the interrupt and re-arms it if necessary
ISR code restores any saved registers and flags
ISR executes a return-from-interrupt instruction or sequence
return-from-interrupt instruction restores automatically-saved status
return-from-interrupt instruction recovers saved program counter
Foreground code continues to run from the point it responded to the interrupt

像往常一样,这个过程的细节将取决于 CPU 设计。许多设备使用硬件堆栈来保存所有数据,但 RISC 设计通常将 PC 保存在寄存器(链接寄存器)中。许多设计还具有单独的重复寄存器,可用于中断处理,从而减少必须保存和恢复的状态数据量。

请注意,为了提高效率,保存和恢复前台代码状态通常是一个两步过程。硬件对中断的响应会自动保存最基本的状态,但 ISR 代码的第一行通常专门用于保存额外的状态(如果硬件没有保存,通常以保存条件标志的形式,同时保存额外的寄存器)。使用这个两步过程是因为每个 ISR 对其所需的寄存器数量都有不同的要求,因此每个 ISR 可能需要保存不同的寄存器和不同数量的寄存器,以确保保存所有适当的状态数据而不会浪费时间不必要地保存寄存器(即保存在 ISR 中未修改的寄存器,因此不需要保存)。一个非常简单的 ISR 可能不需要使用任何寄存器,另一个 ISR 可能只需要使用一个或两个寄存器,而更复杂的 ISR 可能需要使用大量寄存器。在任何情况下,ISR 都应该只保存和恢复它实际使用的那些寄存器。

关于功能与中断调用中的上下文切换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25088639/

相关文章:

java - 关于java中的中断

windows - gcc 和 lccwin32 :different result

c - Travis CI如何添加C库?

c - 通过引用和指针传递

c - 了解从二叉搜索树中删除节点的递归调用

php - 错误报告因解析错误而被阻止

linux - debian init.d 脚本在重启后不运行

C# Winforms 线程 - 延迟子表单事件直到表单关闭

android - 如何运行使用内部类的线程?

c - 如何处理 "warning: ignoring return value of ‘system’ , "