操作系统任务操作
目录
-- 对于操作系统核心要掌握的:(就是以下几点)
-- 任务怎么创建
-- 例如我们创建一个按键的任务
-- 难点:任务优先级分配
-- 有创建就有删除
对于任务的基本操作, 在操作系统里面任务会有四个状态
操作系统到底如何去管理(面试必问的问题)
动态创建和静态创建
应用:将裸机的工程砖换成操作系统的工程
-- 对于操作系统核心要掌握的:(就是以下几点)
- 1、任务怎么创建
- 2、操作系统如何管理任务
- 3、任务间通信
-- 任务怎么创建
- 1、创建任务句柄 -- TaskHandle_t Led1TaskCreat_Handle = NULL;//任务句柄(一般就是全局变量)
- 2、创建任务主题函数(函数具体实现功能)-- 任务一定是一个死循环
- 3、创建任务
- 4、启动任务(任务调度器)(有许多任务时写一次即可)
-- 可以参考文档中的启动流程
-- 例如我们创建一个按键的任务
- 1、创建任务句柄(定义成全局变量)
TaskHandle_t keyTaskCreat_Handle = NULL;//任务句柄
- 2、创建任务主题函数
函数名称不固定,参数格式是固定的(任务一定是一个while循环,每个任务一定要有自己的任务周期)//设置任务周期的目的就是可以让任务可以主动释放cpu(指的是任务能够自动释放cpu)
void KETTaskCreat(void *pvParameters)//函数名称不固定,参数格式是固定的(任务一定是一个while循环,每个任务一定要有自己的任务周期)//设置任务周期的目的就是可以让任务可以主动释放cpu(指的是任务能够自动释放cpu)
{
uint8_t keyflag = 0;
while(1)
{
keyflag = get_key();
switch(keyflag)
{
case 1:
break;
case 2:
break;
}
vTaskDelay(50); //在任务周期时可以释放cpu
}
}
- 3、创建任务
TaskHandle_t Led1TaskCreat_Handle = NULL;//任务句柄
BaseType_t xReturn = pdPASS;
xReturn = xTaskCreate(KETTaskCreat, //任务函数接口 函数名称 //任务主体函数名称(也叫做任务函数接口)
"led1", //任务别名不能一样 //人为起的一个任务别名(不能超过16个字节)(不能太长)(相当于给任务起绰号)(每个任务不能相同)
256, //任务栈空间(字节) //单位是字节(一般在创建任务的时候空间尽量给大一些)
NULL, //任务传参 //任务传参,有参数的时候写,没参数写NULL
1, //任务优先级 那个任务重要,优先级高 //任务优先级,
&keyTaskCreat_Handle); //任务句柄
- 4、启动任务
if(xReturn == pdPASS)
vTaskStartScheduler();//任务调度器 //当程序执行完这句话之后,正常情况下下面的代码不会再运行,只会运行任务主题函数
-- 整体代码
- main.c
TaskHandle_t Led1TaskCreat_Handle = NULL;//任务句柄
void LED1TaskCreat(void *pvParameters)
{
while(1)
{
LED1(1);
vTaskDelay(100); //任务周期 100个时钟节拍 释放cpu
LED1(0);
vTaskDelay(100); //任务周期
}
}
TaskHandle_t keyTaskCreat_Handle = NULL;//任务句柄
//2
void KETTaskCreat(void *pvParameters)//函数名称不固定,参数格式是固定的(任务一定是一个while循环,每个任务一定要有自己的任务周期)//设置任务周期的目的就是可以让任务可以主动释放cpu(指的是任务能够自动释放cpu)
{
uint8_t keyflag = 0;
while(1)
{
keyflag = get_key();
switch(keyflag)
{
case 1:
//vTaskDelete( NULL );//删除自身
vTaskDelete(Led1TaskCreat_Handle);//删除led的任务
break;
case 2:
break;
}
vTaskDelay(50); //在任务周期时可以释放cpu
}
}
int main()
{
key_init();
led_init();
TaskHandle_t Led1TaskCreat_Handle = NULL;//任务句柄
BaseType_t xReturn = pdPASS;
xReturn = xTaskCreate(LED1TaskCreat, //任务函数接口 函数名称
"led1", //任务别名不能一样
128, //任务栈空间(字节)
NULL, //任务传参
1, //任务优先级 那个任务重要,优先级高
&Led1TaskCreat_Handle); //任务句柄
//3、
BaseType_t xReturn = pdPASS;
xReturn = xTaskCreate(KETTaskCreat, //任务函数接口 函数名称 //任务主体函数名称(也叫做任务函数接口)
"key", //任务别名不能一样 //人为起的一个任务别名(不能超过16个字节)(不能太长)(相当于给任务起绰号)(每个任务不能相同)
256, //任务栈空间(字节) //单位是字节(一般在创建任务的时候空间尽量给大一些)
NULL, //任务传参 //任务传参,有参数的时候写,没参数写NULL
1, //任务优先级 那个任务重要,优先级高 //任务优先级,
&keyTaskCreat_Handle); //任务句柄
if(xReturn == pdPASS)
vTaskStartScheduler();//任务调度器 //当程序执行完这句话之后,正常情况下下面的代码不会再运行,只会运行任务主题函数
}
-- 注意创建任务函数的参数解释:在上面的代码注释
-- 操作系统不会出现没有任务执行的时候,操作系统有空闲任务(优先级最低)
-- 难点:任务优先级分配
-- 优先级,会产生任务之间相互打断,同时也会产生资源抢占
-- 难在任务逻辑,FREERTOS操作系统允许任务优先级一样,其他有的操作系统任务优先级都不同
-- 如果两个任务优先级一样,谁先运行?一般谁先创建,谁先运行
-- 在咱们这个项目里面,有数据采集,wifi,屏幕这些任务
-- 哪些任务比较重要(任务重要与否主要看项目的主要立意)
-- 一些面试会问的问题:
-- 咱们这个项目最重要的就是?项目在哪用?(室内),产品长什么样子?产品怎么供电?(电池或者usb)用户该怎么操作你制造的东西?
项目一定要了解清楚,哪个任务比较重要?咱们这个项目是和用户的交互最重要(如果一点就卡,喊语音喊半天没有效果)
-- 对于现在来说最重要的 -- 1、界面任务,2、语音,3、云端
-- 对于任务优先级的划分,要根据设备应用环境不同,重要程度之分
--
-- 在任务周期时,本质是任务延时(在任务延时时间内,任务会释放cpu,cpu会执行其他任务)
上面写的程序的运行顺序: -- 先执行灯,在任务周期时执行按键的主体函数 -- 当按键的任务周期到时,灯的任务周期还没完成
-- 如果将按键的优先级设置成2,一开始就会先运行按键
-- 有创建就有删除
-- 想删除哪个函数,就写他的句柄,参数如果时NULL,就是删除自身
-- 查看文档了解任务删除函数
-- 删除之后,
-- 在当前任务删除其他任务
-- 删除自身任务
对于任务的基本操作, 在操作系统里面任务会有四个状态
-- 一个任务有:创建,删除,挂起,恢复(有这些函数)
-- 根据不同的场合选择不同的应用
- 答:
-- 先了解任务的状态:(操作系统有四个)
-- Running—运行态
-
当任务处于实际运行状态被称之为运行态,即 CPU 的使用权被这个任务占用。
-
Ready—就绪态
-
处于就绪态的任务是指那些能够运行(没有被阻塞和挂起),但是当前没有运行的任务,因为同优先级或更高优先级的任务正在运行。
-- Blocked—阻塞态
- 由于等待信号量,消息队列,事件标志组等而处于的状态被称之为阻塞态,另外任务调用延迟函数也会处于阻塞态。
-- Suspended—挂起态
- 类似阻塞态,通过调用函数 vTaskSuspend()对指定任务进行挂起,挂起后这个任务将不被执行,只有调用函数 xTaskResume()才可以将这个任务从挂起态恢复。
-- 如何从运行态变成就绪态?
低优先级的任务被高优先级的任务打断,此时,低优先级的任务重新处于就绪态
-- 从挂起态恢复只会是就绪态
-- 挂起只有调用挂起函数才会进入挂起态
- 运行态
-- 运行完之后,转换为阻塞态
-
阻塞态(例如进入任务延时函数)
-
就绪态(任务准备好了,只需要等待cpu调用)--可以转换成就绪态
-- 当启动任务调度器之后,会去就绪态里面找到一个最高优先级的任务,然后执行
-- 任务执行完之后,转换成阻塞态
-- 正常运行的时候,会在上述三种状态中切换
-- 挂起态
-- 还有一个函数叫做挂起函数
-- 对应的一个状态叫做挂起态(也是参数是句柄)
被挂起的任务不会再参与cpu的调度,cpu不再处理这个任务
-- 挂起就是自己创建的空间还在,删除是不在了
-- 有挂起就有恢复
操作系统到底如何去管理(面试必问的问题)
--
-- 咱们这个项目,任务大概5、6个,就会存在一个问题, 这么多任务,操作系统到底如何去管理(面试必问的问题)?
-- 当任务创建完毕之后,所有的任务,都是就绪态,此时所有的任务在一个叫做就绪列表里面保存。(只要是就绪态,就会在就绪列表里)
根据任务优先级的不同,最高优先级的任务排在就绪列表的最开头(跟据优先级从高到低进行排序)
-- 除了运行态,每个形态都有一个列表,例如阻塞态的会在阻塞列表里
-- 当就绪列表每次新增一个任务时,就绪列表就会重新排序
-- cpu也就是任务调度器永远只会运行就绪列表的第一个任务(最高优先级的任务)
-- 当任务运行完毕之后,任务会进入阻塞态,此时,在这个阻塞列表,会重新排序(根据什么排序呢?是根据阻塞时间来排序的,从大到小)
动态创建和静态创建
-- 实际在操作系统创建任务有两种方法:动态创建和静态创建
-- 每个任务都有自己的空间
-- 空间的大小固定,空间的位置固定吗?不固定
-- 现在的操作是动态创建,用的话划分,不用就不划分,空间用多少给多少(节省),问题:如果同一时间执行太多任务,程序可以会死。-- 动态创建的应用率太高
-- tip:操作系统 的空间应用算法
-- 静态创建空间,空间的位置固定,空间的大小固定
-- 静态创建就是先定义空间大小,再去创建。不会出现卡死的。可以保证任务不会出现空间的问题。缺点:在运行速度上比较慢(在同一时刻动态运行10个,静态运行8个。)