STM32F407ZGT6-UCOSIII笔记3:任务挂起与恢复实验

news2024/12/18 15:36:15

本文学习与程序编写基于 正点原子的 STM32F1 UCOS开发手册

编写熟悉一下UCOSIII系统的任务挂起与恢复实验

文章提供测试代码讲解、完整工程下载、测试效果图

目录

任务挂起与恢复目的:

任务挂起的目的

任务恢复的目的

任务函数文件:

任务块头文件  #include "Task_config.h"  :

文件整体结构如下:

目前各个文件任务:

#include "main.h"

#include "ComTask.h"

#include "MessageTask.h"

#include "CalculateTask.h"

 下载测试效果:

 

测试工程下载:


任务挂起与恢复目的:

任务挂起的目的

  1. 任务暂停:当任务需要等待某些事件发生(如I/O操作完成、信号量可用等)时,可以通过挂起任务来释放CPU资源,让其他任务有机会运行。这样可以避免任务长时间占用CPU资源,导致系统响应变慢。
  2. 资源管理:在某些情况下,可能需要暂时停止某些任务的执行,以便重新分配系统资源或调整任务优先级。通过挂起任务,可以实现资源的动态管理和优化。
  3. 任务同步:在多任务环境中,任务之间可能存在依赖关系。通过挂起任务,可以实现任务之间的同步,确保任务按照预定的顺序执行。

任务恢复的目的

  1. 任务继续执行:当挂起任务所等待的事件发生时,或者系统资源得到重新分配后,需要恢复任务的执行。通过恢复任务,可以让任务继续完成其预定的功能。
  2. 提高系统效率:通过合理地挂起和恢复任务,可以避免任务之间的冲突和竞争,提高系统的运行效率和响应速度。
  3. 任务管理:在UCOS系统中,任务挂起和恢复是任务管理的重要组成部分。通过这两个操作,可以实现任务的动态调度和优先级调整,从而更好地满足系统的运行需求。

任务函数文件:

    工程包含一个TASK组,里面含有各个任务的实际函数体:

    #include "ComTask.h"包含串口相关任务操作

    #include "MessageTask.h" 包含信号灯状态等 对外释放信号安排的 相关操作

    #include "CalculateTask.h" 包含数据计算任务

任务块头文件  #include "Task_config.h"  :

这是为了方便 任意其他任务 对 任意任务进行 删除 挂起 恢复 等操作而编写的,

因为每个任务都写在自己的任务文件中,对任务块名称引用需要有专门文件来提供通道

不这么编写就没法有这个实现......

文件整体结构如下:

需要在.c 中定义任务块,然后在.h 文件extern

直接写在.h 文件 不 进行extern,就会报错

#include "Task_config.h" //任务定义文件


/*	开始任务 StartTask	*/
//任务控制块
OS_TCB StartTaskTCB;
//任务堆栈	
CPU_STK START_TASK_STK[START_STK_SIZE];

/*   ComTask  */
//任务控制块
OS_TCB COMTASKTaskTCB;
//任务堆栈	
CPU_STK COMTASK_TASK_STK[COMTASK_STK_SIZE];


/*  MessageTask  */
//任务控制块
OS_TCB MessageTaskTaskTCB;
//任务堆栈	
CPU_STK MessageTask_TASK_STK[MessageTask_STK_SIZE];


/*  CalculateTask */
//任务控制块
OS_TCB	CalculateTaskTaskTCB;
//任务堆栈
__align(8) CPU_STK	CalculateTask_TASK_STK[CalculateTask_STK_SIZE];


// Task_config.h

#ifndef TASK_CONFIG_H
#define TASK_CONFIG_H

#include "headfile.h"


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


//任务优先级
#define COMTASK_TASK_PRIO		6
//任务堆栈大小	
#define COMTASK_STK_SIZE 		128
//任务控制块
extern OS_TCB COMTASKTaskTCB;
//任务堆栈	
extern CPU_STK COMTASK_TASK_STK[COMTASK_STK_SIZE];
//任务函数定义在#include "ComTask.h"


