“野火FreeRTOS教程”第9章知识点总结-空闲任务与阻塞延时

前言

在第7章我们知道在创建任务并启动任务调度器后,当前任务控制块是指向第一个任务(即pxCurrentTCB = &Task1TCB),然后会产生SVC中断,将pxCurrentTCB出栈至CPU寄存器切换至任务1。
在任务1函数的最后会执行taskYield,taskYield会产生PendSVC中断,先将任务1入栈,然后将当前任务控制块指向第二个任务(即pxCurrentTCB = &Task2TCB),再将pxCurrentTCB出栈至CPU寄存器切换至任务2。在任务2函数的最后也是如此切换至任务1。

本章知识点

在本章,在启动任务调度器时,还会同时把空闲任务创建起来,并启动滴答定时器及其中断,然后在产生的SVC中断中切换至任务1。在滴答定时器中断中会先将所有任务的倒计时个数减1,再调用taskYield完成任务切换,如下图:
在这里插入图片描述

在任务1函数中,会通过vTaskDelay函数来给当前任务赋以倒计时个数(即延时时长)并调用taskYield完成任务切换,如下图:
在这里插入图片描述
在这里插入图片描述
注意这里taskYield产生PendSVC中断中的任务切换不再是任务1时切任务2这样简单了,而是会通过一个复杂一些的算法来切换,如下代码:

void vTaskSwitchContext( void )
{
	if ( pxCurrentTCB == &IdleTaskTCB ) //当前为空闲任务时
	{
		if (Task1TCB.xTicksToDelay == 0)//任务1延时倒计时结束了
		{
			pxCurrentTCB =&Task1TCB;
		}
		else if (Task2TCB.xTicksToDelay == 0)//任务2延时倒计时结束了
		{
			pxCurrentTCB =&Task2TCB;
		}
		else //任务延时均没有到期则返回,继续执行空闲任务
		{return;}
	}
	else //当前不是空闲任务
	{
		if (pxCurrentTCB == &Task1TCB)//当前为任务1时
		{
			if (Task2TCB.xTicksToDelay == 0)
			{
				pxCurrentTCB =&Task2TCB;
			}
			else if (pxCurrentTCB->xTicksToDelay != 0)//任务1延时倒计时没结束
			{
				pxCurrentTCB = &IdleTaskTCB;
			}
			else //返回,不进行切换,因为两个任务都处于延时中
			{return;}
		}
		else if (pxCurrentTCB == &Task2TCB)//当前为任务2时
		{
			if (Task1TCB.xTicksToDelay == 0)
			{
				pxCurrentTCB =&Task1TCB;
			}
			else if (pxCurrentTCB->xTicksToDelay != 0)//任务2延时倒计时没结束
			{
				pxCurrentTCB = &IdleTaskTCB;
			}
			else //返回,不进行切换,因为两个任务都处于延时中
			{return;}
		}
	}//end of当前不是空闲任务
}

举例

在这里插入图片描述
最后的波形应该是这样的,如下:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hi,Man go!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值