ISR和函数调用之间的区别?

时间:2013-07-21 00:35:31

标签: operating-system embedded computer-architecture function-calls isr

我想了解ISR(中断服务程序)和函数调用之间的区别。

从硬件的角度来看,我觉得函数调用和ISR都是一样的。如果我错了,请纠正我。 我所能找到的有关ISR和函数调用的内容如下:

ISR:

  • 执行期间可能发生的异步事件 该计划

  • 将PC,标志和寄存器保存在堆栈中 禁用所有中断并加载ISR的地址

  • ISR不能有可传递给它的参数

  • 无法返回值
  • 启用中断
  • 通常很小,因为他们正在花时间进行其他一些过程
  • 部分ISR拥有自己的堆栈

功能:

  • 在有函数调用时发生

  • 将PC和寄存器保存在堆栈中

  • 可以有参数

  • 可以返回值

  • 对执行的大小和持续时间没有限制

除此之外还有什么区别吗?请告诉我。 我还读过关于从ISR进行函数调用的方法。请突出显示。

4 个答案:

答案 0 :(得分:3)

因此断言他们是相同的,你继续列出他们不同的方式 - 这或许可以回答你的问题。

关于ISR的前四点广泛且普遍正确。关于启用中断的要点不一定是这种情况,并且是程序员的实现决策,可能由架构决定,小​​的是指导而不是要求 - “小”完全是主观的。“

差异并不是关于它们如何被编码(尽管ISR通常会施加一些限制,也可能具有正常功能不具有的特权),而是它们如何被调用以及处理器的行为。

必须显式调用函数(或更一般的过程或子例程),并且它是与调用者相同的上下文和执行线程的一部分。硬件ISR未被显式调用,而是由某些外部事件调用(处理器内核外部 - 片上外设可能产生中断)。调用中断时,在将上下文切换到ISR之前会自动保留当前线程的上下文。返回时,反向上下文切换发生在中断之前恢复处理器的状态,以便从中断点继续执行。

由于存在多线程操作系统或调度程序,该机制可能变得复杂,因此ISR本身可能导致线程上下文切换,以便在从ISR返回时切换不同的执行线程或上下文。在这种情况下,机制由操作系统管理。

某些处理器还支持另一种ISR - 软件中断。软件中断就像函数调用一样使用,它是由指令而不是单个事件显式调用的,但提供了一种间接机制,调用者不需要知道ISR的地址,实际上该地址可能会改变。从这个意义上来说,它与通过指针调用函数没什么不同,但是因为它是一个ISR,它在中断上下文中运行,而不是调用者的上下文,所以可能有正常函数没有的限制和特权。

从根本上说,中断能够直接和确定地响应事件,否则您可能会轮询或测试事件然后处理它,但只能在您选择测试它而不是实际发生时处理它,这可能是变化的,也可能是不可接受的。

答案 1 :(得分:2)

主要区别在于(通常)外围硬件调用中断处理程序 - 外围设备生成实际硬件信号,处理器中的硬件将控制转移到适当的处理程序,而不运行的代码执行任何操作在中断之前。与函数不同,没有调用 - 执行程序被处理器硬件从被中断的代码中删除。

在支持多线程/进程的操作系统上,函数调用在与调用者相同的进程/线程上下文中进行。中断OTOH没有线程或进程上下文 - 在编辑Word文档时可能会发生由后台BitTorrent下载导致的网络中断,因此处理程序的功能受到限制。它可以向属于它所绑定的进程/线程的预分配缓冲区加载数据,它可以发信号通知信号量,它可以设置OS事件标志。就是这样。

通常,中断处理程序直接执行中断返回,因此允许执行中断的代码以继续进行任何进一步的干扰。在更简单的控制器上,比如yopur 8051,它经常在没有compex OS的情况下运行嵌入式代码,这是唯一可用的课程。使用抢占式多线程操作系统,中断处理程序还可以通过操作系统代码执行中断返回,从而导致调度程序运行。这允许中断处理程序使等待中断的线程准备好并且可能正在运行(因此可能抢占最初被中断的线程)。这使得这些系统在没有任何轮询的情况下具有良好的I / O性能。

硬件中断源我的是嵌入在处理器芯片中的外围设备 - 网络控制器,磁盘控制器,显示控制器,DMA控制器,USB控制器,intercore-comms控制器,(在具有多个内核的处理器上),定时器等或中断 - 封装上的请求引脚可用于从外部硬件源(可能是按钮,键盘,键盘或触摸屏硬件)生成中断。

答案 2 :(得分:1)

它们不一定与你在ISR的第一点上说的一样:中断是异步的,因此必须以某种方式“中断”主处理器的工作。

例如,让我们看看这个用地址修饰的MIPS代码,它没有任何用处:

4000.       add $1, $2, $3
4004.       sw $ra, 0($sp)
4008.       jal subr   # function call, sets $ra to 4012 and jumps to 4024
4012.       lw $ra, 0($sp)
4016.       jr $ra
4020.
4024. subr: sub $2, $1, $3
4028.       jr $ra

此代码可以从主处理器处理:算术运算(第1,7行)由运算单元完成,存储器控制器执行存储器访问(第2,4行),以及跳转(第3行,第5行) ,8)也由主cpu完成。 (在绑定目标文件期间设置jal的实际地址。)

这是用于函数调用。在任何时候确定代码现在在哪里以及在下一个时间点执行哪些代码(即当程序计数器递增时:PC + = 4)。

现在有了这一点,当你的功能做了一些复杂的事情,但你仍然希望软件能够对击键做出反应。然后一个所谓的协处理器发挥作用。此协处理器等待直到某些事件(如键盘上的按键)发生,然后调用中断处理程序。这是位于内存中某个地址的代码块。

请注意,处理器在上面的计算中,但与此同时,您希望在地址keys上存储击键次数。然后你编写一个从地址0x80000180开始的程序(这被定义为MIPS中的exeption处理程序地址):

lw $at, keys
addi $at, $at, 1
sw $at, keys
eret

现在击键会发生什么?

  1. 协处理器了解击键
  2. 保存主处理器的当前PC
  3. 主处理器的PC设置为0x80000180,执行中断代码
  4. 在发生中断之前,将eret PC设置为主处理器的PC
  5. 主程序的执行在那里继续。
  6. 这里有从正常执行切换到步骤2和3之间的中断处理,再从4到5的切换。

    注意:我对此进行了简化,但应该清楚,中断与函数调用有何不同,以及硬件如何具有中断处理的附加功能。

答案 3 :(得分:1)

以上答案非常完整......特别注意Clifford的软件中断。

我唯一要做的就是这个。存储在函数调用中的寄存器上下文由CPU体系结构的过程调用约定定义。这通常意味着调用者在堆栈上保存了一些东西,并且被调用者保存了一些东西并且几乎是静态集。例外:IA64具有寄存器保存/恢复的动态窗口。

在ISR上,存储的唯一寄存器上下文是将在ISR中使用的内容。如果使用一个寄存器,则只保存/恢复该寄存器。

在大多数情况下,由于过程调用约定的静态性质,函数调用中存储/恢复的寄存器集比ISR中存储/恢复的寄存器集大得多。