基于正点原子FreeRTOS学习笔记——时间片调度实验

news/2024/7/9 5:54:52 标签: 学习, 笔记

目录

一、时间片调度介绍

二、实验演示

1、宏修改

1.1、滴答定时器宏

1.2、调度器宏

2、实验程序

2.1.1、任务1,任务2不加临界区程序

2.1.2 实验现象

2.2.1、任务1,任务2加临界区程序

 2.2.2 实验现象


一、时间片调度介绍

时间片:同等优先级任务轮流地享有相同的CPU时间

在FreeRTOS中,一个时间片等于SysTick中断周期。如果需要修改时间片时间长短,就要修改滴答定时器中断频率。

如果任务提前结束,直接进行下一个任务,没有用完的时间不会在使用,无论是下一个任务还是本任务再次执行都按一个时间片节拍运行。

运行过程:

1、Task1运行完一个时间片后,切换到Task2运行

2、Task2运行完一个时间片后,切换到Task3运行

3、Task3运行过程中,Task3阻塞了(系统延时或等待信号量等),此时直接切换到下一个任务

二、实验演示

1、宏修改

1.1、滴答定时器宏

#define configTICK_RATE_HZ      20      /* 定义系统时钟节拍频率, 单位: Hz, 无默认需定义 */

实验要求一个时间片是50ms,则设置为20Hz

1.2、调度器宏

#define configUSE_PREEMPTION     1     /* 1: 抢占式调度器, 0: 协程式调度器, 无默认需定义 */

#define configUSE_TIME_SLICING     1    /* 1: 使能时间片调度, 默认: 1 */

都设置为1

2、实验程序

2.1.1、任务1,任务2不加临界区程序

/******************************************************************************************************/
/*FreeRTOS配置*/

/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_STACK_SIZE 128
#define START_TASK_PRIO       1
TaskHandle_t start_task_handler;

void start_task( void * pvParameters );

#define TASK1_STACK_SIZE 128
#define TASK1_PRIO       2
TaskHandle_t task1_handler;
void task1( void * pvParameters );

#define TASK2_STACK_SIZE 128
#define TASK2_PRIO       2
TaskHandle_t task2_handler;
void task2( void * pvParameters );
/******************************************************************************************************/


/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */
void freertos_demo(void)
{
		xTaskCreate( (TaskFunction_t        ) start_task,
					 (char *                ) "start_task",
					 (configSTACK_DEPTH_TYPE) START_TASK_STACK_SIZE,
					 (void *                ) NULL,
					 (UBaseType_t           ) START_TASK_PRIO,
					 (TaskHandle_t *        ) &start_task_handler );
    vTaskStartScheduler();
}

void start_task( void * pvParameters )
{
	taskENTER_CRITICAL();/*进入临界区*/
		xTaskCreate( (TaskFunction_t        ) task1,
					 (char *                ) "task1",
					 (configSTACK_DEPTH_TYPE) TASK1_STACK_SIZE,
					 (void *                ) NULL,
					 (UBaseType_t           ) TASK1_PRIO,
					 (TaskHandle_t *        ) &task1_handler );
								 
		xTaskCreate( (TaskFunction_t        ) task2,
					 (char *                ) "task2",
					 (configSTACK_DEPTH_TYPE) TASK2_STACK_SIZE,
					 (void *                ) NULL,
					 (UBaseType_t           ) TASK2_PRIO,
					 (TaskHandle_t *        ) &task2_handler );						 
		
		vTaskDelete(NULL);
		taskEXIT_CRITICAL(); 		/*退出临界区*/				 
}

void task1( void * pvParameters )
{
	uint32_t task1_num = 0;
	while(1)
	{
		printf("task1运行次数:%d\r\n",++task1_num);
		delay_ms(10);//FreeRTOS的延迟函数会将任务挂载到阻塞列表,导致任务提前结束
								//而delay_ms()只会死等		
	}
}

void task2( void * pvParameters )
{
	uint32_t task2_num = 0;
	while(1)
	{
		printf("task2运行次数:%d\r\n",++task2_num);
		delay_ms(10);		
	}
	
	
}

2.1.2 实验现象

打印出运行次数,但是会出现打印的不完整。因为本次任务未执行完,调度器切换到下一个任务

2.2.1、任务1,任务2加临界区程序

/******************************************************************************************************/
/*FreeRTOS配置*/

/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_STACK_SIZE 128
#define START_TASK_PRIO       1
TaskHandle_t start_task_handler;

void start_task( void * pvParameters );

#define TASK1_STACK_SIZE 128
#define TASK1_PRIO       2
TaskHandle_t task1_handler;
void task1( void * pvParameters );

#define TASK2_STACK_SIZE 128
#define TASK2_PRIO       2
TaskHandle_t task2_handler;
void task2( void * pvParameters );
/******************************************************************************************************/


