微型操作系统内核源码详解系列四(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

相关文章

Python 字典 (Dictionary)使用详解

《Python字典(Dictionary)使用详解》字典是python中最重要,最常用的数据结构之一,它提供了高效的键值对存储和查找能力,:本文主要介绍Python字典(Dictionary)... 目录字典1.基本特性2.创建字典3.访问元素4.修改字典5.删除元素6.字典遍历7.字典的高级特性默认字典

MySQL 主从复制部署及验证(示例详解)

《MySQL主从复制部署及验证(示例详解)》本文介绍MySQL主从复制部署步骤及学校管理数据库创建脚本,包含表结构设计、示例数据插入和查询语句,用于验证主从同步功能,感兴趣的朋友一起看看吧... 目录mysql 主从复制部署指南部署步骤1.环境准备2. 主服务器配置3. 创建复制用户4. 获取主服务器状态5

一文详解如何使用Java获取PDF页面信息

《一文详解如何使用Java获取PDF页面信息》了解PDF页面属性是我们在处理文档、内容提取、打印设置或页面重组等任务时不可或缺的一环,下面我们就来看看如何使用Java语言获取这些信息吧... 目录引言一、安装和引入PDF处理库引入依赖二、获取 PDF 页数三、获取页面尺寸(宽高)四、获取页面旋转角度五、判断

Spring Boot中的路径变量示例详解

《SpringBoot中的路径变量示例详解》SpringBoot中PathVariable通过@PathVariable注解实现URL参数与方法参数绑定,支持多参数接收、类型转换、可选参数、默认值及... 目录一. 基本用法与参数映射1.路径定义2.参数绑定&nhttp://www.chinasem.cnbs

MySql基本查询之表的增删查改+聚合函数案例详解

《MySql基本查询之表的增删查改+聚合函数案例详解》本文详解SQL的CURD操作INSERT用于数据插入(单行/多行及冲突处理),SELECT实现数据检索(列选择、条件过滤、排序分页),UPDATE... 目录一、Create1.1 单行数据 + 全列插入1.2 多行数据 + 指定列插入1.3 插入否则更

Redis中Stream详解及应用小结

《Redis中Stream详解及应用小结》RedisStreams是Redis5.0引入的新功能,提供了一种类似于传统消息队列的机制,但具有更高的灵活性和可扩展性,本文给大家介绍Redis中Strea... 目录1. Redis Stream 概述2. Redis Stream 的基本操作2.1. XADD

Spring StateMachine实现状态机使用示例详解

《SpringStateMachine实现状态机使用示例详解》本文介绍SpringStateMachine实现状态机的步骤,包括依赖导入、枚举定义、状态转移规则配置、上下文管理及服务调用示例,重点解... 目录什么是状态机使用示例什么是状态机状态机是计算机科学中的​​核心建模工具​​,用于描述对象在其生命

Java JDK1.8 安装和环境配置教程详解

《JavaJDK1.8安装和环境配置教程详解》文章简要介绍了JDK1.8的安装流程,包括官网下载对应系统版本、安装时选择非系统盘路径、配置JAVA_HOME、CLASSPATH和Path环境变量,... 目录1.下载JDK2.安装JDK3.配置环境变量4.检验JDK官网下载地址:Java Downloads

使用Python删除Excel中的行列和单元格示例详解

《使用Python删除Excel中的行列和单元格示例详解》在处理Excel数据时,删除不需要的行、列或单元格是一项常见且必要的操作,本文将使用Python脚本实现对Excel表格的高效自动化处理,感兴... 目录开发环境准备使用 python 删除 Excphpel 表格中的行删除特定行删除空白行删除含指定

MySQL中的LENGTH()函数用法详解与实例分析

《MySQL中的LENGTH()函数用法详解与实例分析》MySQLLENGTH()函数用于计算字符串的字节长度,区别于CHAR_LENGTH()的字符长度,适用于多字节字符集(如UTF-8)的数据验证... 目录1. LENGTH()函数的基本语法2. LENGTH()函数的返回值2.1 示例1:计算字符串