uCOSIII实时操作系统 五 任务API(任务创建和删除)

news2024/9/22 13:32:54

任务创建和删除

引入:一个任务的三要素是任务主体函数,任务栈,任务控制块,那么怎样吧这个三要素联系在一起呐?

任务创建:

在UCOSIII中我们通过函数OSTaskCreate()来创建任务。

作用:任务控制块,任务堆栈,任务代码等联系在一起,并初始化控制块的相应字段。

位置:os_task.c中定义原型函数

先不深究源码,先看看怎么用起来。

//任务创建函数入口参数解释
void  OSTaskCreate (OS_TCB        *p_tcb,//指向任务控制块OS_TCB
                    CPU_CHAR      *p_name,//指向任务的名字(字符串类型),每个任务都有不同的名字
                    OS_TASK_PTR    p_task,//执行任务代码,任务函数名
                    void          *p_arg,//传递任务主体函数的参数
                    OS_PRIO        prio,//任务优先级(一般从3开始,不用0/1/2)
                    CPU_STK       *p_stk_base,//指向堆栈基地址
                    CPU_STK_SIZE   stk_limit,//任务堆栈的最大深度(堆栈限制)
                    CPU_STK_SIZE   stk_size,//任务堆栈的大小
                    OS_MSG_QTY     q_size,//内嵌消息队列,0默认不用
                    OS_TICK        time_quanta,//时间片的长度,0默认时间节数除以10,// 轮转时间=time_quanta*时间长度
                    void          *p_ext,指向用户补充内存区,填0即可
                    OS_OPT         opt,//选项
                    /*选项:
                        OS_OPT_TASK_NONE //不使用任何选项
                        OS_OPT_TASK_STK_CHK //检查栈
                        OS_OPT_TASK_STK_CLR //清除栈
                        OS_OPT_TASK_SAVE_FP //保存浮点寄存器中的内容
                    */
                    OS_ERR        *p_err)//错误码

注意:为什么任务优先级一般从3开始

//UCOSIII中以下优先级用户程序不能使用,ALIENTEK
//将这些优先级分配给了UCOSIII的5个系统内部任务
//优先级0:中断服务服务管理任务 OS_IntQTask()
//优先级1:时钟节拍任务 OS_TickTask()
//优先级2:定时任务 OS_TmrTask()
//优先级OS_CFG_PRIO_MAX-2:统计任务 OS_StatTask()
//优先级OS_CFG_PRIO_MAX-1:空闲任务 OS_IdleTask()

任务创建应用模版:

//任务优先级
#define START_TASK_PRIO		3
//任务控制块
OS_TCB StartTaskTCB;
//任务堆栈大小	
#define START_STK_SIZE 		512
//任务堆栈	
CPU_STK START_TASK_STK[START_STK_SIZE];
//任务函数
void start_task(void *p_arg);


int main(void)
{
	OS_ERR err;//定义一个错误码
	CPU_SR_ALLOC();//进入临界区,定义临界区需要的变量
	
//硬件初始化
/*
	delay_init();       //延时初始化
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组配置
	uart_init(115200);    //串口波特率设置
	LED_Init();         //LED初始化
*/
	OSInit(&err);		//初始化UCOSIII
	OS_CRITICAL_ENTER();//进入临界区(关闭中断)
	//创建开始任务
/*
	OSTaskCreate((OS_TCB 	* )&StartTaskTCB,		//任务控制块
				 (CPU_CHAR	* )"start task", 		//任务名字
                 (OS_TASK_PTR )start_task, 			//任务函数
                 (void		* )0,					//传递给任务函数的参数
                 (OS_PRIO	  )START_TASK_PRIO,     //任务优先级
                 (CPU_STK   * )&START_TASK_STK[0],	//任务堆栈基地址
                 (CPU_STK_SIZE)START_STK_SIZE/10,	//任务堆栈深度限位
                 (CPU_STK_SIZE)START_STK_SIZE,		//任务堆栈大小
                 (OS_MSG_QTY  )0,					//任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
                 (OS_TICK	  )0,					//当使能时间片轮转时的时间片长度,为0时为默认长度,
                 (void   	* )0,					//用户补充的存储区
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项
                 (OS_ERR 	* )&err);				//存放该函数错误时的返回值
*/
	OS_CRITICAL_EXIT();	//退出临界区(开启中断)	 
	OSStart(&err);  //开启UCOSIII
	while(1);
}

任务删除:

OSTaskDel()函数用来删除当前任务。删除的任务将从所有就绪堵塞挂起和事件列表中删除。

作用: 用来删除任务,当一个任务不需要运行时候可以利用此函数删掉。  

位置:os_task.c中定义 函数原型:

