【FreeRTOS】任务调度算法

目录
1.是否抢占优先级configUSE_PREEMPTION
2. 是否进行时间片轮转configUSE_TIME_SLICING
3. 空闲函数是否礼让configIDLE_SHOULD_YIELD
4. 实验
5. 特殊情况

在FreeRTOS中,Tick中断来执行任务调度,所谓的Tick中断,就是程序每执行固定时间后系统会发生定时器中断。
怎么来管理处于不同状态的任务?将不同状态的任务放在不同的链表内,等待态放在DelayList,暂停态放在SuspendedList,就绪态的任务放在ReadyList,就绪态的任务有5个优先级。当任务需要从就绪态转换为运行态的时候,先找到就绪态中最高优先级的任务运行。如果同一优先级的话就轮流执行,然后每个任务执行一个tick后排在链表最后面。

任务调度算法需要查看FreeRTOSConfig.h文件

1.是否抢占优先级

configUSE_PREEMPTION 当高优先级的任务处于就绪状态时,是否可以抢占优先级,打断低优先级任务的执行
设置为1则允许抢占优先级,设置0则不允许抢占优先级

2.是否进行时间片轮转

configUSE_TIME_SLICING 同等优先级的任务是否具有轮流执行的功能,如果不进行配置的话,当某个任务获得执行权之后在该任务结束之前会一直执行
设置为1则允许进行时间片轮转,设置0则不允许进行时间片轮转

3.空闲任务是否让步

configIDLE_SHOULD_YIELD 空闲任务是否具有礼让其他任务的功能,如果有同是优先级为0的其他就绪任务,空闲任务获取运行资格后,只运行一遍进行礼让,而其他任务运行一个tick周期
设置为1则空闲任务让步,设置0则空闲任务不让步

4.实验

任务1和空闲任务的优先级为0,任务2的优先级为2,程序如下:

static void prvSetupHardware( void );
static int task1flag=0;
static int task2flag=0;
static int taskIdleflag=0;


void Task1Function(void *param)
{
	while(1)
	{
		task1flag=1;
		task2flag=0;
		taskIdleflag=0;
		printf("1");
	}
}

void Task2Function(void *param)
{
	while(1)
	{
		task1flag=0;
		task2flag=1;
		taskIdleflag=0;
		printf("2");
		vTaskDelay(2);
	}
}

void vApplicationIdleHook(void)
{
	task1flag=0;
	task2flag=0;
	taskIdleflag=1;
	printf("0");
}


StackType_t xIdleTaskStack[100];
StaticTask_t xIdelTaskTCB;

void	vApplicationGetIdleTaskMemory(StaticTask_t ** ppxIdleTaskTCBBuffer,
									StackType_t ** ppxIdleTaskStackBuffer,
									uint32_t * pulIdleTaskStackSize)
{
	*ppxIdleTaskTCBBuffer=&xIdelTaskTCB; 
	*ppxIdleTaskStackBuffer=xIdleTaskStack;
	*pulIdleTaskStackSize=100;
}		


int main( void )
{

 TaskHandle_t xHandleTask1;

	prvSetupHardware();

	printf("Hello World!\r\n");

	xTaskCreate(Task1Function,"Task1",100,NULL,0,&xHandleTask1);
	xTaskCreate(Task2Function,"Task2",100,NULL,2,NULL);
	
	/* Start the scheduler. */
	vTaskStartScheduler();
	return 0;
}

实验一:

configUSE_PREEMPTION=0, configUSE_TIME_SLICING=0,configIDLE_SHOULD_YIELD=0不允许抢占优先级,不允许时间片轮转,不允许空闲函数礼让。代码显示,当不抢占的时候,空闲任务永远礼让,虽然配置了不礼让,但只要不抢占就礼让

任务2优先级最高先执行,执行之后进入阻塞状态,然后任务1开始执行,由于不允许抢占优先级,也不允许时间片轮转,则任务1一直执行,结果如下:
在这里插入图片描述
实验二:

configUSE_PREEMPTION=1, configUSE_TIME_SLICING=0,configIDLE_SHOULD_YIELD=0允许抢占优先级,不允许时间片轮转,不允许空闲函数礼让

任务2任务2优先级最高先执行,执行之后进入阻塞两个tick状态,然后任务1开始执行;任务2再次进入运行状态,抢占优先级,执行之后进入阻塞两个tick状态,然后空闲任务开始执行;循环上面的过程,结果如下:
在这里插入图片描述
实验三:

configUSE_PREEMPTION=1, configUSE_TIME_SLICING=1,configIDLE_SHOULD_YIELD=0允许抢占优先级,允许时间片轮转,不允许空闲函数礼让

任务2优先级最高先执行,执行之后进入阻塞两个tick状态,然后任务1和空闲任务进行时间片轮转,任务2再次进入运行状态,重复上面过程,结果如下:
在这里插入图片描述
实验四:

configUSE_PREEMPTION=1, configUSE_TIME_SLICING=0,configIDLE_SHOULD_YIELD=1允许抢占优先级,不允许时间片轮转,允许空闲函数礼让

任务2优先级最高先执行,执行之后进入阻塞两个tick状态,任务1执行;任务2再次执行,再次阻塞,然后空闲任务执行一次,马上礼让task1运行,循环伤处操作,结果如下:
在这里插入图片描述
实验五:

configUSE_PREEMPTION=1, configUSE_TIME_SLICING=1,configIDLE_SHOULD_YIELD=1允许抢占优先级,允许时间片轮转,允许空闲函数礼让
在这里插入图片描述

5.特殊情况

1.当任务1,任务2和空闲任务的优先级都为0时,如果先创建任务1,再创建任务2,启动调度器时会创建空闲任务,则任务执行时,先执行任务1,在执行任务2,再执行空闲任务。
在这里插入图片描述

在这里插入图片描述

2.当任务1,任务2的优先级为1,空闲任务的优先级都为0时,如果先创建任务1,再创建任务2,启动调度器时会创建空闲任务,则任务执行时,先执行任务2,在执行任务1。
在这里插入图片描述
在这里插入图片描述
原因:如果后创建任务的优先级大于等于当前任务的优先级,则当前TCB指向后创建的任务,然后任务按顺序执行

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值