【无标题】

1.任务的基本概念
      RTOS 系统的核心就是任务管理,FreeRTOS 也不例外,而且大多数学习 RTOS 系统的工程 师或者学生主要就是为了使用 RTOS 的多任务处理功能,初步上手 RTOS 系统首先必须掌握的 也是任务的创建、删除、挂起和恢复等操作,由此可见任务管理的重要性。

2.什么是多任务系统?
       回想一下我们以前在使用 51、AVR、STM32 单片机裸机(未使用系统)的时候一般都是在 main 函数里面用 while(1)做一个大循环来完成所有的处理,即应用程序是一个无限的循环,循 环中调用相应的函数完成所需的处理。有时候我们也需要中断中完成一些处理。相对于多任务 系统而言,这个就是单任务系统,也称作前后台系统,中断服务函数作为前台程序,大循环 while(1)作为后台程序,

 前后台系统的实时性差,前后台系统各个任务(应用程序)都是排队等着轮流执行,不管你 这个程序现在有多紧急,没轮到你就只能等着!相当于所有任务(应用程序)的优先级都是一样 的。但是前后台系统简单啊,资源消耗也少啊!在稍微大一点的嵌入式应用中前后台系统就明 显力不从心了,此时就需要多任务系统出马了。 多任务系统会把一个大问题(应用)“分而治之”,把大问题划分成很多个小问题,逐步的把 小问题解决掉,大问题也就随之解决了,这些小问题可以单独的作为一个小任务来处理。这些 小任务是并发处理的,注意,并不是说同一时刻一起执行很多个任务,而是由于每个任务执行 的时间很短,导致看起来像是同一时刻执行了很多个任务一样。多个任务带来了一个新的问题, 究竟哪个任务先运行,哪个任务后运行呢?完成这个功能的东西在 RTOS 系统中叫做任务调度 器。不同的系统其任务调度器的实现方法也不同,比如 FreeRTOS 是一个抢占式的实时多任务 系统,那么其任务调度器也是抢占式的,,运行过程如图
 

图中高优先级的任务可以打断低优先级任务的运行而取得 CPU 的使用权,这样 就保证了那些紧急任务的运行。这样我们就可以为那些对实时性要求高的任务设置一个很高的 优先级,比如自动驾驶中的障碍物检测任务等。高优先级的任务执行完成以后重新把 CPU 的使 用权归还给低优先级的任务,这个就是抢占式多任务系统的基本原理。

 3.任务状态迁移
FreeRTOS 系统中的每一个任务都有多种运行状态,他们之间的转换关系是怎么样的呢? 从运行态任务变成阻塞态,或者从阻塞态变成就绪态,这些任务状态是如何进行迁移?下 面就让我们一起了解任务状态迁移吧,

(1):创建任务→就绪态(Ready):任务创建完成后进入就绪态,表明任务已 准备就绪,随时可以运行,只等待调度器进行调度。

(2):就绪态→运行态(Running):发生任务切换时,就绪列表中最高优先级 的任务被执行,从而进入运行态。

(3):运行态→就绪态:有更高优先级任务创建或者恢复后,会发生任务调度, 此刻就绪列表中最高优先级任务变为运行态,那么原先运行的任务由运行态变为就绪态, 依然在就绪列表中,等待最高优先级的任务运行完毕继续运行原来的任务(此处可以看做 是 CPU 使用权被更高优先级的任务抢占了)。

(4):运行态→阻塞态(Blocked):正在运行的任务发生阻塞(挂起、延时、 读信号量等待)时,该任务会从就绪列表中删除,任务状态由运行态变成阻塞态,然后发 生任务切换,运行就绪列表中当前最高优先级任务。

(5):阻塞态→就绪态:阻塞的任务被恢复后(任务恢复、延时时间超时、读 信号量超时或读到信号量等),此时被恢复的任务会被加入就绪列表,从而由阻塞态变成 就绪态;如果此时被恢复任务的优先级高于正在运行任务的优先级,则会发生任务切换, 将该任务将再次转换任务状态,由就绪态变成运行态。

(6) (7) (8):就绪态、阻塞态、运行态→挂起态(Suspended):任务可以通 过调用 vTaskSuspend() API 函数都可以将处于任何状态的任务挂起,被挂起的任务得不到 CPU 的使用权,也不会参与调度,除非它从挂起态中解除。