//任务优先级
#define MessageTask_TASK_PRIO		6
//任务堆栈大小	
#define MessageTask_STK_SIZE 		128
//任务控制块
extern OS_TCB MessageTaskTaskTCB;
//任务堆栈	
extern CPU_STK MessageTask_TASK_STK[MessageTask_STK_SIZE];
//任务函数定义在#include "MessageTask.h"


//任务优先级
#define CalculateTask_TASK_PRIO		8
//任务堆栈大小
#define CalculateTask_STK_SIZE		128
//任务控制块
extern OS_TCB	CalculateTaskTaskTCB;
//任务堆栈
extern __align(8) CPU_STK	CalculateTask_TASK_STK[CalculateTask_STK_SIZE];
//任务函数定义在#include "CalculateTask.h"




#endif 

// TASK_CONFIG_H

目前各个文件任务:

#include "main.h"

创建开始任务初始化三个基本任务:

代码如下:

#include "main.h"

void start_task(void *p_arg);//开始任务函数


int main(void)
{
	OS_ERR err;
	CPU_SR_ALLOC();
	
  Init_ALL();
	
	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);
								 
}

//开始任务函数
void start_task(void *p_arg)
{
	OS_ERR err;
	CPU_SR_ALLOC();
	p_arg = p_arg;

	CPU_Init();
#if OS_CFG_STAT_TASK_EN > 0u
   OSStatTaskCPUUsageInit(&err);  	//统计任务                
#endif
	
#ifdef CPU_CFG_INT_DIS_MEAS_EN		//如果使能了测量中断关闭时间
    CPU_IntDisMeasMaxCurReset();	
#endif

#if	OS_CFG_SCHED_ROUND_ROBIN_EN  //当使用时间片轮转的时候
	 //使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms
	OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);  
#endif		
	
	OS_CRITICAL_ENTER();	//进入临界区
	//创建ComTask任务
	OSTaskCreate((OS_TCB 	* )&COMTASKTaskTCB,		
				 (CPU_CHAR	* )"com task", 		
                 (OS_TASK_PTR )comTask, 			
                 (void		* )0,					
                 (OS_PRIO	  )COMTASK_TASK_PRIO,     
                 (CPU_STK   * )&COMTASK_TASK_STK[0],	
                 (CPU_STK_SIZE)COMTASK_STK_SIZE/10,	
                 (CPU_STK_SIZE)COMTASK_STK_SIZE,		
                 (OS_MSG_QTY  )0,					
                 (OS_TICK	  )0,					
                 (void   	* )0,					
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
                 (OS_ERR 	* )&err);				
				 
	//创建MessageTask任务
	OSTaskCreate((OS_TCB 	* )&MessageTaskTaskTCB,		
				 (CPU_CHAR	* )"Message task", 		
                 (OS_TASK_PTR )MessageTask, 			
                 (void		* )0,					
                 (OS_PRIO	  )MessageTask_TASK_PRIO,     	
                 (CPU_STK   * )&MessageTask_TASK_STK[0],	
                 (CPU_STK_SIZE)MessageTask_STK_SIZE/10,	
                 (CPU_STK_SIZE)MessageTask_STK_SIZE,		
                 (OS_MSG_QTY  )0,					
                 (OS_TICK	  )0,					
                 (void   	* )0,				
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, 
                 (OS_ERR 	* )&err);
				 
	//创建CalculateTask任务
	OSTaskCreate((OS_TCB 	* )&CalculateTaskTaskTCB,		
				 (CPU_CHAR	* )"Calculate task", 		
                 (OS_TASK_PTR )CalculateTask,	
                 (void		* )0,					
                 (OS_PRIO	  )CalculateTask_TASK_PRIO,     	
                 (CPU_STK   * )&CalculateTask_TASK_STK[0],	
                 (CPU_STK_SIZE)CalculateTask_STK_SIZE/10,	
                 (CPU_STK_SIZE)CalculateTask_STK_SIZE,		
                 (OS_MSG_QTY  )0,					
                 (OS_TICK	  )0,					
                 (void   	* )0,				
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, 
                 (OS_ERR 	* )&err);				 
	OS_TaskSuspend((OS_TCB*)&StartTaskTCB,&err);		//挂起开始任务			 
	OS_CRITICAL_EXIT();	//进入临界区
}

