(学习日记)2024.03.13:UCOSIII第十五节:基于时基列表的时延操作(持续更新)

本文主要是介绍(学习日记)2024.03.13:UCOSIII第十五节:基于时基列表的时延操作(持续更新),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

写在前面:
由于时间的不足与学习的碎片化,写博客变得有些奢侈。
但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。
既然如此
不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录,记录笔者认为最通俗、最有帮助的资料,并尽量总结几句话指明本质,以便于日后搜索起来更加容易。


标题的结构如下:“类型”:“知识点”——“简短的解释”
部分内容由于保密协议无法上传。


点击此处进入学习日记的总目录

2024.03.13

  • 二十九、UCOSIII:基于时基列表的时延操作
    • 1、配置时钟中断时间
    • 2、创建任务
    • 3、任务放置到就绪列表中,并优先级排队
    • 4、将任务插入时基列表
      • 1. 确认时延
      • 2.对任务进行排序
      • 3. 确认插入时基列表哪个成员
      • 4. 对就绪列表的操作

二十九、UCOSIII:基于时基列表的时延操作

1、配置时钟中断时间

/* 配置SysTick 10ms 中断一次 */OS_CPU_SysTickInit (10);

在中断触发时运行OSTimeTick()函数

/* SysTick 中断服务函数 */
void SysTick_Handler(void)
{OSTimeTick();
}

OSTimeTick()函数定义如下:

void  OSTimeTick (void)
{/* 更新时基列表 */OS_TickListUpdate();/* 任务调度 */OSSched();
}

很明显,系统需要10ms一个时钟周期,每一个时钟周期更新一次时基列表

2、创建任务

创建任务需要使用 OSTaskCreate()函数,这部分和之前相同,不再概述。

任务指针格式如下:

struct os_tcb {CPU_STK         *StkPtr;CPU_STK_SIZE    StkSize;/* 任务延时周期个数 */OS_TICK         TaskDelayTicks;/* 任务优先级 */OS_PRIO         Prio;/* 就绪列表双向链表的下一个指针 */OS_TCB          *NextPtr;/* 就绪列表双向链表的前一个指针 */OS_TCB          *PrevPtr;/* 时基列表相关字段 */OS_TCB          *TickNextPtr;OS_TCB          *TickPrevPtr;	OS_TICK_SPOKE   *TickSpokePtr;	OS_TICK         TickCtrMatch;	OS_TICK         TickRemain;		
};

3、任务放置到就绪列表中,并优先级排队

任务创建好之后,会放到就绪列表中,并在优先级列表对应值中设为1
上述在之前章节已整理,本次不再概述。

4、将任务插入时基列表

当任务需要延时时,使用OS_TickListInsert()函数将任务插入时基列表。

/* 将一个任务插入时基列表,根据延时时间的大小升序排列 */
void  OS_TickListInsert (OS_TCB *p_tcb,OS_TICK time)

在这里插入图片描述
时基列表OSCfg_TickWheel[]OS_CFG_TICK_WHEEL_SIZE个成员。

OS_CFG_TICK_WHEEL_SIZE的推 荐值为任务数/4,不推荐使用偶数。
如果算出来是偶数,则加1变成质数,实际上质数是一个很好的选择。

时基列表OSCfg_TickWheel[]每个成员有三个值。

typedefstruct  os_tick_spoke       OS_TICK_SPOKE;
//在μC/OS-III中,内核对象的数据类型都会用大写字母重新定义。struct  os_tick_spoke {OS_TCB              *FirstPtr;//每个成员都包含一条单向链表, 被插入该条链表的TCB会按照延时时间做升序排列。//FirstPtr用于指向这条单向链表的第一个节点。OS_OBJ_QTY           NbrEntries;//NbrEntries表示该条单向链表当前有多少个节点。OS_OBJ_QTY           NbrEntriesMax;//NbrEntriesMax记录该条单向链表最多的时候有多少个节点, 在增加节点的时候会刷新,在删除节点的时候不刷新。
};

在这里插入图片描述

1. 确认时延

当任务需要插入到时基列表中时,首先需要确认需要时延几个周期,即TickRemain的值。
然后确认OSTickCtr的值,将TickRemainOSTickCtr相加得到TickCtrMatch

OSTickCtr是一个全局变量, 记录的是系统自启动以来或者自上次复位以来经过了多少个SysTick周期。
OSTickCtr的值每经过一个SysTick周期其值就加一

2.对任务进行排序

