网站设计语言有哪些,怎么获得免费网站,彩票系统网站建设,学大教育一对一收费价格表写在前面#xff1a; 由于时间的不足与学习的碎片化#xff0c;写博客变得有些奢侈。 但是对于记录学习#xff08;忘了以后能快速复习#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位#xff0c;以时间为顺序#xff0c;仅仅将博客当做一个知识学习的目录 由于时间的不足与学习的碎片化写博客变得有些奢侈。 但是对于记录学习忘了以后能快速复习的渴望一天天变得强烈。 既然如此 不如以天为单位以时间为顺序仅仅将博客当做一个知识学习的目录记录笔者认为最通俗、最有帮助的资料并尽量总结几句话指明本质以便于日后搜索起来更加容易。 标题的结构如下“类型”“知识点”——“简短的解释” 部分内容由于保密协议无法上传。 点击此处进入学习日记的总目录 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的值将TickRemain和OSTickCtr相加得到TickCtrMatch。 OSTickCtr是一个全局变量 记录的是系统自启动以来或者自上次复位以来经过了多少个SysTick周期。 OSTickCtr的值每经过一个SysTick周期其值就加一 2.对任务进行排序
众所周知任务随时都有可能加入到时基列表中那么怎么能高效的将各个任务按时延长短进行排序并快速取用呢 答案就在TickCtrMatch这个变量上TickCtrMatch变量是系统设计时的一个巧思妙想。 当一个任务需要插入时基列表中时我们先获得TickCtrMatch值。 因为TickCtrMatch值是TickRemain和OSTickCtr的和即当前时间时延时间得到的值就是时延结束的绝对时间。 这样就能将所有任务按照 实验结束的绝对时间 进行排序。
3. 确认插入时基列表哪个成员
用TickCtrMatch对OS_CFG_TICK_WHEEL_SIZE进行求余即对成员总数进行求余得到的数就是存放任务的下标。 这样做是为了对任务进行分类。
假如成员总数为10但实际上应该是个质数当前系统时间为502。 502对10求余得2那么在任务时延结束绝对时间TickCtrMatch为502513515522的几个任务里只有502522余数为2。我们不需要跟其他数比只需要在余数为2的任务里找就行这样就可以极大的减少寻找时间
同时将余数相同的任务按顺序排列那么当系统时间为502任务时延结束的绝对时间为522那么之后的任务就不需要再找了因为一定会比522大。
4. 对就绪列表的操作
当任务加入到时基列表中后就需要从就绪列表中删除。 时基列表OSCfg_TickWheel[]该成员的NbrEntries加1。
当任务任务时延结束绝对时间TickCtrMatch等于系统时间OSTickCtr时就把任务加入到就绪列表并从时基列表中删除。 时基列表OSCfg_TickWheel[]该成员的NbrEntries减1。
每个时间循环都要确定NbrEntriesMax大于等于NbrEntries