宏定义依赖 在Task_config.h 文件: 目前main.h 完全干干净净:

#include "ComTask.h"

一进来就删除CalculateTask任务

随后 ComTask 打印自己运行次数 等待800ms

代码如下:

#include "ComTask.h"

// 删除CalculateTask
//ComTask 打印自己运行次数 然后等待800ms
void comTask(void * p_arg)
{
	OS_ERR err;
	int i=0;
	
	p_arg = p_arg;
	
	OSTaskDel((OS_TCB*)&CalculateTaskTaskTCB,&err);
	UsartPrintf(USART1, "ComTask delete CalculateTask !\r\n");	//删除CalculateTask
	
	while (DEF_TRUE)
	{
		i++;
		UsartPrintf(USART1, "comTask Print%d\r\n",i);		
		//printf("comTask Print%d\r\n",i);
		//UsartPrintf(USART1, "%d\r\n",i);
		
		OSTimeDlyHMSM(0,0,0,800,OS_OPT_TIME_HMSM_STRICT,&err); //延时800ms
		
	}
}

#include "MessageTask.h"

    打印任务MessageTask运行次数  "暂且注释,有问题 会卡主系统"

    2024.12.17已解决:将任务栈大小改大些就行:

    分别按顺序 205ms间隔延迟 单独点亮 红绿蓝 LED 最后全亮
    运行3次后挂起 ComTask 并打印
    运行6次后恢复 ComTask 并打印

代码如下:

#include "MessageTask.h"

/*
	打印任务MessageTask运行次数  "暂且注释,有问题 会卡主系统"
	分别按顺序 205ms间隔延迟 单独点亮 红绿蓝 LED 最后全亮 
	运行3次后挂起 ComTask 并打印
	运行6次后恢复 ComTask 并打印 
*/
void MessageTask (void * p_arg)
{
	OS_ERR err;
	int i=0;
	p_arg = p_arg;
	while (DEF_TRUE)
	{
		i++;
		//UsartPrintf(USART1, "MessageTask Print%d\r\n",i);	 //此行取消注释会卡主系统!
		
		//单独亮红灯
	  LED_RED_L;LED_GREEN_H;LED_Blue_H;
		OSTimeDlyHMSM(0,0,0,205,OS_OPT_TIME_HMSM_STRICT,&err); //延时205ms
		//单独亮绿灯		
		LED_GREEN_L;LED_RED_H;LED_Blue_H;	
		OSTimeDlyHMSM(0,0,0,205,OS_OPT_TIME_HMSM_STRICT,&err); //延时205ms
		//单独亮蓝灯
		LED_Blue_L;LED_RED_H;LED_GREEN_H;		
		OSTimeDlyHMSM(0,0,0,205,OS_OPT_TIME_HMSM_STRICT,&err); //延时205ms
		//全部点亮 
		LED_RED_L;LED_GREEN_L;LED_Blue_L;
		OSTimeDlyHMSM(0,0,0,205,OS_OPT_TIME_HMSM_STRICT,&err); //延时205ms		
		
		if(i==3)
		{
			UsartPrintf(USART1, "M Sus Com\r\n");	//挂起
			OSTaskSuspend((OS_TCB*)&COMTASKTaskTCB,&err);
		}
		if(i==6)
		{
			UsartPrintf(USART1, "M Res Com\r\n");	//恢复
			OSTaskResume((OS_TCB*)&COMTASKTaskTCB,&err);
		}		
		
	}
	
}

#include "CalculateTask.h"

