中断的工作流程

网上对于中断的工作流程各有各的说法,各阶段的划分也十分模糊,再三考虑下,我还是打算以王道书中的中断流程作为参考。

1. 中断请求 

中断源是请求CPU中断的设备或事件,一台计算机允许有多个中断源。每个中断源向CPU发出中断请求的时间是随机的。

2. 中断响应判优

中断响应优先级是指CPU响应中断请求的先后顺序。当多个中断源同时提出请求时,需通过中断判优逻辑来确定响应哪个中断源的请求,中断响应的判优通常是通过硬件排队器实现的。

3. CPU响应中断的条件

CPU在满足一定的条件下响应中断源发出的中断请求,并经过一些特定的操作,转去执行中断服务程序。CPU响应中断必须满足以下三个条件:(1)中断源有中断请求。(2)CPU允许中断及开中断(异常和不可屏蔽中断不受此限制)。(3)一条指令执行完毕(异常不受此限制),且没有更紧迫的任务。(CPU在每条指令执行结束前,检查中断请求,若有,则进入中断响应阶段,又称中断周期)

4. 中断响应过程(中断周期)

CPU响应中断后,经过某些操作,转去执行中断服务程序。这些操作由硬件直接实现,我们将它称为中断隐指令。中断隐指令并不是指令系统中的一条真正的指令,只是一种虚拟的说法,本质上是硬件的一系列操作。它所完成的操作如下:(1)关中断。保证断点或现场保存的正常进行,防止被其它中断影响。(2)保存断点。保证在中断服务程序执行后能正确地返回到原来的程序。(保存PC和PSW的内容)。(3)引出中断服务程序。识别中断源,将中断的服务程序入口地址送人PC。

5. 中断处理过程(中断隐指令(1)~(3)和中断服务程序(4)~(9))

(1)关中断。

(2)保存断点。

(3)中断服务程序寻址。

(4)保存现场和屏蔽字。进入中断服务程序后首先要保存现场和中断屏蔽字,现场信息是指用户可见的工作寄存器的内容,它存放着程序执行到断点处的现行值(由操作系统完成)。

(5)开中断。允许更高级中断请求得到响应,实现中断嵌套。

(6)执行中断服务程序。这是中断请求的目的。

(7)关中断。保证在恢复现场和屏蔽字时不被中断。

(8)恢复现场和屏蔽字。

(9)开中断、中断返回。中断服务程序的最后一条指令通常是一条中断返回指令,使其返回到原程序的断点处,以便继续执行原程序。

王道视频与书上的内容不同,视频将中断流程分为三个阶段。                                                           

可以看到各小步骤基本一致,但大模块的划分有不同,视频中将中断响应分为了判优与响应条件,我个人更赞同书上的划分,因为能与中断周期的操作对的上(中断周期的操作就是中断隐指令)。

接下来看一个例题,只判断B选项:

根据书上的中断流程,很明显B选项错误,中断响应过程所作的操作为中断隐指令,由硬件实现,而中断服务程序是在中断处理过程中。但让人不解的是,A,C,D选项也是错误的。这是王道的解析:

那么问题来了,这题答案是什么?通过在网上搜索,我找到了一个一模一样的题,网上给出的答案是B选项正确,网上的各种信息也显示这题是很早以前,一本教材中的习题。那么是怎么得出这样的结论呢?个人猜测出题人将中断响应过程与程序中断过程等同,因为网上有些对中断响应过程的划分就是整个中断流程,在网上查找相关信息时,我终于找到了该题的出处: 

题中的A选项与B选项对应,但原题中说的是程序中断过程而不是中断响应过程,在王道书上也有与原题一样的题(计算机组成原理p305第6题),这也就证实了我的猜想,这个错题的原因就这么被解开了 。

  • 13
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个Arduino示例代码,通过串口指令触发外部中断,然后进入睡眠模式: ``` #include <avr/sleep.h> const int interruptPin = 2; volatile bool interruptFlag = false; void setup() { pinMode(interruptPin, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(interruptPin), ISR, FALLING); Serial.begin(9600); } void loop() { if (interruptFlag) { Serial.println("Interrupt occurred, going to sleep..."); interruptFlag = false; delay(100); // 确保串口数据发送完毕 set_sleep_mode(SLEEP_MODE_PWR_DOWN); // 设置睡眠模式 sleep_enable(); // 允许睡眠模式 sleep_cpu(); // 进入睡眠模式 // 中断唤醒后会从这里继续执行 Serial.println("Woke up from sleep."); } } void ISR() { interruptFlag = true; } ``` 在上面的代码中,我们使用attachInterrupt()函数将中断服务函数与引脚2的下降沿触发条件连接起来。中断服务函数中,我们将中断标志变量设置为真。 在主循环中,我们检查中断标志变量的值。如果它是真的,我们打印一条消息,然后将中断标志变量重置为假。接下来,我们设置睡眠模式为`SLEEP_MODE_PWR_DOWN`,允许睡眠模式并进入睡眠模式使用`sleep_cpu()`函数。当外部中断被触发时,将唤醒芯片,继续执行后续代码。 请注意,需要在睡眠模式之前等待足够的时间以确保串口数据发送完毕。同时,需要在ISR()函数中使用`volatile`关键字来确保中断标志变量可以被正确地共享。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值