FREERTOS学习笔记,中断管理一

中断与任务

这里中断指的是硬件中断,优先级最低的硬件中断都会抢占优先级最高的任务进程。所以硬件中断的中断函数应尽可能地短,否则会影响任务进程。

中断专用应用接口函数(API)

在FREERTOS中,由于任务中调用的API接口函数许多时候需要进入阻塞状态,而硬件中断处理函数应尽可能短,故任务中调用的API函数不适用于硬件中断。故,在FREERTOS中采用了将二者的API接口函数分开的方式,任务中不可调用硬件中断API函数,硬件中断中也不应调用任务相关的API函数。在定义函数中,与中断相关API函数都加有“FromISR”的扩展。中断中调用的函数名一定要含有“FromISR”。

xHigherPriorityTaskWoken参数相关

若中断触发了上下文开关,则进入中断时执行的任务与退出中断后执行的任务不一致(中断结束后触发了任务调度函数,从而更改其他任务)。在抢占模式下
1,若任务调用API函数使得另一个高优先级任务退出阻塞态,此时高优先级任务会直接抢占此时正在执行的低优先级任务。
2,若硬件中断处理函数调用API函数使得一个高优先级任务退出阻塞态进入就绪态,由于硬件中断优先级最高,故高优先级任务并不会抢占硬件中断函数,但硬件中断函数执行完之后需要调用任务调度函数来调度高优先级任务来执行,而xHigherPriorityTaskWoken参数就是为了这个目的,当有高优先级时需要任务调度时xHigherPriorityTaskWoken将被置为pdTRUE,表示需要任务调度。需要注意的是该参数在第一次使用之前需要置为pdFALSE。硬件中断函数中调用的API函数中需要对xHigherPriorityTaskWoken置pdTRUE以便快速切换任务,若不实施该操作会使得高优先级任务在下一次任务调度时才运行。若没有高优先级任务则尽量不要置为pdTRUE,因为若中断频繁会导致任务频繁切换,影响任务正常运行。故该功能为可选功能,若不用应置为NULL

宏portYIELD_FROM_ISR() and portEND_SWITCHING_ISR()

在任务中调用宏taskYIELD() 来请求上下文开关即任务调度器。在中断中应使用上面两种宏,这两种宏功能完全一致,有时仅提供一种。函数原型如下:

portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );

若portYIELD_FROM_ISR( xHigherPriorityTaskWoken )的输入参数为pdFALSE,则中断结束后并不会调用任务调度函数。若输入参数为pdTRUE,则在中断结束后会调用任务调度函数调度任务执行。
对于大部分系统,该函数可以放在中断处理函数中任意位置,一小部分规定必须放在中断处理函数结尾。

推迟中断进程

中断服务程序必须记录中断产生的原因,并清楚中断标志。任何一个中断运行必需的进程一般经常在任务中执行。这样就可以使得中断服务程序快速推出。这个方法就叫做推迟中断进程。因为中断必需函数在之后的任务中执行了。

推迟中断的原因,若中断处理函数较长,会导致影响正常任务的运行,使得任务执行时间抖动较大,不利于任务执行。

将中断进程推迟到任务中执行可以使得应用层按顺序处理相关内容。也可以使用所有任务相关API函数。
在这里插入图片描述
如图,任务2即为推迟后的中断进程,当中断ISR结束后,马上会跳转到高优先级的任务二来执行中断相关函数。结束后任务一接着执行。

用于同步的二进制信号量

二进制信号量API的中断安全版本可以使得当任意时间一个特定中断触发后,将一个阻塞任务退出阻塞状态,有效的同步任务与中断。这可以使得大部分的中断事件进程在任务中执行。仅保留一小部分快速执行的程序在中断函数中。二进制信号量就是为了将中断进程推迟到任务中。

如果一个中断是对时间要求严格的,那么推迟中断任务应设置一个比较高的优先级,并且在中断处理函数中应调用portYIELD_FROM_ISR(),使得在中断结束后马上调用推迟中断任务。这样就可以保证整个事件进程就像在同一个时间段内执行。

当中断推迟任务执行完后就可以采用拿走信号量(Taking a semaphore)模式进入阻塞状态,继续等待下一次中断来临。当下一次中断到来后中断函数给与一个信号量(giving a semaphore),之后任务又可从阻塞态进入就绪态。

‘Taking a semaphore’ 与‘giving a semaphore’ 在不同情况下有着不同的定义,在上述同步情况下,二进制信号量可以描述为一个长度为一的队列,在任何时间队列最多可含有一个数据,所以该队列总是处于空或满两种状态。通过调用xSemaphoreTake(),推迟中断进程将会进入阻塞读取队列状态,当队列为空时,任务进入阻塞态,当中断发生后,中断函数调用xSemaphoreGiveFromISR()将信号量放到队列中,使得队列状态为满,这会使得任务退出阻塞态进入就绪态。并且移除队列中的信号量,使得队列再次变为空,当任务完成进程后会再次阻塞读取队列。。。

相关接口函数

xSemaphoreCreateBinary()
创建一个类型为SemaphoreHandle_t的信号量,函数原型如下所示:

SemaphoreHandle_t xSemaphoreCreateBinary( void );

返回值:NULL表示内存不足创建失败。非NULL则表示创建成功。

xSemaphoreTake()
取走信号量,可以取走除了递归互斥体外的所有类型信号量。它不可被中断服务函数调用,函数原型如下:

BaseType_t xSemaphoreTake( SemaphoreHandle_t xSe
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值