文章目录
Real-Time OS实时操作系统是通过优先级和分配时间片来进行任务调度。
前言
前文已经了解了RTOS工程的结构。要使用RTOS的多任务处理功能,实现正确创建任务等功能,首先要先学习RTOS的任务基础知识。
一、RTOS任务基础知识
1.RTOS
Real-Time OS实时操作系统是通过优先级和分配时间片来进行任务调度。
RTOS调度器的职责是确保当一个任务开始执行的时候其上下文环境(寄存器的值,堆栈内容等)和任务上一次推出的时候相同。所以创建任务时有个参数为堆栈大小,就是为了将上下文环境保存在堆栈中,就可以在下个时间片到达时接着上次运行。
2.任务状态:
运行态:永远只有一个任务处于运行态
就绪态:由于一个同优先级或者更高优先级的任务正在运行,所以处于就绪态
阻塞态: 由于等待外部事件触发所以处于阻塞态
挂起态:任务挂起后不会被任务调度器调用,通过挂起和解挂函数实现,(可以降低功耗?加快运行速率)
3.任务优先级
4.任务应用程序的一些性质
我们使用函数创建任务;
xTaskCreate(,,,,,); 或者xTaskCreateStatic(,,,,,,)
第一个参数为pxTaskCode,就是任务函数名。
任务函数模板:
要注意:
/*
1.任务函数没有返回值 必须为void
2.一般情况下不能从任务函数中返回或者退出,如果定义了configASSERT()可以推出,如果一定要推出就调用 vTaskDelete(NULL);删除任务
3.任务的具体执行过程是一个大循环 while(1)
4.FreeRTOS的延时API函数是为了发生任务切换,还可以请求信号量,队列等,甚至直接调用任务调度器
为什么要这样::
对任务 Task1 的运行状态做说明:
运行过程描述如下:
- 起初任务 Task1 处于运行态,调用 vTaskDelay 函数后进入到阻塞状态,也就是 blocked 状态。
- vTaskDelay 函数设置的延迟时间到,由于任务 Task1 不是当前就绪的最高优先级任务,处于就绪的是同优先级其他任务,或者就绪的更高优先级的任务,所以Task1不能进入到运行状态,只能进入到就绪状态,也就是 ready 状态。
- 一段时间后, 调度器执行其他任务后发现任务 Task1 是当前就绪的最高优先级任务,从而任务从就绪态切换到运行态。
- 由于时间片调度,任务 Task1 由运行态切换到就绪态。
5.任务函数一般不允许跳出循环,如果跳出循环了一定要删除任务
*/
void vATaskFunction(void *pvParameters)
{
for(;;)//while(1)
{
--任务应用程序--
vTaskDelay();
}
vTaskDelete(NULL);
}
5.任务控制模块
创建任务的时候会自动给每个任务分配一个任务控制块,里面定义了每个任务的一些状态信息。
6.任务堆栈
如果使用xTaskCreate()创建任务(动态方法),任务堆栈会由此函数自动创建;
函数 字符串 堆栈大小 传入参数 优先级 句柄
如果使用函数xTaskCreateStatic()创建任务(静态方法),需要由程序员自行定义任务堆栈;
函数 字符串 堆栈大小 传入参数 优先级 栈首地址puxStackBuffer pxTaskBuffer
注:任务堆栈的数据类型为 StackType_t , StackType_t 是 uint32_t,那么任务的实际堆栈大小就应是定义的4倍
二、RTOS任务相关API函数
1.任务创建和删除API函数
1.1动态创建xTaskCreate()
1.2 静态任务创建 xTaskCreateStatic()
1.3 xTaskCreateRestricted()
此函数创建的任务会受到MPU(内存保护单元)的保护
1.4 vTaskDelete()
2.任务创建和删除实验(动态方法)
较简单,注意句柄即为任务堆栈首地址即可
3.任务创建和删除实验(静态方法)
没看,Minifly未用到
4.任务挂起和恢复API函数
5.任务挂起和恢复实验
暂时没看
总结
主要对任务创建、删除、挂起、解挂函数 及 需要传入的参数 进行了理解
实例的话 上文(一)中理解了一个RTOS下的中断项目
20:30 理学楼
October 20, 2020