CalculateTask 打印自己运行次数 然后等待100ms  "本次实验将其删除"

代码如下:

#include "CalculateTask.h"

//CalculateTask 打印自己运行次数 然后等待100ms  "本次实验将其删除"

void  CalculateTask(void  *p_arg)
{
	OS_ERR err;
	int i=0;
	
	p_arg = p_arg;
	while (DEF_TRUE)
	{
		i++;
		UsartPrintf(USART1, "CalculateTask Print %d\r\n",i);	
		//UsartPrintf(USART1, "C:%d\r\n",i);	
		OSTimeDlyHMSM(0,0,0,100,OS_OPT_TIME_HMSM_STRICT,&err); //延时100ms
	}
}


 下载测试效果:

测试效果与解释如下:

 

测试工程下载:

https://download.csdn.net/download/qq_64257614/90139444

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

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

相关文章

vue使用pdfh5.js插件,显示pdf文件白屏

pdfh5,展示文件白屏,无报错 实现效果图解决方法(降版本)排查问题过程发现问题查找问题根源1、代码写错了?2、预览文件流的问题?3、pdfh5插件更新了,我的依赖包没更新?4、真相大白 彩蛋 实现效果图 解决方法…

脚本搭建论坛

先创建这个目录: 在这个目录中写多个.sh脚本: 将论坛的压缩包放到/var/www/html目录下: 执行main.sh脚本。 Windows网页网址栏输入192.168.234.112/upload/ (服务器ip地址),就可以安装了。

摩方M600_更换散热

研究了半天。参考了很多贴吧,哔哩哔哩的网友的方案。最后采用如下: 使用 apx90x47 散热器。散热静音效果很好。温度基本不到80度。作为对比 猫头鹰l9i 会到90温度墙。毕竟两个散热功率不一样。前置在 130w,后者65w。不过开始不懂&#xff0c…

【昇腾】NPU ID:物理ID、逻辑ID、芯片映射关系

起因: https://www.hiascend.com/document/detail/zh/Atlas%20200I%20A2/23.0.0/re/npu/npusmi_013.html npu-smi info -l查询所有NPU设备: [naienotebook-npu-bd130045-55bbffd786-lr6t8 DCNN]$ npu-smi info -lTotal Count : 1NPU…

python03-保留字、标识符;变量、常量;数据类型、数据类型之间的转化

一、保留字 VS 标识符 1-1、35个保留字 保留字,严格区分大小写! 查询保留字: 1-2、标识符 常量:python中没有明确的定义常量的关键字,常量的值在程序运行过程中不允许修改! 二、变量 VS 常量 2-1、变量 变…

解决VSCode无法识别相对路径的问题

前言: 近日在学习python文件操作时,发现使用VSCode作为编辑器时,文件的相对路径会出问题,报错“指定路径下找不到文件”,无法找到想要的文件。 知识点①:不同操作系统所使用的路径斜杠不同:Lin…

c++理解(三)

本文主要探讨c相关知识。 模板是对类型参数化 函数模板特化不是模板函数重载 allocator(空间配置器):内存开辟释放,对象构造析构 优先调用对象成员方法实现的运算符重载函数,其次全局作用域找 迭代器遍历访问元素,调用erase,insert方法后,当前位置到容器…

「九」HarmonyOS 5 端云一体化实战项目——「M.U.」应用云侧开发云数据库

1 立意背景 M. 代表 “我”,U. 代表 “你”,这是一款用于记录情侣从相识、相知、相恋、见家长、订婚直至结婚等各个阶段美好记忆留存的应用程序。它旨在为情侣们提供一个专属的空间,让他们能够将一路走来的点点滴滴,如初次相遇时…

NVM:安装配置使用(详细教程)

文章目录 一、简介二、安装 nvm三、配置 nvm 镜像四、配置环境变量五、使用教程5.1 常用命令5.2 具体案例 六、结语 一、简介 在实际的开发和学习中可能会遇到不同项目的 node 版本不同,而出现的兼容性问题。 而 nvm 就可以很好的解决这个问题,它可以在…

