关于中断的一点点认识
前一段时间,有幸和都江堰操作的作者面对面的聊了一把。对于前辈的技术和才能,晚辈深深地佩服。DJY_OS在应用方面的事件机制以及处理中断的方法都让人眼前一亮。在谈到中断时,前辈说,很多人都没有真正的理解中断。于是我就请教了前辈。他说:
“http://www.djyos.com/bbs/forum.php?mod=viewthread&tid=6082&extra=page%3D1
1、 中断是异步事件。
2、 中断不一定是紧急事件。
3、 紧急事件必须用中断来通知。
关键是这三句话。”
其实,我听了以后,还是有点迷糊。第一什么是异步事件?Google一下,异步事件是指计算机外部产生的,同计算机内执行的任务在时间上不相关联的事件。(http://define.cnki.net/WebForms/WebDefines.aspx?searchword=%E5%BC%82%E6%AD%A5%E4%BA%8B%E4%BB%B6)
那么这里有个疑问了,软中断是由软件出发的,一般用于呼叫系统服务。这时应用程序必须等待系统服务完成后才能从软中断处继续执行。显然,这种事件不满足这个异步事件的定义,那么它还算是中断吗?也许前辈只是借用了异步事件的术语,指得其它的东西。疑惑促使我去思考这些问题。
中断系统一直困扰着我。我不明白中断和任务最本质的区别。这里先提一下调度,调度的本质是分配CPU的时间。即分配CPU的计算时间给每一个需要计算的任务(线程)。中断发生以后,需要执行中断服务程序(ISR)。ISR显然也有一些任务(线程)的影子。
有一些新CPU,如Cortex-M3之类的,有NVIC,中断控制器。不需要软件做栈的保护(它自己可以做),上电以后初始化栈后,它自己就可以正常工作了。支持背靠背执行ISR。其他处理器上的系统都是执行完了ISR后,再执行一条非ISR指令,防止频繁执行ISR造成前台程序饿死。背靠背的意思是ISR执行完毕后,直接执行另外一个ISR,不执行任何前台代码。这有个好处,没有用户程序的压栈出栈,现场保护。速度快了很多。缺点就是,如果中断很多的话,前台程序得不到执行(不过这个效应应该不明显)。
所有这些,让我想到,中断控制器实际上不就是个带优先级别支持抢占的硬件调度器吗?:),事实的确如此。一个高优先级的ISR不退出的话,低优先级的ISR是得不到服务的。低优先级的ISR在服务时,发生高优先级的ISR,那么直接就被抢占了。我们用关闭中断,实际上就是关闭硬件的调度器。而操作系统(OS),从这个硬件调度器来看,实际上相当于空闲任务(或进程)。当系统没有ISR运行的时候,自然运行空闲任务,也就是操作系统的(OS)。这么一看,这是多么的与抢占式的软件调度器吻合。
硬件只提供了一个抢占式的调度器,并未在此基础上提供丰富的系统调用,诸如信号量、互斥体等等API。而软件调度器是我们真正想要的东西。软件提供了各种各样的同步、通信API。用以管理系统内部的资源。一山容不得二虎,必须有一个主一个从。软件调度器作为我们需要的主流,硬件调度器自然退为二线,默默支持着主调度器。
从硬件调度器的角度去观察,衍生出很多有力的解释:
1.既然硬件调度器被抑制,那么要以主调度器为主。中断ISR应尽可能做最少的事情。尽量不影响主调度器的工作。
2.硬件调度器是个基于优先级的抢占内核,而OS运行在最低优先级。在ISR里不能调用阻塞的函数。调用了,整个系统就崩溃了。或者说发生了优先级反转,但硬件调度器没有提供这个功能。只能是死锁或者是长时间的等待。
3.硬件调度器使用的栈(包括ISR)应该是和操作系统在一个数据空间里。因为硬件调度器高于软件调度器,即软件调度器只能是停止硬件调度器调度,但无法介入这一调度过程。硬件调度器可没有提供诸如MMU切换之类的功能。
4.对于资源的拥有性上来说,操作系统(软件调度器)接管了所有的资源,甚至它把中断也当成了一种资源。对于硬件调度器,它只能拥有最基本的可以使程序运行的资源。即一点点内存+CPU的时间。内存是软件调度器与之分享的,由操作系统全权接管。
...
一点点拙见,大家拍砖。
-----------------------------------
DJYOS作者,罗大哥的指教: