嵌入式FreeRTOS学习十一,深入理解任务调度机制

一.任务调度机制

  • 可抢占:高优先级的任务先运行
  • 时间片轮转:同优先级的任务轮流执行
  • 空闲任务礼让:如果有同是优先级为0的其他就绪任务,空闲任务主动放弃一次运行机会
  • 函数调用vTaskDelay( xDelay5ms )可以主动放弃任务执行,让出CPU使用权
  • 系统中最低优先级中断比最高优先级任务大
int main( void )
{
	prvSetupHardware();
	
	xTaskCreate(vTask1, "Task 1", 1000, NULL, 0, NULL);
	xTaskCreate(vTask2, "Task 2", 1000, NULL, 0, NULL);
	xTaskCreate(vTask3, "Task 3", 1000, NULL, 2, NULL);

	/* 启动调度器 */
	vTaskStartScheduler();

	/* 如果程序运行到了这里就表示出错了, 一般是内存不足 */
	return 0;
}

=========================================================================

二.空闲任务函数 portTASK_FUNCTION( prvIdleTask, pvParameters )

static portTASK_FUNCTION( prvIdleTask, pvParameters )
{    
    ( void ) pvParameters;   
    portALLOCATE_SECURE_CONTEXT( configMINIMAL_SECURE_STACK_SIZE );
    for( ; ; )
    {      
        prvCheckTasksWaitingTermination();
        #if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) )
            {               
                if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) 1 )
                {
                    taskYIELD();
                }
                else
                {
                    mtCOVERAGE_TEST_MARKER();
                }
            }
        #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) */
        #if ( configUSE_IDLE_HOOK == 1 )
            {
                extern void vApplicationIdleHook( void );               
                vApplicationIdleHook();
            }
        #endif /* configUSE_IDLE_HOOK */
        #endif /* configUSE_TICKLESS_IDLE */
    }
}

FreeRTOS操作系统中配置项 configUSE_PREEMPTION == 1表示同等优先级之间可抢占,配置项configIDLE_SHOULD_YIELD == 1 表示表示主动礼让,只有在任务可抢占的情况下,才考虑空闲礼让的情况。 

如果 配置选项配置为configUSE_PREEMPTION == 0不抢占的情况,那么直接进行礼让 taskYIELD(),任何其他的情况发生都是直接礼让。可抢占的时候可以配置是否礼让,不抢占中有礼让的这一种情况。

在空闲任务portTASK_FUNCTION中,会对任务就绪链表里的任务进行一次判断,如果当前任务就绪链表长度listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) )大于1,那么说明链表里面出了空闲任务外,还有其他的优先级为0的任务。那么空闲任务马上就做出任务礼让。其中tskIDLE_PRIORITY =0,即pxReadyTasksLists[ 0 ] 。

 礼让了其他任务以后,空闲任务函数执行 taskYIELD() 礼让其他任务,让其他任务先运行,函数执行到taskYIELD()后马上启动任务调度函数,任务调度函数执行任务Task1,任务Task2,任务Task3,等这三个任务运行完后,再执行回去执行空闲任务函数,从上次礼让的位置继续执行下去。

=========================================================================

可抢占可礼让的情况下,任务执行的的顺序是idle_task 执行一会后,马上执行任务Task 1,是否会执行任务Task 2,任务Task 3还得看任务是否会轮流执行。

在 xTaskIncrementTick函数中可以看到,只有配置成configUSE_PREEMPTION == 1可抢占和 configUSE_TIME_SLICING == 1时间片轮转的情况,任务Task2才可以得到执行。 不抢占不轮转,任务Task2永远得不到运行。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

肖爱Kun

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

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

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

打赏作者

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

抵扣说明:

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

余额充值