原来定时器中断是个伪中断

为什么是伪中断


      在讲主题之前,我们先用一个例子来回顾一下中断的相关概念。假设你正在阅读或者工作,这时候你的朋友突然给你打电话或者发短信,请求你帮助他解决一个问题,之后你给朋友提了些许建议就继续自己的阅读或者工作了。

       在上面这个例子中,这个请求就相当于嵌入式系统中的中断请求。你此时需要停止你手头的任务,回答你朋友的问题,这就相当于中断处理程序的执行过程。当你回答完朋友的问题后,你会回到之前的任务中,继续完成你手头的工作,这就相当于嵌入式系统返回到之前被打断的程序中,继续执行原来的操作。

       通过以上例子的比对,通常我们认为中断是执行程序中意料之外的任务,而主程序是执行意料以内的任务。不过在编程的世界中,没有真正意义上的意料之外,如果有些问题的出现对于程序来说是意料之外,只能说是代码的健壮性不够,这是问题,是 BUG。中断的这种意料之外是对与程序执行而言的,基于某些情况虽然可以被确定,但是在时序与顺序的发生上不可被预知

       回到正题,有了上面的思考,定时器中断还能称为中断吗?定时器中断是指间隔时间内触发中断事件,执行既定操作。从它的执行过程来看,它周期的去执行一些确定性任务,并不是因为某些意料以外的信号来触发,从这点来看,这是一种在时间上的同步行为,可被预测的,所以从本质上来说定时器中断算不上真正意义上的中断,只能说是伪中断

 

为什么要有伪中断



      定时器的伪中断本身有何意义,它的存在究竟意欲何为呢?这就需要引入一对双胞胎——并行并发。这两个概念一般在操作系统相关的主题中提到的比较多,不过这里大家不必要理解很深。并行是指在同一时刻,处理多个任务或数据,这些任务同时在不同的处理器或核心中执行。单核的处理器不能实现实现并行,并行是多处理器的权限,但是单核心可以通过并发来实现伪并行。并发是在一个时间段内,处理多个任务或者数据,这些任务交替执行,看起来好像同时进行。在单核芯片中采用并发诸多优势,这样做一方面可以充分发挥处理器的性能,另一方面可以更好应对比较复杂的应用场景。

      继续回到定时器中断,它可以看做定时器中断中的程序与主程序中程序的交替运行,提供了一条与主程序平行的工作流。到这里这我们终于揭开了定时器中断的庐山真面目,定时器中断的底层逻辑就是并发。理解了定时器中断的本质是并发其实很多东西都明朗了,我们就可以用并发的思路来做开发,这在一定程度上统一了带有操作系统的并发编程,扩展了我们的思路。不过两者在并发的实现,运行等许多方面有一定的差距,那么之前我们给定时器中断脱完衣服发现了并发的基本逻辑,现在我们再给定时器中断穿回其带有其个性的衣服以让我们更好把它运用到实践中去。

     有了定时器中断后,我们可以把一个定时器周期的时间单独拉出来看。一个周期的中断时间可以分为两部分,一部分时间属于定时器中断程序,另一部分属于主程序。由于中断程序天生执行的优先级就高于主程序,因此在代码的编写过程中需要注意双方程序时间占比,防止定时器程序对主程序的压榨,或者说一个定时器周期都不能完成定时器本身的代码执行。通常单纯裸机的代码结构比较简单,裸机提供的这种并发方式在响应时间、优先级等许多方面可能并不完美,但是也能很好的处理许多场景,尤其是在有周期性任务的场景。

 

存在即合理



      通过上面的探讨我们知道定时器中断本身就是为了服务于裸机中的并发需要,那么为什么要用定时器中断而不是其它方式来实现呢?在我看来定时器和中断这两个工具缺一不可。如果要实现并发,就必须要有程序的切换,但是C语言本身并没有提供这种功能,只有通过中断来完成这个过程。那是否可以绕过定时器来实现呢?并发需要系统选择一个时机进行程序的切换,时机怎么选,怎么分配都是个问题,绕过定时器往往需要书写更加冗杂的切换场景代码,对于资源本就不富裕的MCU来说是个不小的负担。另外对 CPU资源的使用单位本就是用时间来计量,直接使用定时器简直是得天独厚。

     由于一些任务学习的原因,时隔两年再次拿起了32单片机,看着沉金的板子心中有说不出的小激动。之前在学习裸机过程中我对于主程序、中断与定时器中断只知道用法,总是浑浑噩噩的使用,在有了嵌入式Linux的基础后,总算把这块的内容统一起来了。技术工具很多,裸机的定时器中断,操作系统的多线程、多进程等等,虽然工具是变的,但是内在的底层逻辑却是一模一样,找到这些底层逻辑,熟练地掌握它们是个不错的学习方向。在思考的过程中也要感谢我的嵌入式设计老师,让我们本着存在即合理的态度,通过对比来思考事物存在的意义与作用。

posted @ 2023-03-27 18:47  Spark++  阅读(204)  评论(0编辑  收藏  举报