微型操作系统内核源码详解系列四(4):操作系统调度算法(FreeRTOS内核篇下)

本文主要是介绍微型操作系统内核源码详解系列四(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内核篇下)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1059855

相关文章

Spring Cloud LoadBalancer 负载均衡详解

《SpringCloudLoadBalancer负载均衡详解》本文介绍了如何在SpringCloud中使用SpringCloudLoadBalancer实现客户端负载均衡,并详细讲解了轮询策略和... 目录1. 在 idea 上运行多个服务2. 问题引入3. 负载均衡4. Spring Cloud Load

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

在 Spring Boot 中使用 @Autowired和 @Bean注解的示例详解

《在SpringBoot中使用@Autowired和@Bean注解的示例详解》本文通过一个示例演示了如何在SpringBoot中使用@Autowired和@Bean注解进行依赖注入和Bean... 目录在 Spring Boot 中使用 @Autowired 和 @Bean 注解示例背景1. 定义 Stud

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为

SQL 中多表查询的常见连接方式详解

《SQL中多表查询的常见连接方式详解》本文介绍SQL中多表查询的常见连接方式,包括内连接(INNERJOIN)、左连接(LEFTJOIN)、右连接(RIGHTJOIN)、全外连接(FULLOUTER... 目录一、连接类型图表(ASCII 形式)二、前置代码(创建示例表)三、连接方式代码示例1. 内连接(I

Go路由注册方法详解

《Go路由注册方法详解》Go语言中,http.NewServeMux()和http.HandleFunc()是两种不同的路由注册方式,前者创建独立的ServeMux实例,适合模块化和分层路由,灵活性高... 目录Go路由注册方法1. 路由注册的方式2. 路由器的独立性3. 灵活性4. 启动服务器的方式5.

Java中八大包装类举例详解(通俗易懂)

《Java中八大包装类举例详解(通俗易懂)》:本文主要介绍Java中的包装类,包括它们的作用、特点、用途以及如何进行装箱和拆箱,包装类还提供了许多实用方法,如转换、获取基本类型值、比较和类型检测,... 目录一、包装类(Wrapper Class)1、简要介绍2、包装类特点3、包装类用途二、装箱和拆箱1、装

Go语言中三种容器类型的数据结构详解

《Go语言中三种容器类型的数据结构详解》在Go语言中,有三种主要的容器类型用于存储和操作集合数据:本文主要介绍三者的使用与区别,感兴趣的小伙伴可以跟随小编一起学习一下... 目录基本概念1. 数组(Array)2. 切片(Slice)3. 映射(Map)对比总结注意事项基本概念在 Go 语言中,有三种主要

Python中Markdown库的使用示例详解

《Python中Markdown库的使用示例详解》Markdown库是一个用于处理Markdown文本的Python工具,这篇文章主要为大家详细介绍了Markdown库的具体使用,感兴趣的... 目录一、背景二、什么是 Markdown 库三、如何安装这个库四、库函数使用方法1. markdown.mark

PLsql Oracle 下载安装图文过程详解

《PLsqlOracle下载安装图文过程详解》PL/SQLDeveloper是一款用于开发Oracle数据库的集成开发环境,可以通过官网下载安装配置,并通过配置tnsnames.ora文件及环境变... 目录一、PL/SQL Developer 简介二、PL/SQL Developer 安装及配置详解1.下