FreeRTOS任务状态与优先级

本文详细解析了FreeRTOS中的多任务调度机制,包括时间片和非时间片抢占式调度,以及任务的不同状态(就绪、运行、阻塞、挂起和空闲),帮助读者掌握这一操作系统的关键特性。
摘要由CSDN通过智能技术生成
1多任务基本运行机制:

在单核处理器上,任何时刻只能有一个任务占用CPU并运行,RTOS的任务调度使得多个任务对CPU实现了分时复用功能。

在一个时间片内会有一个任务占用CPU并执行,在一个时间片结束时(实际上时基础是中定时器发生中断时)进行任务调度。当多个任务的优先级不同时,FreeRTOS还会使用基于优先级的抢占式任务调度方法。

优先级数字越小表示优先级越低。

当一个任务的时间片完成后,他就会将CPU的当前场景保存下来,也就是CPU各个核心寄存器的值,压入自己的空间,然后另一个任务接管CPU的使用权。此时task2就会用自己栈空保存的数据恢复CPU场景,因此得以继续在上次的状态运行。

因为时间片很短,默认时1ms,所以在用户看来,多个任务都是在同一个时间运行。

2任务的状态:
2.1就绪状态:

任务创建之后就处于就绪装填,根据抢占式任务调度的特点,任务调度的结果可以有一下几种状态:

2.1.1如果当前没有其他任务处于运行转台,就绪任务会立即进行运行状态;

2.1.2如果就绪任务的优先级高于或等于当前任务的优先级,就绪任务的就进入运行状态;

2.1.3如果就绪任务的优先级低于当前运行的任务,就绪的任务继续处于就绪状态。

2.2运行状态:

当有CPU并运行的任务就处于运行状态。处于运行状态的任务在空闲的时候就会让出CPU的使用权。处于运行状态的任务有两种方式主动让出CPU的使用权:

2.2.1执行函数vTaskSuspend()进入挂起状态;

2.2.2执行阻塞类函数进入阻塞状态,运行任务交出CPU使用权后,任务调度器就可以使其他就绪任务进入运行状态。

2.3阻塞状态:

阻塞装填就是任务暂时让出CPU的使用权,处于一种等待的状态。运行的任务可以调用辆类函数进入阻塞状态。

2.3.1时间延迟函数,如vTaskDelay();

2.3.2用于进程间通讯的事件请求xSemaphoreTake()。

3.挂起状态:

挂起状态的任务就是暂停任务,挂起状态的任务不参与调度器的调度。其他3种任务都可以通过调用函数vTaskSuspend()进入挂起状态,挂起后的状态不能自动推出挂起状态,需要在其他任务中调用vTaskResume()函数使其解除挂起状态。

4.空闲任务:

osKernelStart()启动FreeRTOS的任务调度器时,会自动创建一个空闲任务,空闲任务的优先级为为0。与空闲任务相关的几个主要配置参数是:

3.1 configUSE_TICK_HOOK:是否使用空闲任务的回调函数,若配置为1,则可以利用空闲任务的回调函数,系统空闲时做一些其他的处理;

3.2 configIDLE_SHOULD_YIELD:空闲任务是否对同优先级用户任务主动让出CPU使用权,这会影响任务结构。

3.3 configUSE_TICKLESS_IDLE:是否在空闲任务时关闭基础定时器时钟,若设置为1,可实现系统的低功耗。

5.任务调度方式:

FreeRTOS有两种任务调度算法,基于优先级的抢占式,和合作式调度,其中抢占式调度算法又可以使用时间片或不使用时间片。

6.使用时间片的抢占式调度方式:

FreeRTOS基础时钟的一个定时周期称为一个时间片,默认值为1ms。当使用时间片时,在基础时钟的每次中断里会要求进行一次上下文切换,,函数xPortSysTickHandler()就是systick定时中断的处理函数。

在低优先级任务运行时,高优先级的任务总是能够抢占获得CPU的使用权,那在没有其他任务运行时呢,空闲任务就处于运行状态,否则就处于堵塞状态,如果多个任务的优先级相同且处于就绪状态,那么他们就会轮流获得CPU的使用权。

7.不使用时间片的抢占式调度方法:

是哟ing时间片的抢占式调度方法在每个systick中断里都进行一次上下文切换请求,从而进行任务调度只是对于相同优先级的任务不再使用时间片,平均分配CPU时间。不使用时间片的抢占式调度只在以下情况下才进行任务调度:

7.1 有更高级别的任务进入就绪状态时;

7.2 运行状态的任务进入阻塞状态或挂起状态;

所以,不使用时间片时,进行上下文切换的频率比使用时间片时低,从而降低CPU的负担。但是,对于同优先级的任务,可能会出现占用CPU时间相差很大的情况。

8.合作式任务调度方法:

使用合作式调度方法时,FreeRTOS不主动进行上下文切换,而是运行状态的任务进入阻塞状态,或显示地调用taskYIELD()函数让出CPU使用权时才进行上下文切换。

任务也不会发生抢占,所以也不使用时间片。

函数taskYIELD()的作用就是主动申请进行一次上下文切换。

  • 13
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值