(9):挂起态→就绪态:把 一 个 挂 起 状态 的 任 务 恢复的 唯 一 途 径 就 是 调 用 vTaskResume() 或 vTaskResumeFromISR() API 函数,如果此时被恢复任务的优先级高 于正在运行任务的优先级,则会发生任务切换,将该任务将再次转换任务状态,由就绪态 变成运行态。

 4.任务状态的概念
FreeRTOS 系统中的每一任务都有多种运行状态。系统初始化完成后,创建的任务就可 以在系统中竞争一定的资源,由内核进行调度。

任务状态通常分为以下四种:

 1.就绪(Ready)
该任务在就绪列表中,就绪的任务已经具备执行的能力,只等 待调度器进行调度,新创建的任务会初始化为就绪态。

2. 运行(Running)
该状态表明任务正在执行,此时它占用处理器,FreeRTOS 调 度器选择运行的永远是处于最高优先级的就绪态任务,当任务被运行的一刻,它 的任务状态就变成了运行态。

3.阻塞(Blocked)
如果任务当前正在等待某个时序或外部中断,我们就说这个任 务处于阻塞状态,该任务不在就绪列表中。包含任务被挂起、任务被延时、任务 正在等待信号量、读写队列或者等待读写事件等。

 4.挂起态(Suspended)
处于挂起态的任务对调度器而言是不可见的,让一个任务进 入挂起状态的唯一办法就是调用 vTaskSuspend()函数;而 把 一 个 挂 起 状态 的任 务 恢复的 唯 一 途 径 就 是 调 用 vTaskResume() 或 vTaskResumeFromISR()函 数,我们可以这么理解挂起态与阻塞态的区别,当任务有较长的时间不允许运行 的时候,我们可以挂起任务,这样子调度器就不会管这个任务的任何信息,直到 我们调用恢复任务的 API 函数;而任务处于阻塞态的时候,系统还需要判断阻塞 态的任务是否超时,是否可以解除阻塞。

5.常用的任务函数讲解
1.任务挂起函数   vTaskSuspend()
     挂起指定任务。被挂起的任务绝不会得到 CPU 的使用权,不管该任务具有什么优先级。 任务可以通过调用 vTaskSuspend()函数都可以将处于任何状态的任务挂起,被挂起的 任务得不到 CPU 的使用权,也不会参与调度,它相对于调度器而言是不可见的,除非它从 挂起态中解除。

2.vTaskSuspendAll()
        这个函数就是比较有意思的,将所有的任务都挂起,其实源码很简单,也很有意思, 不管三七二十一将调度器锁定,并且这个函数是可以进行嵌套的,说白了挂起所有任务就 是挂起任务调度器。调度器被挂起后则不能进行上下文切换,但是中断还是使能的。 当调 度器被挂起的时候,如果有中断需要进行上下文切换, 那么这个任务将会被挂起,在调度 器恢复之后才执行切换任务。

3.任务恢复函数     vTaskResume()
       既然有任务的挂起,那么当然一样有恢复,不然任务怎么恢复呢,任务恢复就是让挂 起的任务重新进入就绪状态,恢复的任务会保留挂起前的状态信息,在恢复的时候根据挂 起时的状态继续运行。如果被恢复任务在所有就绪态任务中,处于最高优先级列表的第一 位,那么系统将进行任务上下文的切换。

4.任务删除函数   vTaskDelete()
     用于删除一个任务。当一个任务删除另外一个任务时,形参为要删除任 务创建时返回的任务句柄,如果是删除自身, 则形参为 NULL。 要想使用该函数必须在 FreeRTOSConfig.h 中把 INCLUDE_vTaskDelete 定义为 1,删除的任务将从所有就绪,阻塞, 挂起和事件列表中删除。

5.任务延时函数    vTaskDelay()
       vTaskDelay()在我们任务中用得非常之多,每个任务都必须是死循环,并且是必须要有 阻塞的情况,否则低优先级的任务就无法被运行了。要想使用 FreeRTOS 中的 vTaskDelay() 函数必须在 FreeRTOSConfig.h 中把 INCLUDE_vTaskDelay 定义为 1 来使能。

6.vTaskDelayUntil()
      在 FreeRTOS 中,除了相对延时函数,还有绝对延时函数 vTaskDelayUntil(),这个绝 对延时常用于较精确的周期运行任务,比如我有一个任务,希望它以固定频率定期执行, 而不受外部的影响,任务从上一次运行开始到下一次运行开始的时间间隔是绝对的,而不 是相对的。

任务创建方法我在上一篇已经介绍过了这里不再赘述了


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值