FreeRTOS(V8.0.1)系统之vTaskSuspendAll()和xTaskResumeAll()

//如果一个临界区太长而不适合简单地关中断来实现,可以考虑采用挂起调度器的方式。但是唤醒(resuming, or un-suspending)调度器却是一个
//相对较长的操作。所以评估哪种是最佳方式需要结合实际情况。如果某个中断在调度器挂起过程中要求进行上下文切换,则个这请求也会被
//挂起,直到调度器被唤醒后才会得到执行
void vTaskSuspendAll( void )
{
	//通过挂起调度器来创建临界区,挂起调度器有些时候也被称为锁定调度器
	++uxSchedulerSuspended;//系统维护一个uxSchedulerSuspended计数值,当其大于0时表示禁止调度;等于0时则表示允许调度。
	//返回值 在调度器挂起过程中,上下文切换请求也会被挂起,直到调度器被唤醒后才会得到执行。
	//如果一个挂起的上下文切换请求在xTaskResumeAll()返回前得到执行,则函数返回pdTRUE,表示CPU要求被抢占,
	//在其它情况下,xTaskResumeAll()返回pdFALSE,然后根据返回值,强制使任务交出CPU(或者叫做任务切换)
}


 
 
//如果一个临界区太长而不适合简单地关中断来实现,可以考虑采用挂起调度器的方式。但是唤醒(resuming, or un-suspending)调度器却是一个
//相对较长的操作。所以评估哪种是最佳方式需要结合实际情况。如果某个中断在调度器挂起过程中要求进行上下文切换,则个这请求也会被
//挂起,直到调度器被唤醒后才会得到执行
BaseType_t xTaskResumeAll ( void )
{
TCB_t *pxTCB;
BaseType_t xAlreadyYielded = pdFALSE;
	//在禁止调度任务期间,若ISR导致了一个任务的就绪,这个任务就会放到xPendingReadyList中,
	//一旦调度允许,必须把所有xPendingReadyList中的任务移动到一个合适的就绪链表中。
	//要考虑调度器被挂起时,放在xPendingReadyList链表中的任务
	taskENTER_CRITICAL();//关中断,进入临界区
	{
		--uxSchedulerSuspended;//调度器挂起计数器减一操作,如果仍大于0,则不止一个任务使调度器挂起;直到调度器不再挂起,则进入以下操作
		if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
		{
			if( uxCurrentNumberOfTasks > ( UBaseType_t ) 0U )
			{
				//目前正在运行的任务数是否大于0,如果大于0,则进入以下操作,否则跳出本函数
				//移除所有的被调度器挂起时就绪的任务,进入合适的就绪链表,直到xPendingReadyList链表为空
				while( listLIST_IS_EMPTY( &xPendingReadyList ) == pdFALSE )
				{
					pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyList ) );
					( void ) uxListRemove( &( pxTCB->xEventListItem ) );
					( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
					prvAddTaskToReadyList( pxTCB );
					//我们转移的任务是否有比当前任务的优先级高的,如果有,则抢占申请成功,进行任务切换
					if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )//新获取任务的优先级不低于当前任务的优先级
					{
						xYieldPending = pdTRUE;//任务切换被使能
					}
					else
					{
						mtCOVERAGE_TEST_MARKER();
					}
				}
				//在调度器被挂起的时间之内,是否有丢失未处理的滴答数。uxMissedTicks是丢失的滴答数
				if( uxPendedTicks > ( UBaseType_t ) 0U )//若在任务挂起了则其值的改变在心跳时钟中++。若大于0说明有丢失的时钟数。
				{
					while( uxPendedTicks > ( UBaseType_t ) 0U )
					{
						if( xTaskIncrementTick() != pdFALSE )	//模拟进入心跳时钟中断,若!pdFALSE则说明进行任务切换。即:补齐缺失的滴答数。
						{
							xYieldPending = pdTRUE;//允许任务切换
						}
						else
						{
							mtCOVERAGE_TEST_MARKER();
						}
						--uxPendedTicks;//将丢失的时钟数--,保证其准确性。
					}
				}
				else
				{
					mtCOVERAGE_TEST_MARKER();
				}

				if( xYieldPending == pdTRUE )//若允许任务切换
				{
					#if( configUSE_PREEMPTION != 0 )//若使用抢占式的系统
					{
						xAlreadyYielded = pdTRUE;//返回值设为已经切换成功
					}
					#endif
					taskYIELD_IF_USING_PREEMPTION();//启用抢占式的方式进行任务切换
				}
				else
				{
					mtCOVERAGE_TEST_MARKER();
				}
			}
		}
		else
		{
			mtCOVERAGE_TEST_MARKER();
		}
	}
	taskEXIT_CRITICAL();

	return xAlreadyYielded;//返回任务是否已经切换;已经切换返回pdTRUE;反之返回pdFALSE。
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值