STM32F407ZGT6-UCOSIII笔记4:时间片轮转调度

news2025/2/27 8:39:03

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

编写熟悉一下  UCOSIII系统的  时间片轮转调度

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

目录

解决上文的卡系统问题:

使能时间片轮转调度:

任务初始化定义更改:

文件结构提要:

任务函数文件:

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

目前各个文件任务: 

#include "main.h"

#include "ComTask.h"

 #include "MessageTask.h"

 #include "CalculateTask.h"

下载测试效果: 

测试工程下载:


解决上文的卡系统问题:

上文讲到在MessageTask任务中使用打印函数会卡系统:

任务栈太小,导致卡系统,将原先的 128 改为 256 就解决了:

使能时间片轮转调度:

先确认 OS_CFG_SCHED_ROUND_ROBIN_EN 定义为 1

查看 OSCfg_TickRate_Hz  定义多大,这是系统时钟节拍频率:

本工程直接在Comtask启动时获取并打印一次:

然后调用函数初始化时间片轮转:

任务初始化定义更改:

这里先更改一下任务初始化的一些定义:

这步更改是设置每个任务的时间片:

修改这俩任务优先级相同:

文件结构提要:

这里赘述一些文件结构,本文不详细解释,在往前的文章有更详细介绍:

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

任务函数文件:

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

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

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

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

任务块头文件  #include "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	  )2,					//之前为0 //2个时间片 2*5ms
                 (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	  )2,					//之前为0 //2个时间片 2*5ms
                 (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();	//进入临界区
}

#include "ComTask.h"

 

#include "ComTask.h"


/*
	ComTask 
	删除CalculateTask
	ComTask 打印自己运行次数
	打印俩次 ComTask 
	后等待800ms
*/	

void comTask(void * p_arg)
{
	OS_ERR err;
	int i=0,OSTime_tickRate,j;
	
	p_arg = p_arg;
		
	OSTime_tickRate=OSCfg_TickRate_Hz;            //获取系统节拍频率,(该宏定义在 OS_CFG_APP.H)
	UsartPrintf(USART1, "OSCfg_TickRate_Hz = %d Hz \r\n",OSTime_tickRate);  //打印系统节拍频率
	OSTaskDel((OS_TCB*)&CalculateTaskTaskTCB,&err);             //删除CalculateTask 
	UsartPrintf(USART1, "ComTask delete CalculateTask !\r\n");	//打印删除 CalculateTask 提示
	
	while (DEF_TRUE)
	{
		i++;
		UsartPrintf(USART1, "ComTask Print%d\r\n",i);		

		for(j=0;j<2;j++)
		{
			UsartPrintf(USART1, "ComTask \r\n");	
		}

		OSTimeDlyHMSM(0,0,0,800,OS_OPT_TIME_HMSM_STRICT,&err); //延时800ms
		
	}
}

 #include "MessageTask.h"

 

#include "MessageTask.h"

/*
	MessageTask
	打印自己运行次数 
	打印俩次 MessageTask
	后等待800ms
*/
void MessageTask (void * p_arg)
{
	OS_ERR err;
	int i=0,j;
	p_arg = p_arg;
	while (DEF_TRUE)
	{
		i++;
		UsartPrintf(USART1, "MessageTask Print%d\r\n",i);	//之前这里会卡系统,因为任务栈太小 MessageTask_STK_SIZE 128,现改为256
		
		for(j=0;j<2;j++)
		{
			UsartPrintf(USART1, "MessageTask \r\n");
		}	
		
		OSTimeDlyHMSM(0,0,0,800,OS_OPT_TIME_HMSM_STRICT,&err); //延时800ms
	}
	
}

 #include "CalculateTask.h"

 本文CalculateTask一开始就被ComTask删了就不贴了

下载测试效果: 

 俩个同优先级 任务能够正常进行运行打印:

测试工程下载:

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

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

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

相关文章

谭浩强C++课后练习(更新中)

