//如果一个临界区太长而不适合简单地关中断来实现,可以考虑采用挂起调度器的方式。但是唤醒(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。
}
STM8CubeMX和STM32CubeMX功能一样吗?
这个暑假,我们不一样 量子计算科普教育基地
基于杂波协方差矩阵特征向量分析STAP降维方法
宝马自动驾驶车辆的折叠式方向盘专利
中国移动联合咪咕与竟盟发布了5G+VR炫风行动
FreeRTOS(V8.0.1)系统之vTaskSuspendAll()和xTaskResumeAll()
小米11全球首发安卓最强芯片骁龙888
零跑 C11 1 月 1 日正式开启预售:双电机四驱、配备高通骁龙第三代数字座舱平台
生物传感器的工作原理及在智能医疗中的应用
了解您的IC:LM386
基于飞轮储能阵列的新型DVR串联型电压恢复器
什么是5.1声道扬声器?
致创新!贸泽电子入驻2015 IIC-China创客专区
福特正开发数字道路安全工具,可预测潜在的道路交通事故热点
大数据需要用到什么编程语言
网络安全 | 巧合?严重RCE漏洞竟被意外修复...
简析DLP大屏幕的安装和保养知识
联发科技CES 2011曝光首款120Hz偏光/快门式3D电
万丰科技超3亿美元收购美国焊接机器人公司PASLIN
开关电源基本知识科普