μC/OS-III 里面的环形表

文章目录

    • 1、时钟节拍任务
    • 2、定时器列表

μC/OS-III 里面两个地方用到了环形表,时钟节拍任务,定时器列表,通过排序后,效率是非常高的。
以下内容整理自 嵌入式实时操作系统uC/OS-Ⅲ

1、时钟节拍任务

全空的时钟节拍列表

2023/12/21 18:04:16

(1) 该时钟节拍列表由一个数据表(见 os_cfg_app.c 中的 OSCfg_TickWheel[]) 和一个计数器(OSTickCtr)构成。

(2) OSCfg_TickWheel[] 数据表包含的表项(entry)数目是由 os_cfg_app.h 文件中的 OS_CFG_TICK_WHEEL_SIZE 设定的,可在编译时进行配置。表项的具体数目要根据处理器中可用的 RAM 存储量和应用程序中的最大任务数来配置。一般可以把 OS_CFG_TICK_WHEEL_SIZE 的值设置为任务数目的1/4左右。建议不要使 OS_CFG_TICK_WHEEL_SIZE 的数值与时钟节拍的频率成倍数关系。如果时钟节拍频率是1000 Hz并且在用户的应用中有50个任务,那么用户应当避免把 OS_CFG_TICK_WHEEL_SIZE 的数值设置为10或20,而应当改为使用11或23。实际上,最好使用素数来设置 OS_CFG_TICK_WHEEL_SIZE。虽然在编译时很难预计运行时将会发生的事情,但理论上可以使在每个表项上等待的任务的数目均匀分布。

(3) 该数据表中的每个表项包含3个成员:

  • .NbrEntriesMax 表示在该表项上等待的任务的最大数目。应用程序可以通过调用函数 OSStatReset() 来重置 .NbrEntriesMax 的值。

  • .NbrEntries 表示在该表项上等待的任务的数目。

  • .FirstPtr 是一个指针变量,在表头上并属于该表,指向在该表项上的等待任务构成的双向链表(通过各任务的 TCB 结构体)。

每当任务 OS_TickTask() 接收到时钟节拍中断发送的信号时,它会将 OSTickCtr 加1。

当应用程序中的某个任务调用 OSTimeDlyXXX() 函数或者使用非零的超时值调用 OSXXXPend() 函数时,该任务会被自动插入到时钟节拍列表中。
在这里插入图片描述
MatchValue = 10 + 13
OSCfg_TickWheel[] spoke number = (10 + 13) * 2

MatchValue = 23
OSCfg_TickWheel[] spoke number = 11

第二个任务会插入到与第一个任务相同的表项中,如图 F5-11 所示。在同一个表项上等待的多个任务按照升序排列,因此,剩余等待时间最少的任务会放在时钟节拍列表的最前面。

在时钟节拍任务执行时(见 os_tick.c 文件中的 OSTickTask()OSTickListUpdate()),它首先会递增 OSTickCtr 的数值,然后判断应该处理哪个表项。如果位于该表项上的时钟节拍列表中有任务存在(即 .FirstPtr 非空),则时钟节拍任务会检查相关任务的 .TickCtrMatch 数值是否与 OSTickCtr 数值相同,如果相同,就会把相应的 OS_TCB 从时钟节拍列表中删除。如果该任务只是等待延时结束,则将会被放入任务就绪表中(后面会描述)。如果该任务在等待某个事件,则不仅需要把它从时钟节拍列表中删除,还需要把它从该事件的任务等待表中删除。在搜索时钟节拍列表时,一旦发现 OSTickCtr 的数值与任务的 .TickCtrMatch 数值不相等,就会立即结束该搜索操作。这是因为延时最先结束的任务总是放在表的最前面。

在这里插入图片描述
如果前面的任务延时还没有结束,那么后面的任务延时时间显然也没有到,也就没有必要再进一步搜索了。
注意,OS TickTask()在更新时钟节拍列表时所做的大部分工作都是在临界段代码中完成的。不过,由于时钟节拍列表是按照顺序排列的,因此,可以把临界区控制得相当短

时钟节拍中断服务程序仅需唤醒时钟节拍任务,可大大缩短中断处理时间。时钟节拍任务使用了一个由N个表项(即辐条)构成的环形数据表(即时钟节拍轮),N的数值由用户配置。所有延时的任务按照延时结束时刻分配到各个表项上,每次节拍中断发生时,只有其中一个表项上的任务可能延时结束。在各个表项上,任务按照延时结束的先后顺序排序。因此,时钟节拍任务每次被节拍中断唤醒后,只处理一个表项,从该表项中的第一个任务开始判断任务延时是否结束,延时结束则继续判断下一个任务,否则停止判断并返回,从而大大节省时间节拍处理时间。

2、定时器列表

在这里插入图片描述
F12-8(1) 定时器列表结构中含有一个表 (OSCfg_TmrWheel[],在 os_cfg_app.c 中声明) 和一个计数器 (OSTmrTickCtr,在 os.h 中声明)。

