FreeRTOS 任务与调度器(1) (3)

FreeRTOS 任务与调度器(1)

任务B:

FreeRTOS 任务与调度器(1)

任务A中,LED端口15毫秒翻转一次

任务B中,LED端口10毫秒翻转一次

*注意:Delay_MS()是一个自定义的函数,用来模拟任务中处理其他东西浪费了5ms。
两个任务都是 TaskDelay(10毫秒) ,但是任务A中使用vTaskDelay(),在任务B中使用vTaskDelayUntil()。
在任务A中:vTaskDelay()是从调用的那一刻开始算,那么这个任务本身在Delay_MS中占用了5MS,LED翻转的时间忽略不计,那么加上vTaskDelay()的10MS,就是15MS。
在任务B中:vTaskDelayUntil()和任务本身执行时间无关,只要任务每次循环执行的总时间少于10ms,那么这个任务就是10ms执行一次了。

最后提一下xTaskAbortDelay()这个函数,根据描述,他能让正在阻塞状态等待延时的函数马上切出,进入就绪状态。但由于我的库版本比较旧,没有这个函数,所以就不作更多的介绍了。

四、开启调度器

FreeRTOS 任务与调度器(1)

4.1、函数简介:

这个函数作用是开启调度器,调用这个函数后任务就会开始执行。所以在整个程序中只需要调用一次,一般在main函数中调用就可以了。开启成功的话,系统由调度器接管了,main函数中vTaskStartScheduler()后面的代码都不会被执行。

4.2、使用简介:

官方的例子:

创建任务

开启调度器,开启后程序会跳转到vATask()任务中

FreeRTOS 任务与调度器(1)

 

五、任务的挂起和恢复

FreeRTOS 任务与调度器(1)

5.1、vTaskSuspend() 和 vTaskResume() 5.1.1、函数简介:

挂起/解除挂起单个任务:

vTaskSuspend的函数是让指定的任务进入挂起状态

xTaskResume的函数是让指定的任务从挂起状态换为就绪状态

xTaskResumeFromISR()是xTaskResume()适合在中断中调用的版本


5.1.2、使用简介
使用很简单,当不需要用某个任务的时候用vTaskResume(句柄) 把那个任务挂起,需要用的时候再打开就行了,下面是官方的例程,实现了这三步:

使用xTaskCreate()创建任务

创建成功的话使用vTaskSuspend()把刚刚创建的任务转换为挂起状态(该任务将不会再得到执行)

使用vTaskResume()让刚刚挂起的任务转为就绪状态

FreeRTOS 任务与调度器(1)

 

5.2、vTaskSuspendAll()和vTaskResumeAll()

FreeRTOS 任务与调度器(1)

5.2.1、函数简介:

vTaskSuspendAll()挂起调度器 对应 xTaskResumeAll()解除挂起调度器:
• vTaskSuspendAll()挂起调度器后,只有当前任务在继续执行,不会发生任务切换了。
• xTaskResumeAll()对应vTaskSuspendAll()恢复调度器。
这个函数的作用之一在于,可以保证一些不能被分的程序执行,因为挂起调度器保证了不会被高优先级的任务强调(注意调度器挂起后中断还是可以运行的,如果要保证时效,还得把中断关闭)

注意:vTaskSuspendAll()是可以递归调用的,这意味着调用了多少次vTaskSuspendAll(),就必须有多少此vTaskResumeAll()的调用才能让调度器恢复。这个情况以下的例子中很好地体现了。


5.2.2、使用简介

在任务vTask1中第一此调用vTaskSuspendAll(),此时调度器被挂起,不会发生任务切换

调用另一个用作例子的vDemoFunction()

第二次调用vTaskSuspendAll(),此时调度器再次被挂起,而且挂起计数增加到2

第一次调用vTaskResumeAll(),此时调度器挂起计数减少为1,但是调度器仍然处于挂起状态

第二次调用vTaskResumeAll(),调度器计数为0,调度器恢复运行,后面会发生任务切换了

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wppdpg.html