当前位置: 首页 > article >正文

操作系统任务操作

目录

-- 对于操作系统核心要掌握的:(就是以下几点)

-- 任务怎么创建

-- 例如我们创建一个按键的任务

-- 难点:任务优先级分配

-- 有创建就有删除

对于任务的基本操作, 在操作系统里面任务会有四个状态

操作系统到底如何去管理(面试必问的问题)

动态创建和静态创建

应用:将裸机的工程砖换成操作系统的工程


-- 对于操作系统核心要掌握的:(就是以下几点)

  • 1、任务怎么创建
  • 2、操作系统如何管理任务
  • 3、任务间通信

-- 任务怎么创建

  • 1、创建任务句柄 -- TaskHandle_t Led1TaskCreat_Handle = NULL;//任务句柄(一般就是全局变量)
  • 2、创建任务主题函数(函数具体实现功能)-- 任务一定是一个死循环
  • 3、创建任务
  • 4、启动任务(任务调度器)(有许多任务时写一次即可)

-- 可以参考文档中的启动流程 

alt text

 

alt text

-- 例如我们创建一个按键的任务

  • 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会执行其他任务) 

alt text

上面写的程序的运行顺序: -- 先执行灯,在任务周期时执行按键的主体函数 -- 当按键的任务周期到时,灯的任务周期还没完成

-- 如果将按键的优先级设置成2,一开始就会先运行按键

-- 有创建就有删除

-- 想删除哪个函数,就写他的句柄,参数如果时NULL,就是删除自身

-- 查看文档了解任务删除函数 

alt text

-- 删除之后, 

alt text

-- 在当前任务删除其他任务

alt text

-- 删除自身任务 

alt text

对于任务的基本操作, 在操作系统里面任务会有四个状态

-- 一个任务有:创建,删除,挂起,恢复(有这些函数)

-- 根据不同的场合选择不同的应用

  • 答:

-- 先了解任务的状态:(操作系统有四个)

-- Running—运行态

  • 当任务处于实际运行状态被称之为运行态,即 CPU 的使用权被这个任务占用。

  • Ready—就绪态

  • 处于就绪态的任务是指那些能够运行(没有被阻塞和挂起),但是当前没有运行的任务,因为同优先级或更高优先级的任务正在运行。

-- Blocked—阻塞态

  • 由于等待信号量,消息队列,事件标志组等而处于的状态被称之为阻塞态,另外任务调用延迟函数也会处于阻塞态。

-- Suspended—挂起态

  • 类似阻塞态,通过调用函数 vTaskSuspend()对指定任务进行挂起,挂起后这个任务将不被执行,只有调用函数 xTaskResume()才可以将这个任务从挂起态恢复。

alt text

-- 如何从运行态变成就绪态?

低优先级的任务被高优先级的任务打断,此时,低优先级的任务重新处于就绪态

-- 从挂起态恢复只会是就绪态

-- 挂起只有调用挂起函数才会进入挂起态

  • 运行态

-- 运行完之后,转换为阻塞态

  • 阻塞态(例如进入任务延时函数)

  • 就绪态(任务准备好了,只需要等待cpu调用)--可以转换成就绪态

-- 当启动任务调度器之后,会去就绪态里面找到一个最高优先级的任务,然后执行

-- 任务执行完之后,转换成阻塞态

-- 正常运行的时候,会在上述三种状态中切换

-- 挂起态

-- 还有一个函数叫做挂起函数

-- 对应的一个状态叫做挂起态(也是参数是句柄)

被挂起的任务不会再参与cpu的调度,cpu不再处理这个任务

-- 挂起就是自己创建的空间还在,删除是不在了

-- 有挂起就有恢复


操作系统到底如何去管理(面试必问的问题)

--

-- 咱们这个项目,任务大概5、6个,就会存在一个问题, 这么多任务,操作系统到底如何去管理(面试必问的问题)?

-- 当任务创建完毕之后,所有的任务,都是就绪态,此时所有的任务在一个叫做就绪列表里面保存。(只要是就绪态,就会在就绪列表里)
根据任务优先级的不同,最高优先级的任务排在就绪列表的最开头(跟据优先级从高到低进行排序)

-- 除了运行态,每个形态都有一个列表,例如阻塞态的会在阻塞列表里

-- 当就绪列表每次新增一个任务时,就绪列表就会重新排序

-- cpu也就是任务调度器永远只会运行就绪列表的第一个任务(最高优先级的任务)

-- 当任务运行完毕之后,任务会进入阻塞态,此时,在这个阻塞列表,会重新排序(根据什么排序呢?是根据阻塞时间来排序的,从大到小)


动态创建和静态创建

-- 实际在操作系统创建任务有两种方法:动态创建和静态创建

-- 每个任务都有自己的空间

-- 空间的大小固定,空间的位置固定吗?不固定

-- 现在的操作是动态创建,用的话划分,不用就不划分,空间用多少给多少(节省),问题:如果同一时间执行太多任务,程序可以会死。-- 动态创建的应用率太高

-- tip:操作系统 的空间应用算法 

alt text

-- 静态创建空间,空间的位置固定,空间的大小固定 

alt text

-- 静态创建就是先定义空间大小,再去创建。不会出现卡死的。可以保证任务不会出现空间的问题。缺点:在运行速度上比较慢(在同一时刻动态运行10个,静态运行8个。)

应用:将裸机的工程砖换成操作系统的工程


http://www.kler.cn/news/356093.html

相关文章:

  • CTFHUB技能树之SQL——Refer注入
  • 滚雪球学Redis[6.4讲]:Redis消息队列:构建高效的消息通信与任务调度系统
  • PyTorch 的 Dataset 类介绍
  • 构建行业应用生态:云原生应用市场简化企业软件安装
  • 【ChatGPT】如何让 ChatGPT 理解多步骤指令
  • 使用Riotee轻松实现无电池TinyML
  • .net 根据html的input type=“week“控件的值获取星期一和星期日的日期
  • 【基础篇】AOF日志:宕机了,Redis如何避免数据丢失?
  • JAVA使用easyExcel导出数据到EXCEl,导出数据不全问题解决
  • 智慧社区Web平台:Spring Boot技术实现
  • 25面向OBject-c语言的超详细知识点教程整理
  • HarmonyOS开发(State模型)
  • 计算机毕业设计Python+Flask智慧交通 客流量分析预测 交通大数据 线性回归预测 大数据毕业设计 数据可视化 人工智能
  • Java:获取视频文件的视频时长
  • springboot031教师工作量管理系统(论文+源码)_kaic
  • 基于SpringBoot的高校竞赛管理系统:设计与实现
  • 【大模型】AI视频课程制作工具开发
  • (JAVA)贪心算法、加权有向图与求得最短路径的基本论述与实现
  • 【达梦数据库】获取表字段信息SQL
  • 单片机原理及应用笔记:单片机的结构原理与项目实践