【FreeRTOS初探】中断管理

中断管理

概览

  1. 只有以“FromISR”或“FROM_ISR”结束的API函数或宏才可以在中断服务例程中。
  2. 本章内容:
    哪些FreeRTOS的API函数可以在中断服务例程中使用?
    延时中断方案是如何实现的?
    如何创建和使用二值信号量以及计数信号量?
    二值信号量和计数信号量之间的区别?
    如何利用队列在中断服务例程中把数据传入传出?
    一些FreeRTOS移植中采用的中断嵌套模型?

延迟中断处理

采用二值信号量同步

二值信号量作用二值信号量可以在某个特殊的中断发送时,让任务解除阻塞,相当于让任务与中断同步。这样,可以让中断事件处理量大的工作在同步任务中完成中断服务例程(ISR)中只是快速处理少部分工作
若某个中断处理要求特别紧急,其延迟处理任务的优先级可以设为最高,以保证延迟处理任务随时都抢占系统中的其他任务。这样,延迟处理任务就成为其对应的ISR退出后第一个执行的任务,在时间上紧接着ISR执行,相当于所有的处理都在ISR中完成一样。

这里写图片描述

获取(Taking),P()操作延时处理任务对一个信号量进行带阻塞性质的take调用→进入阻塞态以等待事件发生
给出(Giving),V()操作→当事件发生后,ISR对同一个信号量进行give操作,使得延迟处理任务解除阻塞事件在延迟处理任务中得到相应的处理。
备注:
P(荷兰语Parsseren,即英文Pass)
V(荷兰语Verhoog,即英文Increment)。
S(信号量Semaphore,相当于一个标志,代表一个资源,一个事件)
P(S)/V(S)操作时信号量的两个原子操作,原子操作如下行为:
P(S):

IF(S <= 0)THEN 将本线程加入S的等待队列
S=S-1

V(S)

S = S + 1
IF(S > 0)THEN 唤醒某个等待线程

在此中断同步的情形下,信号量可看做是一个深度为1的队列(因此队列最多只能保存一个数据单元,所以,其不为空,则为满,即为二值
延迟处理任务调用xSemaphoreTake()时←→带阻塞时间地读取队列若队列为空,任务则进入阻塞态
事件发生后,ISR通过调用xSemaphoreGiveFromISR()放置一个令牌(信号量),使得队列为满状态。这使得延迟处理任务切出阻塞态,并移除令牌,使得队列再次成为空。
当任务完成处理后,再次读取队列,发现队列为空,又进入阻塞态,等待下一次时间发生。
这里写图片描述

vSemaphoreCreateBinary() API

作用:创建二值信号
函数原型:

void vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore);

参数:
xSemaphore——创建的信号量。

xSemaphoreTake() API

作用:等同于一次P()操作,获取信号量。所有类型的信号量都可以通过调用函数xSemaphoreTake获取。
注意:xSemaphoreTake 不能在·中断服务例程中调用。
函数原型:

portBASE_TYPE xSemaphoreTake( xSemaphoreHandle xSemaphore, portTickType xTicksToWait);

参数:
xSemaphore——获取信号量;
xTicksToWait——阻塞超时时间,即任务进入阻塞以等待信号量的有效的最长时间
返回值:
pdPASS(成功获取信号量)
pdFALSE(未能获取信号量)

xSemaphoreGiveFromISR()

作用:xSemaphoreGiveFromISR是xSemaphoreGive()特殊形式,专用于中断服务例程。
函数原型:

portBASE_TYPE xSemaphoreGiveFromISR( xSemaphoreHandle xSemaphore,
portBASE_TYPE *pxHigherPriorityTaskWoken );

参数:
xSemaphore——给出信号量
pxHigherProorityTaskWoken——若调用xSemaphoreGiveFromISR()使得一个任务解除阻塞,并且这个任务的优先级高于当前任务,那么xSemaphoreGiveFromISR会在函数内部将*pxHigherProorityTaskWoken设为pdTRUE
返回值:
pdPASS
pdFAIL——信号量以有效,无法给出。

计数信号量

在中断服务例程中使用队列

中断嵌套

猜你喜欢

转载自blog.csdn.net/xiuhua_wu/article/details/79515095