F12-8(2) 这个表可以容纳的条目数的最大值由参数 OS_CFG_TMR_WHEEL_SIZE 决定,可以在编译时设定(见 os_cfg_app.h)。实际的条目数取决于处理器可用的 RAM 大小和应用程序中的最大定时器数量。建议将 OS_CFG_TMR_WHEEL_SIZE 设为定时器数量的 1/4 左右。不建议将 OS_CFG_TMR_WHEEL_SIZE 设为定时器任务率的偶数倍。例如,如果定时器任务率是10Hz,请避免将 OS_CFG_TMR_WHEEL_SIZE 设为10或100(可以使用11或101)。最好使用素数。尽管在编译时很难预测运行时的情况,但在理想情况下,每个表项中定时器的数量应该是均匀分布的。

F12-8(3) 表中的每个条目包括三个字段:.NbrEntriesMaxNbrEntries.FirstPtr

  • .NbrEntries 表示链接到这个条目的定时器数量。
  • .NbrEntriesMax 用来跟踪表中的最大条目数。
  • .FirstPtr 包括一个指向当前位置上定时器双向链表的指针(通过 OS_TMR)。

每次时钟节拍中断服务程序 (ISR) 发送信号给定时器任务时,OSTmrTickCtr 增加1。

要将定时器插入定时器列表中,需要调用函数 OSTmrStart()。当然,定时器必须在使用之前先创建。

在这里插入图片描述
μC/OS-II将计算匹配值和序号,如下所示:

  • MatchValue = 12 + 10
  • OSCfg_TmrWheel[]中的序号 = 22


MatchValue = 22
OSCfg_TmrWheel[]中的序号 = 4

如图 F12-10 所示,第二个定时器插入到同一个条目指向的链表中,并且系统将根据定时器的剩余时间排序,将剩余时间较少的定时器排在链表头,而剩余时间最长的定时器排在链表尾。

在这里插入图片描述
当定时器任务执行时(见 os_tmr.cOS_TmrTask()),OSTmrTickCtr 开始加 1 并指向下一个辐条格子。如果此条中含有定时器(即 .FirstPtr 非空),那么第一个 S_TMR.Match 都会被检查是否与 OSTmrTickCtr 匹配。如果找到匹配的 OS_TMR,则将其从列表中移除,并且检查下一个,然后 OS_TmrTask() 将调用定时器回调函数(假设定时器创建时已定义)。反之,若 OSTmrTickCtr 不匹配定时器的 .Match 值,则查找过程立即结束。原因是链表已经排序,不需要再继续向后查找。

注意,OS_TmrTask() 执行时调度器是上了锁的。由于链表已经排序,并且查找过程在找不到匹配值后立即结束,因此临界代码段比较短。

备注:由于 OS_TMR 链表按照定时器的剩余时间从小到大排序,所以它们的 .Match 值也是按照相同顺序排列的。如果 OSTmrTickCtr 小于链表中某个定时器的 .Match 值,那么后面的定时器也一定都不匹配,可以停止查找并等待下一次比较。正是这样的轮设计和排序链表,使得系统大大减少了遍历每个定时器所需的时间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/237290.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数论】约数

试除法求约数 时间复杂度 O(sqrt(n))。 核心思路是求到较小的约数时,将其对应的较大约数也可以直接求出来, 例如:a/bc,b是a的余数,c也是a的余数 ps:注意bc的情况,要注意去重 void solve() …

JavaGUI(但期末速成版)之事件监听和处理

点击返回标题->JavaGUI期末速成版-CSDN博客 前言 依旧先声明,本篇记录的JavaGUI编程都是十分精简的,内容只取常用的、套路的、应付期末考试的。 我先放两张ppt的原内容。。。 看完(我觉得你可能都没看完),摊牌了&a…

赴日IT培训课程 程序员新思路!

先说好,跟国内相比,日本IT并不发达。日本IT是依托着日本传统强势的制造业和政府机关发展的,所以开发的大多数软件也是面向这些的,由于日本人的严谨态度,各种文档的编写层出不穷,不像国内程序员每天没日没夜…

android 新版studio gradle 里面没有offline 勾选项

studio 右边 gradle 上面有个图标可以点击切换

【深度学习】注意力机制(七)Agent Attention

本文介绍Agent Attention注意力机制,Transformer中的Attention模块可以提取全局语义信息,但是计算量太大,Agent Attention是一种计算非常有效的Attention模块。 论文:Agent Attention: On the Integration of Softmax and Linear…

前端手动部署与自动化部署

连接服务器 先购买服务器 安装vscode插件 连接服务器 连接成功 手动部署 安装nginx 启动nginx systemctl start nginx systemctl status nginx systemctl enable nginx启动 检查状态 开机就启动nginx 开始手动部署 配置nginx 成功

走过的2023:在挑战中领悟,在仿徨中成长

