FreeRTOS-时间片调度

一、时间片调度简介

  • 同等优先级任务轮流的享有相同的CPU时间(可设置),叫时间片,在FreeRTOS中,一个时间片就等于SysTick中断周期,所以说时间片大小取决于滴答定时器中断频率
  • 运行完Task1一个时间片后,切换到Task2,Task2运行完一个时间片后,切换到Task3运行
  • 假设Task3运行到一半时,Task3被阻塞(系统延时或等待信号量等)了,此时直接切换到Task1
    在这里插入图片描述

二、时间片调度实验

  • 实验设计:三个任务:start_task、task1、task2,其中task1和task2优先级相同均为2。为了使得现象明显,将抵达定时器的中断频率设置为50ms一次,即一个时间片50ms
  • 注意辨别FreeRTOS自带延时函数和系统延时函数的区别,使用FreeRTOS延时函数时,会阻塞任务,从而直接运行下一任务,系统延时函数会直接等待结束
#define configUSE_TIME_SLICING					1
#define configUSE_PREEMPTION					1//使用时间片调度需要置宏为1
#define configSUPPORT_DYNAMIC_ALLOCATION		1//动态创建任务宏定义配置
#define configTICK_RATE_HZ						20//对应时间片50ms

//start_task参数宏定义
#define	START_TASK_STACK_SIZE 								128//堆栈大小
#define	START_TASK_PRIO										1//任务优先级
TaskHandle_t	start_task_handle;							//任务句柄
//task1参数宏定义
#define	TASK1_STACK_SIZE 									128//堆栈大小
#define	TASK1_PRIO											2//任务优先级
TaskHandle_t	task1_handle;								//任务句柄
//task2参数宏定义
#define	TASK2_STACK_SIZE 									128//堆栈大小
#define	TASK2_PRIO											2//任务优先级
TaskHandle_t	task2_handle;								//任务句柄


//task1任务函数:打印task1运行次数,大概是一个时间片4-5次
void task1( void * pvParameters )
{
		uint32_t task1_num = 0;
		while(1)
		{
			taskENTER_CRITICAL();//进入临界区,这里不加临界区,会使得task1和task2打印出错
			printf("%d\r\n",++task1_num);//打印task1运行次数
			delay_ms(10);//系统死等延时函数,不会阻塞产生调度
			taskEXIT_CRITICAL();//退出临界区
		}
}
//task2任务函数:打印task2运行次数
void task2( void * pvParameters )
{
		uint32_t task2_num = 0;
		while(1)
		{
			taskENTER_CRITICAL();//进入临界区
			printf("%d\r\n",++task2_num);//打印task2运行次数
			delay_ms(10);
			taskEXIT_CRITICAL();//退出临界区
		}
}
//Start_task任务函数
void Start_task( void * pvParameters )
{
		taskENTER_CRITICAL();//进入临界区
		//创建任务1
		xTaskCreate(task1,//任务函数
					"task1",//任务名称
					TASK1_STACK_SIZE,//堆栈大小/字
					NULL,//入口参数没有
					TASK1_PRIO,//优先级
					&task1_handle//任务句柄
					);
		//创建任务2
		xTaskCreate(task2,//任务函数
					"task2",//任务名称
					TASK2_STACK_SIZE,//堆栈大小/字
					NULL,//入口参数没有
					TASK2_PRIO,//优先级
					&task2_handle//句柄
					);
		vTaskDelete(start_task_handle);
		//删除自身任务Start_task,start_task_handle或NULL都可以
		taskEXIT_CRITICAL();//退出临界区
}

//FreeRTOS入口函数,程序从此处开始执行
void freertos_demo()
{
		xTaskCreate(Start_task,//任务函数
					"Start_task",//任务名称
					START_TASK_STACK_SIZE,//堆栈大小/字
					NULL,//入口参数没有
					START_TASK_PRIO,//优先级
					&start_task_handle//句柄
					);//创建Start任务
		vTaskStartScheduler();//开启任务调度器,开启执行Start任务,创建task12
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值