众所周知,任务随时都有可能加入到时基列表中,那么怎么能高效的将各个任务按时延长短进行排序,并快速取用呢?
答案就在TickCtrMatch这个变量上,TickCtrMatch变量是系统设计时的一个巧思妙想。
在这里插入图片描述
当一个任务需要插入时基列表中时,我们先获得TickCtrMatch值。
因为TickCtrMatch值是TickRemainOSTickCtr的和,即当前时间+时延时间,得到的值就是时延结束的绝对时间
这样就能将所有任务按照 实验结束的绝对时间 进行排序。

3. 确认插入时基列表哪个成员

TickCtrMatchOS_CFG_TICK_WHEEL_SIZE进行求余,即对成员总数进行求余,得到的数就是存放任务的下标。
这样做是为了对任务进行分类。

假如成员总数为10(但实际上应该是个质数),当前系统时间为502
50210求余得2,那么在任务时延结束绝对时间TickCtrMatch502,513,515,522的几个任务里只有502,522余数为2。我们不需要跟其他数比,只需要在余数为2的任务里找就行,这样就可以极大的减少寻找时间

同时将余数相同的任务按顺序排列,那么当系统时间为502,任务时延结束的绝对时间为522,那么之后的任务就不需要再找了,因为一定会比522大。
在这里插入图片描述

4. 对就绪列表的操作

当任务加入到时基列表中后,就需要从就绪列表中删除。
时基列表OSCfg_TickWheel[]该成员的NbrEntries加1。

当任务任务时延结束绝对时间TickCtrMatch等于系统时间OSTickCtr时就把任务加入到就绪列表,并从时基列表中删除。
时基列表OSCfg_TickWheel[]该成员的NbrEntries减1。

每个时间循环都要确定NbrEntriesMax大于等于NbrEntries

这篇关于(学习日记)2024.03.13:UCOSIII第十五节:基于时基列表的时延操作(持续更新)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

SQL中JOIN操作的条件使用总结与实践

《SQL中JOIN操作的条件使用总结与实践》在SQL查询中,JOIN操作是多表关联的核心工具,本文将从原理,场景和最佳实践三个方面总结JOIN条件的使用规则,希望可以帮助开发者精准控制查询逻辑... 目录一、ON与WHERE的本质区别二、场景化条件使用规则三、最佳实践建议1.优先使用ON条件2.WHERE用

Linux链表操作方式

《Linux链表操作方式》:本文主要介绍Linux链表操作方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、链表基础概念与内核链表优势二、内核链表结构与宏解析三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势六、典型应用场景七、调试技巧与

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

Java Multimap实现类与操作的具体示例

《JavaMultimap实现类与操作的具体示例》Multimap出现在Google的Guava库中,它为Java提供了更加灵活的集合操作,:本文主要介绍JavaMultimap实现类与操作的... 目录一、Multimap 概述Multimap 主要特点:二、Multimap 实现类1. ListMult

Python中文件读取操作漏洞深度解析与防护指南

《Python中文件读取操作漏洞深度解析与防护指南》在Web应用开发中,文件操作是最基础也最危险的功能之一,这篇文章将全面剖析Python环境中常见的文件读取漏洞类型,成因及防护方案,感兴趣的小伙伴可... 目录引言一、静态资源处理中的路径穿越漏洞1.1 典型漏洞场景1.2 os.path.join()的陷

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

Python使用Code2flow将代码转化为流程图的操作教程

《Python使用Code2flow将代码转化为流程图的操作教程》Code2flow是一款开源工具,能够将代码自动转换为流程图,该工具对于代码审查、调试和理解大型代码库非常有用,在这篇博客中,我们将深... 目录引言1nVflRA、为什么选择 Code2flow?2、安装 Code2flow3、基本功能演示

Python中OpenCV与Matplotlib的图像操作入门指南

《Python中OpenCV与Matplotlib的图像操作入门指南》:本文主要介绍Python中OpenCV与Matplotlib的图像操作指南,本文通过实例代码给大家介绍的非常详细,对大家的学... 目录一、环境准备二、图像的基本操作1. 图像读取、显示与保存 使用OpenCV操作2. 像素级操作3.

Python中合并列表(list)的六种方法小结

《Python中合并列表(list)的六种方法小结》本文主要介绍了Python中合并列表(list)的六种方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋... 目录一、直接用 + 合并列表二、用 extend() js方法三、用 zip() 函数交叉合并四、用

python操作redis基础

《python操作redis基础》Redis(RemoteDictionaryServer)是一个开源的、基于内存的键值对(Key-Value)存储系统,它通常用作数据库、缓存和消息代理,这篇文章... 目录1. Redis 简介2. 前提条件3. 安装 python Redis 客户端库4. 连接到 Re