中断是用以提高计算机工作效率、增强计算机功能的一项重要技术。最初引入硬件中断,只是出于性能上的考量。如果计算机系统没有中断,则处理器与外部设备通信时,它必须在向该设备发出指令后进行忙等待,反复轮询该设备是否完成了动作并返回结果。这就造成了大量处理器周期被浪费。
其实这里面主要涉及到了软件开发中同步和异步概念。
这里我们以定时器为例。假设我们需要开一个1s的定时器。
- 定时器模块是独立工作的,它和CPU有一段共享的RAM空间,方便他们进行数据传递,在本系列文章第一篇MCU和外设中有详细解释。
- 既然定时器是独立工作的,我们做一个类比
- 你在宿舍看电视,到了饭点,叫了外卖。
- 你自己看电视,相当于主循环,是你自己在做,相当于CPU
- 外卖系统相当于定时器,是其他在做,相当于定时器模块
- 这两部分是完全分别独立工作的。
- 你不停的打电话问,快递到了么,是轮询,这样你电视就干不成了。
- 他到了,打你电话,这叫中断,但这个电话你必须听到。
- 电话铃响,你暂停电视叫保护现场,去去开门,吃饭,叫中断处理,吃完饭,继续看电视,叫恢复现场,这是中断处理函数。
- 你暂停电视(保护现场),每隔两分钟打一次电话问外卖是否到了(不需要保护现场了),吃过饭,继续看电视(恢复现场),这是轮询过程。
在上面的类比中,我们很明显的能够感受到,中断的效率是高的,但是这需要你必须能够接到快递小哥给你的电话,你的电话不能欠费。在单片机中,我们需要有一套中断系统,来做这件事,这样的话,中断系统需要做到几点
- 改变CPU的执行流,即强行改变PC寄存器的值。
- 保护现场,需要和中断函数合作,但在单片机C语言编程中,编译器帮你完成了相当一部分工作。
- CPU级别的现场保护,在coretxM3中,他提供了PSP和MSP两个栈寄存器,您可以阅读相关文章详细了解
- 编译器帮你完成的现场保护,您可以结合单片机的C语言一文,思考一下,编译器是怎么保护现场的。
- 你自己需要做到的现场保护,主要指全局变量的处理,多为一些flag标记。
我们知道中断函数要保护现场,可为什么不能有参数呢呢?
- 外设和CPU是两个独立的构件。
- 函数调用是正常的CPU执行流程,前面准备参数,接着调用,而中断并不知道什么时候会来
- 中断函数,是非常特殊的一类函数,编译器也为他做了特殊的准备。他不是被调用的,他是外设硬生生的改变了PC寄存器的值
- 中断需要的参数,一般来说都是外设产生的,和CPU不是一个系统,根本没有办法按照普通的传递参数的方法传递。
- 中断函数需要的参数,是通过外设和CPU那一段共享的RAM来传递的,也就是我们理解的外设寄存器。