void  OSTaskDel (OS_TCB  *p_tcb,//删除任务TCB,也可以传递NULL指针删除自身函数
                 OS_ERR  *p_err)//返回错误码

eg:

OSTaskDel((OS_TCB*)0,&err); //删除任务自身 OSTaskDel((OS_TCB*)&Task2_TaskTCB,&err); //删除指定任务

任务创建和删除实验

实验要求:

1、主函数创建任务1负责创建任务2和任务3执行完函数之后删掉自身。
2、任务2和任务3在任务运行过程中要将自身运行次数通过串口打印。
3、任务2在执行任务超过十次后删除任务3

先准备一个移植好的空白模版:

先定义一下任务1:

在main函数当中根据之前的模版输入

此时在创建任务1的各个入口参数与定义的任务1对应

编写任务1,因为要求我们在任务1中创建任务2任务3

此时任务2任务3还未被定义,返回定义任务1的下方定义任务2任务3 :

编写任务2任务3 函数。

又裸机基础的上边要求的逻辑很好理解,这里就不在解释。

注意:在任务2/3都是运行在while(1)循环当中,要是任务一直在while(1)中没法挂起,退出死循环,那这样就不会进行任务3,所以while(1)中一定要加阻塞。所以用OSTimeDlyHMSM();函数进行延时阻塞。

这样实验就进行成功了查看一下运行结果:

实验源码:

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "includes.h"

//UCOSIII中以下优先级用户程序不能使用,ALIENTEK
//将这些优先级分配给了UCOSIII的5个系统内部任务
//优先级0:中断服务服务管理任务 OS_IntQTask()
//优先级1:时钟节拍任务 OS_TickTask()
//优先级2:定时任务 OS_TmrTask()
//优先级OS_CFG_PRIO_MAX-2:统计任务 OS_StatTask()
//优先级OS_CFG_PRIO_MAX-1:空闲任务 OS_IdleTask()

//创建任务1
//定义任务优先级
#define TASK_1_PRIO 3
//定义任务控制块
OS_TCB TASK_1_TCB;
//定义任务堆栈大小
#define TASK_1_STK_SIZE 128
//定义任务堆栈
CPU_STK TASK_1_STK[TASK_1_STK_SIZE];
//定义任务函数
void TASK_1(void *arg);

//创建任务2
//定义任务优先级
#define TASK_2_PRIO 4
//定义任务控制块
OS_TCB TASK_2_TCB;
//定义任务堆栈大小
#define TASK_2_STK_SIZE 128
//定义任务堆栈
CPU_STK TASK_2_STK[TASK_2_STK_SIZE];
//定义任务函数
void TASK_2(void *arg);

//创建任务3
//定义任务优先级
#define TASK_3_PRIO 5
//定义任务控制块
OS_TCB TASK_3_TCB;
//定义任务堆栈大小
#define TASK_3_STK_SIZE 128
//定义任务堆栈
CPU_STK TASK_3_STK[TASK_3_STK_SIZE];
//定义任务函数
void TASK_3(void *arg);


int main(void)
{
	OS_ERR err1;//错误码变量
	CPU_SR_ALLOC();//定义临界区需要的变量
	
	//硬件初始化
	delay_init();       //延时初始化
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组配置
	uart_init(115200);    //串口波特率设置
	
	OSInit(&err1);//初始化UCOSIII
	OS_CRITICAL_ENTER();//进入临界区代码
	
	//创建开始任务1
	OSTaskCreate((OS_TCB 	* )&TASK_1_TCB,		//任务控制块
				 (CPU_CHAR	* )"main TASK1", 		//任务名字
                 (OS_TASK_PTR )TASK_1, 			//任务函数
                 (void		* )0,					//传递给任务函数的参数
                 (OS_PRIO	  )TASK_1_PRIO,     //任务优先级
                 (CPU_STK   * )&TASK_1_STK[0],	//任务堆栈基地址
                 (CPU_STK_SIZE)TASK_1_STK_SIZE/10,	//任务堆栈深度限位
                 (CPU_STK_SIZE)TASK_1_STK_SIZE,		//任务堆栈大小
                 (OS_MSG_QTY  )0,					//任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
                 (OS_TICK	  )0,					//当使能时间片轮转时的时间片长度,为0时为默认长度,
                 (void   	* )0,					//用户补充的存储区
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项
                 (OS_ERR 	* )&err1);				//存放该函数错误时的返回值
	
	OS_CRITICAL_EXIT();//退出临界区代码
	OSStart(&err1);//开启UCOSIII

	while(1);
}

