第十章 FreeRTOS的时间片调度

目录

一.时间片调度

1.1 简介

1.2 时间片调度运行举例

1.3 总结

二. 时间片调度实验

2.1使能宏

2.2 滴答定时器中断频率

2.3 代码示例


一.时间片调度

1.1 简介

同等优先级任务轮流地享有相同的 CPU 时间(可设置),叫时间片;

在FreeRTOS中,一个时间片就等于SysTick中断周期。在源码中,SysTick中断服务函数1ms中断一次,一个时间片就是1ms,滴答定时器SysTick的中断周期可以自己设置。

1.2 时间片调度运行举例

运行条件:

1.创建三个任务:Task1、Task2、Task3
2.Task1、Task2、Task3的优先级均为1;即3个任务同等优先级

运行过程如下:

1、首先Task1运行完一个时间片后,切换至Task2运行(不管Task1是否运行完成,只能运行一个时间片)
2、Task2运行完一个时间片后,切换至Task3运行
3、Task3运行过程中(还不到一个时间片),Task3阻塞了(系统延时或等待信号量等,下次轮到Task3时还是只允许一个时间片,上次阻塞剩余的时间片,不会再被补回来),此时直接切换到下一个任务Task1
4、Task1运行完一个时间片后,切换至Task2运行

1.3 总结

1. 同等优先级任务,轮流执行,时间片流转;
2. 一个时间片大小,取决为滴答定时器中断频率;
3. 注意没有用完的时间片不会再使用,下次任务Task3得到执行还是按照一个时间片的时钟节拍运行。


二. 时间片调度实验

2.1使能宏

#define configUSE_PREEMPTION         1 /* 1: 抢占式调度器, 0: 协程式调度器, 无默认需定义 */
#define configUSE_TIME_SLICING       1 /* 1: 使能时间片调度, 默认: 1 */

2.2 滴答定时器中断频率

/* 定义系统时钟节拍频率, 单位: Hz, 无默认需定义 */
#define configTICK_RATE_HZ        20   //时钟节拍频率,这里设置为20,周期就是50ms

2.3 代码示例

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"
#include "key.h"

/*START任务的基本配置*/
#define START_STK_SIZE 128
#define START_TASK_PRIO 1
TaskHandle_t	start_task_handler;
void StartTask_fun(void * pvParameters);

/*TASK1任务的基本配置*/
#define TASK1_STK_SIZE 128
#define TASK1_PRIO 		2	
TaskHandle_t	task1_handler;
void TASK1(void * pvParameters);

/*TASK2任务的基本配置*/
#define TASK2_STK_SIZE 128
#define TASK2_PRIO 		2	
TaskHandle_t	task2_handler;
void TASK2(void * pvParameters);


void freertosdemo()
{
	xTaskCreate((TaskFunction_t	)	StartTask_fun,		//任务函数	
				(char * 		) 	"StartTask_fun",	//任务名字
				(uint16_t		) 	START_STK_SIZE,		//堆栈大小
				(void * 		) 	NULL,				//任务参数
				(UBaseType_t	) 	START_TASK_PRIO,	//任务优先级
				(TaskHandle_t *	) 	&start_task_handler);//任务句柄
				
	vTaskStartScheduler();          //开启任务调度
}

/*
	START任务创建 TASK1任务
*/
void StartTask_fun(void * pvParameters)
{
	taskENTER_CRITICAL();           //进入临界区		临界区内的代码在执行过程中不被其它中断或者任务打断
	
	xTaskCreate((TaskFunction_t	)	TASK1,		//任务函数	
				(char * 		) 	"TASK1",	//任务名字
				(uint16_t		) 	TASK1_STK_SIZE,	//堆栈大小
				(void * 		) 	NULL,			//任务参数
				(UBaseType_t	) 	TASK1_PRIO,		//任务优先级
				(TaskHandle_t *	) 	&task1_handler);//任务句柄
					
	xTaskCreate((TaskFunction_t	)	TASK2,			//任务函数	
				(char * 		) 	"TASK2",		//任务名字
				(uint16_t		) 	TASK2_STK_SIZE,	//堆栈大小
				(void * 		) 	NULL,			//任务参数
				(UBaseType_t	) 	TASK2_PRIO,		//任务优先级
				(TaskHandle_t *	) 	&task2_handler);//任务句柄			
	taskEXIT_CRITICAL();            //退出临界区
	vTaskDelete(NULL);				//删除任务
}

/*由于时间片设置为50ms,所以每一个任务,同等享有50ms的cpu时间*/
/*通过串口打印task1的运行次数*/
void TASK1(void * pvParameters)
{
	uint32_t task1_num = 0;
	while(1)
	{
		taskENTER_CRITICAL();           //进入临界区
		printf("task1运行次数:%d\r\n",++task1_num);
		taskEXIT_CRITICAL();            //退出临界区
		delay_ms(10);
	}
}

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


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值