本文主要是介绍微型操作系统内核源码详解系列四(4):操作系统调度算法(FreeRTOS内核篇下),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
系列一:微型操作系统内核源码详解系列一:rtos内核源码概论篇(以freertos为例)-CSDN博客
系列二:微型操作系统内核源码详解系列二:数据结构和对象篇(以freertos为例)-CSDN博客
系列三:微型操作系统内核源码详解系列三(0):空间存储及内存管理篇(前置篇)-CSDN博客
微型操作系统内核源码详解系列三(1):任务及切换篇(任务函数定义)-CSDN博客
微型操作系统内核源码详解系列三(2):任务及切换篇(任务函数定义)-CSDN博客
微型操作系统内核源码详解系列三(3):任务及切换篇(任务函数定义)-CSDN博客
微型操作系统内核源码详解系列三(4):arm架构篇-CSDN博客
微型操作系统内核源码详解系列三(5):进程与线程-CSDN博客
系列四:
微型操作系统内核源码详解系列四(1):操作系统调度算法(linux0.11版本内核)-CSDN博客
微型操作系统内核源码详解系列四(2):操作系统调度算法(rt-thread内核)-CSDN博客
微型操作系统内核源码详解系列四(3):操作系统调度算法(FreeRTOS内核篇上)-CSDN博客
微型操作系统内核源码详解系列四(4):操作系统调度算法(FreeRTOS内核篇下)-CSDN博客
从前面几篇博客我们学习到了几种不同操作系统的调度算法,其实这些调度算法的核心思想都是可以互相联系的。
下面笔者讲解FreeRTOS根据arm架构指令优化的方法:
其实它跟RTT的图标法思想是类似的,但是对过程进行了简化。
这是另一种选择算法:
让我们先看一下这个指令__clz,这个指令会计算从最高位到第一个1之间的0的个数。参考文章:arm clz指令c语言,协处理器及其他指令之:零计数指令CLZ-CSDN博客
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) __clz( ( uxReadyPriorities ) ) )
让我们回忆一下,在RTT内核篇,为了得到第一个1的位置,我们使用了图表法,计算8个位所有出现情况,根据每个不同的数字,我们利用函数算出来了它对应的第一个1在哪里,这样,我们只要把这个数字作为下标,就能以o(1)的时间复杂度找出来这个数字对应的最高优先级是什么。
这种算法的缺点是,空间资源消耗过大。
现在我们有了这个指令clz,所以我们可以很方便的计算位图中1之前的0的个数,而不用去图表中查找。
先看这个函数:
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities )
( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
它被宏定义为taskRECORD_READY_PRIORITY函数,这其实就是根据就绪任务的优先级,把变量uxTopReadyPriority相关的位置1,与上一篇的通用算法对任务的处理类似,每一个任务被添加到就绪列表时,它对应的位置1,进行延时等其他放弃cpu使用权的活动时,它被移除就绪列表,对应的位置0;这两种算法,一个是更新最高优先级的数字,另一个则是更新对应的位,其实这两个之间有一点细微的差别,就是在移除就绪列表的任务时通用算法不用更新,而指令算法要更新,至于原因,笔者已经在上一篇写了。
对应的函数:
当然,实际上是要确认这个优先级对应的链表是否含有多个任务的,为了方便讲解,笔者默认每个优先级只有一个任务。
现在让我们来到taskSELECT_HIGHEST_PRIORITY_TASK函数:
上面已经讲解过了portGET_HIGHEST_PRIORITY函数,我们通过这个指令获得了最高优先级任务的数字,configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 );同理,是断言,用来调试,判断这个链表的长度是否大于0,也就是是否有任务,如果没有,那么这个判断的真值就是0,就会触发这个断言。
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) );
同理,当获取最高优先级,判断优先级上面有任务时,就会把pxCurrentTCB的值更新,它代表下一个要被切换的任务,将会在pendsv中断中完成上下文切换。
综上,FreeRTOS的调度算法算是讲完了,笔者花费众多篇幅将调度器的框架抽象出来,如果读者能够理解FreeRTOS内核的本质其实就是一个调度器的话,那么其实已经差不多理解实时操作系统的核心了。顺着这个主干,那些枝叶都是能够衍生出来的,这也就是为什么笔者要从入口一路切入到调度算法的原因,其他的部分笔者会在之后的篇章陆陆续续更新,不过笔者太懒了,也可能某天就断更了 ʅ(´◔౪◔)ʃ
这篇关于微型操作系统内核源码详解系列四(4):操作系统调度算法(FreeRTOS内核篇下)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!