Spark优化----Spark 数据倾斜

目录 数据倾斜的表现: 定位数据倾斜问题: 解决方案一:聚合原数据 避免 shuffle 过程 缩小 key 粒度(增大数据倾斜可能性,降低每个 task 的数据量) 增大 key 粒度(减小数据倾斜可能性&#xff0c…

第十六届蓝桥杯模拟赛(第一期)-Python

本次模拟赛我认为涉及到的知识点: 分解质因数 Python的datetime库 位运算 简单dp 1、填空题 【问题描述】 如果一个数 p 是个质数,同时又是整数 a 的约数,则 p 称为 a 的一个质因数。 请问 2024 有多少个质因数。 【答案提交】 这是一道结…

MATLAB2021B APP seriallist 串口通信

文章目录 前言一、项目需要二、使用步骤1.查找串口填写到查找列表2.发送函数3. 接收函数4.检测串口按钮5.选择串口号 总结 前言 提示:这里可以添加本文要记录的大概内容: 项目需要: 提示:以下是本篇文章正文内容,下面…

OpenShift 4 - 多云管理(2) - 配置多集群观察功能

《OpenShift / RHEL / DevSecOps 汇总目录》 本文在 OpenShift 4.17 RHACM 2.12 环境中进行验证。 文章目录 多集群观察技术架构安装多集群观察功能监控多集群的运行状态监控多集群的应用运行在被管集群监控应用运行在管理集群监控被管集群的应用运行 参考 多集群观察技术架构…

AMBA-CHI协议详解(十二)

AMBA-CHI协议详解(一)- Introduction AMBA-CHI协议详解(二)- Channel fields / Read transactions AMBA-CHI协议详解(三)- Write transactions AMBA-CHI协议详解(四)- Other transac…

【win10+RAGFlow+Ollama】搭建本地大模型助手(教程+源码)

一、RAGFlow简介 RAGFlow是一个基于对文档深入理解的开源RAG(Retrieval-augmented Generation,检索增强生成)引擎。 主要作用: 让用户创建自有知识库,根据设定的参数对知识库中的文件进行切块处理,用户向大…

Android中坐标体系知识超详细讲解

说来说去都不如画图示意简单易懂啊!!!真是的! 来吧先上张图! (一)首先明确一下android 中的坐标系统: 屏幕的左上角是坐标系统原点(0,0) 原点向右延伸是X轴正…

IO的进阶

目录 1. 字符流转向字节流的桥梁1.1 OutputStreamWriter1.2 InputStreamReader1.3 编码与解码1.4 常见编码方式1.5 编码与解码的注意事项 2.Properties2.1概述2.2 Properties 的常用方法2.3 Properties 的应用场景2.4 实例 3.序列化3.1 ObjectOutputStream 4.字符编码4.1 ASCII…

【计算机网络】期末考试预习复习|中

作业讲解 转发器、网桥、路由器和网关(4-6) 作为中间设备,转发器、网桥、路由器和网关有何区别? (1) 物理层使用的中间设备叫做转发器(repeater)。 (2) 数据链路层使用的中间设备叫做网桥或桥接器(bridge)。 (3) 网络层使用的中间设备叫做路…

Edge Scdn用起来怎么样?

Edge Scdn:提升网站安全与性能的最佳选择 在当今互联网高速发展的时代,各种网络攻击层出不穷,特别是针对网站的DDoS攻击威胁,几乎每个行业都可能成为目标。为了确保网站的安全性与稳定性,越来越多的企业开始关注Edge …

UE4_控件蓝图_制作3D生命血条

一:效果图如下: 二、实现步骤: 1、新建敌人 右键蓝图类 选择角色, 重命名为BP_Enemytest。 双击打开,配置敌人网格体 修改位置及朝向 效果如下: 选择合适的动画蓝图类: 人物就有了动作&#x…