void TASK_1(void *arg)
{
	OS_ERR err2_3;//错误码变量
	CPU_SR_ALLOC();//定义临界区需要的变量
	
	OS_CRITICAL_ENTER();//进入临界区代码
	
	//创建开始任务2
	OSTaskCreate((OS_TCB 	* )&TASK_2_TCB,		//任务控制块
				 (CPU_CHAR	* )"main TASK2", 		//任务名字
                 (OS_TASK_PTR )TASK_2, 			//任务函数
                 (void		* )0,					//传递给任务函数的参数
                 (OS_PRIO	  )TASK_2_PRIO,     //任务优先级
                 (CPU_STK   * )&TASK_2_STK[0],	//任务堆栈基地址
                 (CPU_STK_SIZE)TASK_2_STK_SIZE/10,	//任务堆栈深度限位
                 (CPU_STK_SIZE)TASK_2_STK_SIZE,		//任务堆栈大小
                 (OS_MSG_QTY  )0,					//任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
                 (OS_TICK	  )0,					//当使能时间片轮转时的时间片长度,为0时为默认长度,
                 (void   	* )0,					//用户补充的存储区
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项
                 (OS_ERR 	* )&err2_3);				//存放该函数错误时的返回值
	//创建开始任务3
	OSTaskCreate((OS_TCB 	* )&TASK_3_TCB,		//任务控制块
				 (CPU_CHAR	* )"main TASK3", 		//任务名字
                 (OS_TASK_PTR )TASK_3, 			//任务函数
                 (void		* )0,					//传递给任务函数的参数
                 (OS_PRIO	  )TASK_3_PRIO,     //任务优先级
                 (CPU_STK   * )&TASK_3_STK[0],	//任务堆栈基地址
                 (CPU_STK_SIZE)TASK_3_STK_SIZE/10,	//任务堆栈深度限位
                 (CPU_STK_SIZE)TASK_3_STK_SIZE,		//任务堆栈大小
                 (OS_MSG_QTY  )0,					//任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
                 (OS_TICK	  )0,					//当使能时间片轮转时的时间片长度,为0时为默认长度,
                 (void   	* )0,					//用户补充的存储区
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项
                 (OS_ERR 	* )&err2_3);				//存放该函数错误时的返回值							 
								 
	OS_CRITICAL_EXIT();//退出临界区代码
	
	//任务一执行完函数之后删掉自身
	OSTaskDel((OS_TCB *)0,&err2_3);			 
}


void TASK_2(void *arg)
{
	int num = 0;//任务2运行次数
	OS_ERR err2;
	while(1)
	{
		num++;
		if(num==10)
		{
			OSTaskDel((OS_TCB *)&TASK_3_TCB,&err2);
			printf("删除任务三\r\n");
		}
		printf("任务2运行次数:%d\r\n",num);
		OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err2);//延时1S
	}
}

void TASK_3(void *arg)
{
	int num = 0;//任务2运行次数
	OS_ERR err3;
	while(1)
	{
		num++;
		printf("任务3运行次数:%d\r\n",num);
		OSTimeDlyHMSM(0,0,0,500,OS_OPT_TIME_HMSM_STRICT,&err3);//延时500ms
	}
}

 

  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1080262.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

有root权限的共享服务器,返现福利

以下是目前各类型服务器配置与价格目录: 可咨询文末微信号领取返现福利,注册链接: 西柚云超算https://www.xiyoucloud.net/aff/YADJJHWA 微信号:生信小博士

需求解析思路

需求:如果一个学生N天没学习了 根据question_user_submit_record(N配置),公众号推送通知到java8c.com学习 由于写代码需要严谨快速: 当前写代码方式:先写controller,再写sql语句,…

Postman历史版本下载

1. 下载对应版本的postman 历史版本下载 请把下面链接的"版本号"替换为指定的版本号,例如:8.8.0 Windows64位 ​https://dl.pstmn.io/download/version/版本号/win64​ Windows32位 https://dl.pstmn.io/download/version/版本号…

SpringBoot+Dubbo+Nacos 开发Demo

1、是什么 Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的RPC实现服务的输出和输入功能,可以和Spring框架无缝集成。Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的…

MinIO的安装与使用

文章目录 1.MINIO是什么?2.MINIO安装3.启动脚本4.打开MINIO页面5.MC命令6.MINIO备份脚本 1.MINIO是什么? MinIO 是一款高性能、分布式的对象存储系统. 它是一款软件产品, 可以100%的运行在标准硬件。即X86等低成本机器也能够很好的运行MinIO。 MinIO与…

智能导诊系统、智能在线问诊系统源码

一、需求背景 目前各大城市的著名医院吸引越来越多的患者,咨询台的服务需求也随之增加。医院虽然设置了少数咨询台,但由于患者人数众多,咨询台往往无法满足患者咨询要求,护士工作量巨大,医院巨大的规模也让咨询台数量…

佳音通讯400电话中心:在线自选,惠及企业

