freeRTOS小结——中断管理

概述

本章所述中断管理主要是针对中断处理程序的管理。

RTOS中,中断处理程序由用户自定义,是类似于TASK一样的存在,中断处理程序有自己的栈,可以支持低优先级中断处理程序被高优先级中断处理程序打断。实际上,个人认为TASK就是以中断处理程序为原型演进而来。

考虑到OS的很多功能,如时间片机制、TASK切换(后边将会讲到)都是基于中断处理程序来完成的。

如之前所述,中断处理程序具有比常规用户指令集合更高的处理优先级,当中断发生时,CPU会立即执行中断处理程序。TASK就处于常规用户指令集合之中,因此中断发生时,TASK必然被中断处理程序打断,如下图所示,

freeRTOS小结——中断管理

其中,

·           t1时刻,TASK 1开始在CPU上执行

·           t2时刻,CPU检测到中断,开始执行中断处理程序

·           t3时刻,中断处理程序执行完成,CPU在切换回TASK 1继续执行

 

中断嵌套

某些嵌入式系统中,支持低优先级中断处理程序被高优先级中断处理程序打断,即为中断嵌套,如下图所示,

freeRTOS小结——中断管理

其中

·           t1时刻,TASK 1开始在CPU上执行

·           t2时刻,CPU检测到中断1,开始执行其对应的 中断处理程序

·           t3时刻,CPU检测到中断2,由于其优先级较高,开始执行其对应的 中断处理程序

·           t4时刻,CPU完成中断2的中断处理程序,恢复执行中断1的中断处理程序

·           t5时刻,CPU完成中断1的中断处理程序,恢复执行TASK1

 

基于中断的任务切换

大部分的RTOS中,都使用基于中断的TASK切换方式:

·           当TASK需要触发TASK切换时,其触发产生一次中断(记为SWI),SWI的中断处理程序即为包含压栈、出栈的任务切换处理过程。

·           当中断处理程序需要触发TASK切换时,可在中断处理程序执行过程中,将出栈处理恢复的寄存器直接替换为新切换TASK的寄存器

这样做的好处在于保证TASK切换不会中断处理程序打断导致异常。

此时TASK切换过程如下图所示,

freeRTOS小结——中断管理

当然,这并非唯一方式,任何能够保证TASK切换正常执行的方式也是可行的 :如TASK触发的TASK切换,可以采用后边提到的临界区机制;又如对于不支持中断嵌套的系统,以上两种情况都可采用直接触发switch interrupt的方式。

 

基于中断的时间片机制

时间片机制,即外部的硬件定时器周期性地向CPU发送一个中断(记为TickINT),该中断的ISR即OS的时间片处理过程:尝试进行TASK切换并统计OS的状态信息。

如下图所示

freeRTOS小结——中断管理

其中,

·           t1~t2时间段,TASK 1在CPU上执行

·           t2时刻,时间片超时,OS发现存在更高优先级的TASK2,因此触发TASK切换,切换到TASK 2

·           t2~t3时间段,TASK 2在CPU上执行

·           t3时刻,时间片超时,OS发现没有更高优先级的TASK,不触发TASK切换

其中的TASK切换过程细节可参考之前提到的ISR触发的TASK切换过程。

 

中断处理程序

由于ISR的特殊性(ISR优先于TASK执行,且部分OS功能如时间片和TASK切换基于ISR实现),freeRTOS为ISR设计了一套特殊的API函数,即后缀为“FromISR”的API函数,以保证ISR在使用API时不会出现异常,如下表所示(其中只给出了常用的部分),

功能

TASK使用API

ISR使用API

触发TASK切换

portYIELD

portYIELD_FROM_ISR

发送消息

xMessageBufferSend

xMessageBufferSendFromISR

接收消息

xMessageBufferRecv

xMessageBufferRecvFromISR

获取互斥信号量

xSemaphoreTake

xSemaphoreTakeFromISR

释放互斥信号量

xSemaphoreGive

xSemaphoreGiveFromISR

获取信号量

xSemaphoreTake

xSemaphoreTakeFromISR

释放信号量

xSemaphoreGive

xSemaphoreGiveFromISR

 

它们的区别再去,TASK使用API会立即尝试触发TASK切换,而ISR使用API只会返回一个BOOL值,指示是否需要触发TASK切换——ISR触发的TASK切换需要在其执行完成后在进行。