基于过程的程序设计 第1章 C的初步知识 1. 请根据你的了解&#xff0c;叙述C的特点。C对C有哪些发展? 2. 一个 C程序是由哪几部分构成的?其中的每一部分起什么作用? 3. 从接到一个任务到得到最终结果&#xff0c;一般要经过几个步骤? 4. 请说明编辑、编译、连接的作用…

单元测试知识总结

我们希望每段代码都是自测试的&#xff0c;每次改动之后&#xff0c;都能自动发现对现有功能的影响。 1 测试要求 在对软件单元进行动态测试之前&#xff0c;应对软件单元的源代码进行静态测试&#xff1b; 应建立测试软件单元的环境&#xff0c;如数据准备、桩模块、模拟器…

前后端跨域问题(CROS)

前端 在src中创建util文件&#xff0c;写request.js文件&#xff1a; request.js代码如下&#xff1a; import axios from axios import { ElMessage } from element-plus;const request axios.create({// baseURL: /api, // 注意&#xff01;&#xff01; 这里是全局统一加…

【数据结构——查找】顺序查找(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 测试说明 我的通关代码: 测试结果&#xff1a; 任务描述 本关任务&#xff1a;实现顺序查找的算法。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;1.根据输入数据建立顺序表&#xff0c;2.顺序表的输出&#xff0c;…

Android 车载虚拟化底层技术-Kernel 5.15 -Android13(multi-cards)技术实现

系列文章请扫点击如下链接&#xff01; Android Display Graphics系列文章-汇总 本文主要包括部分&#xff1a; 一、Android13的Kernel 5.15版本 1.1 Kernel 5.15 情况说明 1.2 前置条件 二、QCM61*5 plane配置 2.1 multi-card配置 2.2 移植msm-lease 2.3 配置信息确认…

【FFmpeg】FFmpeg 内存结构 ⑥ ( 搭建开发环境 | AVPacket 创建与释放代码分析 | AVPacket 内存使用注意事项 )

文章目录 一、搭建开发环境1、开发环境搭建参考2、项目搭建 二、AVPacket 创建与释放代码分析1、AVPacket 创建与释放代码2、Qt 单步调试方法3、单步调试 - 分析 AVPacket 创建与销毁代码 三、AVPacket 内存使用注意事项1、谨慎使用 av_init_packet 函数2、av_init_packet 函数…

C# DLT645 97/07数据采集工具

电表模拟器 97协议测试 07协议测试 private void btnSend_Click(object sender, EventArgs e) {string addr txtAddr.Text.Trim();string data txtDataFlg.Text.Trim();byte control 0x01;switch (cmbControl.SelectedIndex){case 0: control (byte)0x01; break;// 97协议c…

颜色代码表: 一站式配色方案设计工具集网站

大家好&#xff0c;我是一名设计师&#xff0c;同时也是一名开发者。平时的工作中&#xff0c;相信很多设计师和我一样经常遇到一个问题&#xff1a;设计配色方案时&#xff0c;工具太分散了。寻找颜色搭配灵感需要去一个网站&#xff0c;颜色代码转换要开另一个&#xff0c;检…

Android显示系统(13)- 向SurfaceFlinger提交Buffer

Android显示系统&#xff08;01&#xff09;- 架构分析 Android显示系统&#xff08;02&#xff09;- OpenGL ES - 概述 Android显示系统&#xff08;03&#xff09;- OpenGL ES - GLSurfaceView的使用 Android显示系统&#xff08;04&#xff09;- OpenGL ES - Shader绘制三角…

WebSocket 与 Server-Sent Events (SSE) 的对比与应用

目录 ✨WebSocket&#xff1a;全双工通信的利器&#x1f4cc;什么是 WebSocket&#xff1f;&#x1f4cc;WebSocket 的特点&#x1f4cc;WebSocket 的优点&#x1f4cc;WebSocket 的缺点&#x1f4cc;WebSocket 的适用场景 ✨Server-Sent Events (SSE)&#xff1a;单向推送的轻…

Mysql 深度分页查询优化

Mysql 分页优化 1. 问题根源 问题&#xff1a; mysql在数据量大的时候&#xff0c;深度分页数据偏移量会增大&#xff0c;导致查询效率越来越低。 问题根源&#xff1a; 当使用 LIMIT 和 OFFSET 进行分页时&#xff0c;MySQL 必须扫描 OFFSET LIMIT 行&#xff0c;然后丢弃前…

SpringBoot - 动态端口切换黑魔法

文章目录 关键技术点核心原理Code 关键技术点 利用 Spring Boot 内嵌 Servlet 容器 和 动态端口切换 的方式实现平滑更新的方案&#xff0c;关键技术点如下&#xff1a; Servlet 容器重新绑定端口&#xff1a;Spring Boot 使用 ServletWebServerFactory 动态设置新端口。零停…

linux(CentOS8)安装PostgreSQL16详解

文章目录 1 下载安装包2 安装3 修改远程连接4 开放端口 1 下载安装包 官网下载地址&#xff1a;https://www.postgresql.org/download/ 选择对应版本 2 安装 #yum源 yum -y install wget https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redha…

spring学习(spring-bean实例化(无参构造与有参构造方法实现)详解)

目录 一、spring容器之bean的实例化。 &#xff08;1&#xff09;"bean"基本概念。 &#xff08;2&#xff09;spring-bean实例化的几种方式。 二、spring容器使用"构造方法"的方式实例化bean。 &#xff08;1&#xff09;无参构造方法实例化bean。 &#…

ElasticSearch学习5

基本Rest命令说明&#xff1a; method url地址 描述 PUT&#xff08;创建,修改&#xff09; localhost:9200/索引名称/类型名称/文档id 创建文档&#xff08;指定文档id&#xff09; POST&#xff08;创建&#xff09; localhost:9200/索引名称/类型名称 创建文档&…

分享本周所学——三维重建算法3D Gaussian Splatting(3DGS)

大家好&#xff0c;欢迎来到《分享本周所学》第十二期。本人是一名人工智能初学者&#xff0c;刚刚读完大二。前几天自学了一下3D Gaussian Splatting&#xff08;3DGS&#xff09;&#xff0c;觉得非常有意思。写这篇文章主要是因为网上大部分关于3DGS的文章都比较晦涩&#x…

【中工开发者】鸿蒙商城app

这学期我学习了鸿蒙&#xff0c;想用鸿蒙做一个鸿蒙商城app&#xff0c;来展示一下。 项目环境搭建&#xff1a; 1.开发环境&#xff1a;DevEco Studio2.开发语言&#xff1a;ArkTS3.运行环境&#xff1a;Harmony NEXT base1 软件要求&#xff1a; DevEco Studio 5.0.0 Rel…

【Qt】按钮类控件:QPushButton、QRadioButton、QCheckBox、ToolButton

目录 QPushButton 例子&#xff1a; QRadioButton 例子&#xff1a; 按钮的常见信号函数 单选按钮分组 例子&#xff1a; QCheckButton 例子&#xff1a; QToolButton QWidget的常见属性及其功能对于它的派生类控件都是有效的(也就是Qt中的各种控件)&#xff0c;包括…

UI框架DevExpress XAF v24.2新功能预览 - .NET Core / .NET增强

DevExpress XAF是一款强大的现代应用程序框架&#xff0c;允许同时开发ASP.NET和WinForms。DevExpress XAF采用模块化设计&#xff0c;开发人员可以选择内建模块&#xff0c;也可以自行创建&#xff0c;从而以更快的速度和比开发人员当前更强有力的方式创建应用程序。 在上文中…

ArrayList源码分析、扩容机制面试题,数组和List的相互转换,ArrayList与LinkedList的区别

目录 1.java集合框架体系 2. 前置知识-数组 2.1 数组 2.1.1 定义&#xff1a; 2.1.2 数组如何获取其他元素的地址值&#xff1f;&#xff08;寻址公式&#xff09; 2.1.3 为什么数组索引从0开始呢&#xff1f;从1开始不行吗&#xff1f; 3. ArrayList 3.1 ArrayList和和…