12.FreeRTOS之中断中API的使用

一.两类API对比
FreeRTOS有两套函数,一套是普通中,一套是在中断中使用的(在中断中使用的API在函数名的尾部都有FromISR),中断中使用的FreeRTOS的API有什么特殊点呢?1: 执行速度尽可能快,尽可能减小对操作系统实时性的影响 2:不能阻塞,因为中断是单片机硬件本身的操作,可不受FreeRTOS的调度,一旦阻塞(比如等待信号量),而中断中的内容不会被调度器调用,此时程序就卡死了。
二.以写队列为例对比两类API
详细内部软件流程
附件链接
1.普通任务写队列执行过程:
(1)当队列没满的时候写入队列,如果有任务在等待接收队列数据,那就把这个任务唤醒,如果这个任务优先级比当前高,那就发起一次调度
(2)当前队列满但是写队列等待时间为0,那就直接返回错误
(3)当前队列满,且写队列等待时间不为0,那就把当前任务从readylist中移除,同时添加到delayList里去,任务阻塞
2.中断写队列执行过程
 (1)函数参数里没有等待时间,即不允许写队列等待(保证不在中断中发生阻塞)
 (2)当队列没满的时候写入队列,如果有任务在等待接收队列数据,那就把这个任务唤醒,如果这个任务优先级比当前高,不发起调度,但是把需要发起调度的变量设置为 pdTRUE
3.中断中写队列使用方法举例
void xxx_ISR()//某中断响应函数内部
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;//这边变量用来存放是否要发起调度
    xQueueSendToBackFromISR(xQueue, pvItemToQueue, &xHigherPriorityTaskWoken);//如果有高优先级任务,需要发起调度,那xHigherPriorityTaskWoken会被设为pdTRUE
    if (xHigherPriorityTaskWoken == pdTRUE)
    {
        /* 任务切换 */
        portYIELD_FROM_ISR( xHigherPriorityTaskWoken );//触发PendSV中断。由于PendSV中断中断优先级低,所以会在该中断函数执行后才会执行
    }
}
在上述xQueueSendToBackFromISR(xQueue, pvItemToQueue, &xHigherPriorityTaskWoken)中,如果因为向队列中发送数据导致有任务处于就绪态,同时该任务的优先级更高,那么xHigherPriorityTaskWoken就会被赋值为1。这个时候就可以使用portYIELD_FROM_ISR(pdTRUE)来触发上下文的切换。那portYIELD_FROM_ISR(pdTRUE)的原理是什么呢?这个函数会设置pendsv对应的bit位置1,即触发pendSV中断,在pendsv中完后任务的上下文切换。由于pendsv优先级很低,所以pendsv会在当前中断后执行。
不仅是队列操作的工作流程是这样,信号量、事件组等也是一样。互斥量不可以在中断中使用。
4.总结
在使用非ISR的API函数时,比如写队列xQueueSendToBack(),如果此时有个高优先级的任务正在等待写队列,那么前面这个xQueueSendToBack()执行过程中就会发起调度。
但是ISR的API,比如xQueueSendToBackFromISR()在相同情况下不会发起调度(因为在中断里,优先级都比pendsv高,就算发起调度,pensv也不会执行),所以这个API只是把xHigherPriorityTaskWoken这个值设置为pdTrue,然后在函数快结束的时候执行portYIELD_FROM_ISR( xHigherPriorityTaskWoken ),触发pendsv从而触发调度。
  • 19
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值