在当今竞争激烈的商业环境中,企业需要提供卓越的客户服务来脱颖而出。而一个高效的400电话中心则成为了越来越多企业的选择。佳音通讯400电话中心官方网站是企业选择400电话服务的首选平台,提供了在线自选功能,让企业能够根据自身需求灵活选择…

实现一个自己的脚手架教程

前言 脚手架并不实现,难的是最佳实践的整理和沉淀。本文不会涉及到最佳实践方面的内容,只是教会你如何实现一个最基础的脚手架,以此作为展示最佳实践的载体。 如何搭建一个脚手架的工程 如何开发和调试一个脚手架 脚手架中如何接收和处理命…

C++教程(2)

C 环境设置 本地环境设置 如果您想要设置 C 语言环境,您需要确保电脑上有以下两款可用的软件,文本编辑器和 C 编译器。 文本编辑器 这将用于输入您的程序。文本编辑器包括 Windows Notepad、OS Edit command、Brief、Epsilon、EMACS 和 vim/vi。 文…

零代码编程:用ChatGPT批量调整文件名称中的词汇顺序

文件夹里面很多文件,需要批量挑战标题中的一些词组顺序:“Peppa Pig - Kylie Kangaroo (14 episode _ 4 season) [HD].mp4”这个文件名改成“14 episode _ 4 season _ Peppa Pig - Kylie Kangaroo.mp4”,可以在ChatGPT中输入提示词&#xff1…

加盐加密详解

一、什么是加盐加密 加盐加密就是后端在存储一个密码的时候,为了提高安全性,随机生成一个盐值(随机值),将盐值和密码进行有规则的结合,然后将结合过后的数据使用加密算法(一般是md5加密&#x…

数据中心供配电及能效管理系统的设计要点

摘要:现代的数据中心中都包括大量的计算机,对于这种场所的电力供应,都要求供电系统需要在所有的时间都有效,这就不同于一般建筑的供配电系统,它是一个交叉的系统,涉及到市电供电、防雷接地、防静电、UPS不间…

CAN和CANFD通信介绍

CAN(Controller Area Network,控制器局域网)是一种串行通信技术,专门用于在汽车电子控制单元(ECU)之间实现可靠的数据交换。 CAN协议介绍 电子化 汽车近年来的发展呈现出以电子化为主的特点。电子化的主…

深度学习基础知识 Dataset 与 DataLoade的用法解析

深度学习基础知识 Dataset 与 DataLoade的用法解析 1、Dataset2、DataLoader参数设置:1、pin_memory2、num_workers3、collate_fn分类任务目标检测任务 1、Dataset 代码: import torch from torch.utils import dataclass MyDataset(torch.utils.data.D…

c#-特殊的集合

位数组 可观察的集合 private ObservableCollection<string> strList new ObservableCollection<string>();// Start is called before the first frame updatevoid Start(){strList.CollectionChanged Change;strList.Add("ssss");strList.Add("…

uTools使用技巧

uTools 提高工作效率、学习效率。 启动uTools Alt 空格 关键词 任何系统文件&#xff0c;软件&#xff0c;插件&#xff0c;都可以通过 关键词 快速跳转。 快速打开文件/软件 输入"控制面板"&#xff0c;选中后就能跳转到 “控制面板” 同样的 “程序与功能…

软件测试工程师是做什么的?这是我的理解...

近年来&#xff0c;由于IT行业的人才稀缺&#xff0c;越来越多人转向了IT相关职业。 由于IT软件业的薪资较高&#xff0c;吸引了不少人选择了IT软件专业&#xff0c;IT软件专业包括软件开发、Java工程师、软件测试工程师等。 软件测试工程师主要是负责理解产品的功能要求&…

RESIDUAL INTERPOLATION FOR COLOR IMAGE DEMOSAICKING

ABSTRACT 一种广泛应用于彩色图像马赛克的色差插值技术。在本文中&#xff0c;我们提出残差插值作为一种替代颜色差插值&#xff0c;其中残差是一个观察和一个初步估计的像素值之间的差异。我们将所提出的残差插值方法引入到基于梯度的无阈值(GBTF)算法中&#xff0c;该算法是…

速腾激光雷达 RS M1 slam 建图

速腾激光雷达 RS M1 slam 建图

【QT】Ubuntu 编译安装 QT 5.12.7 源码

直接通过源码来编译安装 QT&#xff0c;难度太大&#xff0c;耗时较长&#xff0c;一般不是特别推荐使用源码安装。 目录 1、下载 QT 源码包 2、搭建安装环境(下载依赖库) 3、编译QT源码的脚本 1、下载 QT 源码包 QT5.12.7源码下载地址: download | QT 5.12.7 选择任意一…