转眼间就到了2023年的最后一个月,回顾这短暂而又有意义的一年,可以用12个字总结:在挑战中领悟,在仿徨中成长。这篇文章我会从技术成长、职场生活、读书感悟和个人生活等几个方面,总结一下过去的这一年,梳理…

【玩转TableAgent数据智能分析】——个人体验分享

文章目录 前言上手体验优势不足 再次体验第三次体验第四次体验1、找到高价房源和低价房源的特点,看清民宿行业的整体布局2、了解各个地域的整体价格,优选潜力城市3、对比各个城市的评分,深入了解不同城市的民宿市场特点4、对比不同床型价格&a…

Java AQS 阻塞式锁和相关同步器工具的框架

8 J.U.C Java 并发工具包 AQS 原理 AQS:AbstractQueuedSynchronizer(抽象队列同步器),阻塞式锁和相关同步器工具的框架 特点: 用 state 属性来表示资源的状态(分独占模式和共享模式)&#…

TCP/IP 传输层协议

传输层定义了主机应用程序之间端到端的连通性。传输层中最为常见的两个协议分别是传输控制协议TCP(Transmission Control Protocol)和用户数据包协议UDP(User Datagram Protocol)。 TCP协议 TCP是一种面向连接的传输层协议&#…

esp32-s3解决使用蓝牙ble一键配网时,蓝牙ble内存使用的内部空间,空间不足时可采用外部PSRAM

idf.py menuconfig进入到esp32配置界面,配置NimBLE使用外部PSRAM内存即可

pip 离线安装:利用pypi网站进行模块 库的离线安装

离线安装是一种很好的方法,在网络不佳、库版本不明确、复杂库本地编译安装报错时,通过whl文件的下载安装,可以很高效的解决问题。 pypi的网站:https://pypi.org/ 这个网站包含各种你 pip install xxx 的库,离线安装可…

我做了一个在手机灵动岛锁屏看实时网速/步数/下班倒计时/跑步距离/照片/待办/倒计时/手机使用次数/帧率...的软件

我做了一个在手机灵动岛&锁屏看实时网速/步数/下班倒计时/跑步距离/照片/待办/倒计时/手机使用次数/帧率…的软件 Island Widgets 的作用: 提醒您 : 准时下班每天运动陪伴家人保持体重放下手机每日待办当前网速手机使用强度实时热搜现在天气… 初…

Python库学习(十三):爬虫框架Scrapy

微信搜索【猿码记】查看更多文章... 1.介绍 Scrapy是一个用于爬取网站数据的Python框架。它提供了一套强大而灵活的工具,使开发者能够轻松地创建和管理爬虫,从而从网站中提取所需的信息。框架要求Python的版本 3.8 Github Star:49.6k: https://github.c…

【Linux】Linux线程概念和线程控制

文章目录 一、Linux线程概念1.什么是线程2.线程的优缺点3.线程异常4.线程用途5.Linux进程VS线程 二、线程控制1.线程创建2.线程终止3.线程等待4.线程分离 一、Linux线程概念 1.什么是线程 线程是进程内的一个执行流。 我们知道,一个进程会有对应的PCB,…

GEE-Sentinel-2月度时间序列数据合成并导出

系列文章目录 第一章:时间序列数据合成 文章目录 系列文章目录前言时间序列数据合成总结 前言 利用每个月可获取植被指数数据取均值,合成月度平均植被指数,然后将12个月中的数据合成一个12波段的时间数据合成数据。 时间序列数据合成 代码…

ROS2 学习09--ros 中的通信接口的定义以及如何创建自定义msg、srv和action文件

在ROS系统中,无论话题还是服务,或者我们后续将要学习的动作,都会用到一个重要的概念——通信接口。 通信并不是一个人自言自语,而是两个甚至更多个人,你来我往的交流,交流的内容是什么呢?为了让…

数值分析(只为应付考试)

概述 研一时为应付高等工程数学考试整理的有关数值分析部分的内容,目的是为了应付考试。 误差 误差限与有效数字的联系 对于有 n n n 位有效数字的 x x x 的近似值 x ∗ x^* x∗, 其科学计数法表示形式 x ∗ a 1 . a 2 . . . a n 1 0 m ( a 1 ≠ 0 ) x^* …

Python开发GUI常用库PyQt6和PySide6介绍之二:设计师(Designer)

Python开发GUI常用库PyQt6和PySide6介绍之二:设计师(Designer) PySide6和PyQt6都有自己的设计师(Designer),用于可视化地设计和布局GUI应用程序的界面。这些设计师提供了丰富的工具和功能,使开…

文件名生成excel清单,怎么操作?这里有简单办法

文件名生成excel清单,怎么操作?为了整理文件名称,有时候需要将所有的文件名称整理好并且生成excel清单,大家可能还不能理解是什么意思,其实就是将所有文件的名称整理到excel表格里,形成一个清单。这个操作很…