/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */
void freertos_demo(void)
{
		xTaskCreate( (TaskFunction_t        ) start_task,
					(char *                ) "start_task",
					(configSTACK_DEPTH_TYPE) START_TASK_STACK_SIZE,
					(void *                ) NULL,
					(UBaseType_t           ) START_TASK_PRIO,
					(TaskHandle_t *        ) &start_task_handler );
    vTaskStartScheduler();
}

void start_task( void * pvParameters )
{
	taskENTER_CRITICAL();/*进入临界区*/
		xTaskCreate( (TaskFunction_t        ) task1,
					(char *                ) "task1",
					(configSTACK_DEPTH_TYPE) TASK1_STACK_SIZE,
					(void *                ) NULL,
					(UBaseType_t           ) TASK1_PRIO,
					(TaskHandle_t *        ) &task1_handler );
								 
		xTaskCreate( (TaskFunction_t        ) task2,
					(char *                ) "task2",
					(configSTACK_DEPTH_TYPE) TASK2_STACK_SIZE,
					(void *                ) NULL,
					(UBaseType_t           ) TASK2_PRIO,
					(TaskHandle_t *        ) &task2_handler );						 
		
		vTaskDelete(NULL);
		taskEXIT_CRITICAL(); 		/*退出临界区*/				 
}

void task1( void * pvParameters )
{
	uint32_t task1_num = 0;
	while(1)
	{
		taskENTER_CRITICAL();/*进入临界区*/
		printf("task1运行次数:%d\r\n",++task1_num);
		delay_ms(10);//FreeRTOS的延迟函数会将任务挂载到阻塞列表,导致任务提前结束
								//而delay_ms()只会死等
		taskEXIT_CRITICAL(); 		/*退出临界区*/			
	}
}

void task2( void * pvParameters )
{
	uint32_t task2_num = 0;
	while(1)
	{
		taskENTER_CRITICAL();/*进入临界区*/
		printf("task2运行次数:%d\r\n",++task2_num);
		delay_ms(10);
		taskEXIT_CRITICAL(); 		/*退出临界区*/			
	}
	
	
}

 2.2.2 实验现象

可以看到由于临界区保护,都打印出了完整的信息


http://www.niftyadmin.cn/n/5538557.html

相关文章

EasyExcel导入合并单元格数据

1.EasyExcel.read 方法 这里在read的时候要注意,增加这个extraRead(CellExtraTypeEnum.MERGE)来解析合并单元格的信息 ImportListener listener new ImportListener();try {EasyExcel.read(file.getInputStream(), ImportDto.class, listener).headRowNumber(1).e…

万和-集训刷题1

leetcode 2 两数之和 class Solution {public ListNode addTwoNumbers(ListNode l1, ListNode l2) {ListNode p1l1;ListNode p2l2;int next0;ListNode headnew ListNode(-1);ListNode tailhead;while (p1!null||p2!null){int n1p1!null?p1.val:0;int n2p2!null?p2.val:0;i…

7月6日 VueConf 技术大会即将在深圳举办

7月6日,VueConf 2024 即将在深圳召开,本次大会正值 Vue.js 十周年,旨在聚焦 Vue.js 社区的成员,分享最新的技术动态、经验以及创新实践。 本次参与 VueConf 大会的是来自全球 Vue.js 核心团队成员、行业专家及前端开发者。其中&a…

将CSV、Excel、XML文件转换为MySQL数据库

在平时的工作中,经常会遇到需要将文件数据导入到数据库中的情况。有些客户之前可能只使用Excel表格作为记录工具,但当数据量达到一定程度或者需要将数据导入到其他系统中时,就会很emo,因为Excel表格虽然方便,但在数据处理和管理方…

Hadoop3:Yarn的Tool接口案例

一、需求 依然以wordcount案例为基础,进行开发 我们知道,用hadoop自带的example.jar执行wordcount 命令如下 hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount -D mapreduce.job.queuename…

用Redis实现排行榜的详细用例

下面是一个使用 Redis 的 Sorted Set 数据结构实现的排行榜系统的详细示例,包括查看全部排名、获取单个排名、增加分数等操作。我们将使用 Lettuce 库来与 Redis 进行交互。 项目结构 pom.xml:添加必要的依赖。LeaderBoardService:实现排行…

在CenteOs7上安装mysql8.0(Super详细版)

在CenteOs7上安装mysql8.0 为什么用Mysql8.0?如何下载下载地址需要提前准备下载步骤 服务器上安装如何上传到服务器?通过wget下载到服务器并解压 开始安装非必须安装如果全部安装执行顺序 安装完后,启动mysql使用“systemctl”检测mysqld服务…

2个方法教你轻松移除pdf文件编辑限制

PDF是一种常见的办公文档格式,常用于文件共享和保护。然而,有时候我们需要编辑PDF文件中的内容,但受到了编辑限制。本文将介绍一些有效的方法,帮助您解除PDF的编辑限制,轻松进行编辑和修改。 一、通过密码取消PDF“限制…