μC/OS-III---I笔记3---时间管理
时间管理相关函数,其实深入根本的理解就是一些对时间任务相关变量,数据结果进行修改的函数这样方便对应任务查找延时等时间相关的任务有没有到期。前面的时间相关的函数是这些操作的基
1.延时函数 OsTImeDly
函数是一个按时钟节拍定时的延时函数 ,默认是将当前执行的任务延时一定时钟节拍。
OS_OPT_TIME_DLY 此选项为相对延时 比如5S后
OS_OPT_TIME_TIMEOUT 同上
OS_OPT_TIME_MATCH 绝对延时 比如延时到系统开始运行后的一个时钟节拍点
OS_OPT_TIME_PERIODIC 周期延时 与相对延时差不多但是相对长时间周期性延时时更准确一些
void OSTimeDly (OS_TICK dly,OS_OPT opt,OS_ERR *p_err) {CPU_SR_ALLOC();#ifdef OS_SAFETY_CRITICALif (p_err == (OS_ERR *)0) {OS_SAFETY_CRITICAL_EXCEPTION();return;} #endif#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0uif (OSIntNestingCtr > (OS_NESTING_CTR)0u) { /* Not allowed to call from an ISR */*p_err = OS_ERR_TIME_DLY_ISR;return;} #endifif (OSSchedLockNestingCtr > (OS_NESTING_CTR)0u) { /* Can't delay when the scheduler is locked */*p_err = OS_ERR_SCHED_LOCKED;return;}switch (opt) {case OS_OPT_TIME_DLY:case OS_OPT_TIME_TIMEOUT:case OS_OPT_TIME_PERIODIC:if (dly == (OS_TICK)0u) { /* 0 means no delay! */*p_err = OS_ERR_TIME_ZERO_DLY;return;}break;case OS_OPT_TIME_MATCH:break;default:*p_err = OS_ERR_OPT_INVALID;return;}OS_CRITICAL_ENTER();OSTCBCurPtr->TaskState = OS_TASK_STATE_DLY;OS_TickListInsert(OSTCBCurPtr,dly,opt,p_err);if (*p_err != OS_ERR_NONE) {OS_CRITICAL_EXIT_NO_SCHED();return;}OS_RdyListRemove(OSTCBCurPtr); /* Remove current task from ready list */OS_CRITICAL_EXIT_NO_SCHED();OSSched(); /* Find next task to run! */*p_err = OS_ERR_NONE; }
OSTimeDly
2.OSTimeDlyHMSM
函数是一个按时间定时的延时函数 ,默认是将当前执行的任务延时一段时间。
void OSTimeDlyHMSM (CPU_INT16U hours,CPU_INT16U minutes,CPU_INT16U seconds,CPU_INT32U milli,OS_OPT opt,OS_ERR *p_err) { #if OS_CFG_ARG_CHK_EN > 0uCPU_BOOLEAN opt_invalid;CPU_BOOLEAN opt_non_strict; #endifOS_OPT opt_time;OS_RATE_HZ tick_rate;OS_TICK ticks;CPU_SR_ALLOC();#ifdef OS_SAFETY_CRITICALif (p_err == (OS_ERR *)0) {OS_SAFETY_CRITICAL_EXCEPTION();return;} #endif#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0uif (OSIntNestingCtr > (OS_NESTING_CTR)0u) { /* Not allowed to call from an ISR */*p_err = OS_ERR_TIME_DLY_ISR;return;} #endifif (OSSchedLockNestingCtr > (OS_NESTING_CTR)0u) { /* Can't delay when the scheduler is locked */*p_err = OS_ERR_SCHED_LOCKED;return;}opt_time = opt & OS_OPT_TIME_MASK; /* Retrieve time options only. */switch (opt_time) {case OS_OPT_TIME_DLY:case OS_OPT_TIME_TIMEOUT:case OS_OPT_TIME_PERIODIC:if (milli == (CPU_INT32U)0u) { /* Make sure we didn't specify a 0 delay */if (seconds == (CPU_INT16U)0u) {if (minutes == (CPU_INT16U)0u) {if (hours == (CPU_INT16U)0u) {*p_err = OS_ERR_TIME_ZERO_DLY;return;}}}}break;case OS_OPT_TIME_MATCH:break;default:*p_err = OS_ERR_OPT_INVALID;return;}#if OS_CFG_ARG_CHK_EN > 0u /* Validate arguments to be within range */opt_invalid = DEF_BIT_IS_SET_ANY(opt, ~OS_OPT_TIME_OPTS_MASK);if (opt_invalid == DEF_YES) {*p_err = OS_ERR_OPT_INVALID;return;}opt_non_strict = DEF_BIT_IS_SET(opt, OS_OPT_TIME_HMSM_NON_STRICT);if (opt_non_strict != DEF_YES) {if (milli > (CPU_INT32U)999u) {*p_err = OS_ERR_TIME_INVALID_MILLISECONDS;return;}if (seconds > (CPU_INT16U)59u) {*p_err = OS_ERR_TIME_INVALID_SECONDS;return;}if (minutes > (CPU_INT16U)59u) {*p_err = OS_ERR_TIME_INVALID_MINUTES;return;}if (hours > (CPU_INT16U)99u) {*p_err = OS_ERR_TIME_INVALID_HOURS;return;}} else {if (minutes > (CPU_INT16U)9999u) {*p_err = OS_ERR_TIME_INVALID_MINUTES;return;}if (hours > (CPU_INT16U)999u) {*p_err = OS_ERR_TIME_INVALID_HOURS;return;}} #endif/* Compute the total number of clock ticks required.. *//* .. (rounded to the nearest tick) */tick_rate = OSCfg_TickRate_Hz;ticks = ((OS_TICK)hours * (OS_TICK)3600u + (OS_TICK)minutes * (OS_TICK)60u + (OS_TICK)seconds) * tick_rate+ (tick_rate * ((OS_TICK)milli + (OS_TICK)500u / tick_rate)) / (OS_TICK)1000u;if (ticks > (OS_TICK)0u) {OS_CRITICAL_ENTER();OSTCBCurPtr->TaskState = OS_TASK_STATE_DLY;OS_TickListInsert(OSTCBCurPtr,ticks,opt_time,p_err);if (*p_err != OS_ERR_NONE) {OS_CRITICAL_EXIT_NO_SCHED();return;}OS_RdyListRemove(OSTCBCurPtr); /* Remove current task from ready list */OS_CRITICAL_EXIT_NO_SCHED();OSSched(); /* Find next task to run! */*p_err = OS_ERR_NONE;} else {*p_err = OS_ERR_TIME_ZERO_DLY;} }
OSTimeDlyHMSM
3.任务插入节拍列表操作
void OS_TickListInsert (OS_TCB *p_tcb,OS_TICK time,OS_OPT opt,OS_ERR *p_err) {OS_TICK tick_delta;OS_TICK tick_next;OS_TICK_SPOKE *p_spoke;OS_TCB *p_tcb0;OS_TCB *p_tcb1;OS_TICK_SPOKE_IX spoke;if (opt == OS_OPT_TIME_MATCH) { /* Task time is absolute. */tick_delta = time - OSTickCtr - 1u;if (tick_delta > OS_TICK_TH_RDY) { /* If delay already occurred, ... */p_tcb->TickCtrMatch = (OS_TICK )0u;p_tcb->TickRemain = (OS_TICK )0u;p_tcb->TickSpokePtr = (OS_TICK_SPOKE *)0;*p_err = OS_ERR_TIME_ZERO_DLY; /* ... do NOT delay. */return;}p_tcb->TickCtrMatch = time;p_tcb->TickRemain = tick_delta + 1u;} else if (time > (OS_TICK)0u) {if (opt == OS_OPT_TIME_PERIODIC) { /* Task time is periodic. */tick_next = p_tcb->TickCtrPrev + time;tick_delta = tick_next - OSTickCtr - 1u;if (tick_delta < time) { /* If next periodic delay did NOT already occur, ... */p_tcb->TickCtrMatch = tick_next; /* ... set next periodic delay; ... */} else {p_tcb->TickCtrMatch = OSTickCtr + time; /* ... else reset periodic delay. */}p_tcb->TickRemain = p_tcb->TickCtrMatch - OSTickCtr;p_tcb->TickCtrPrev = p_tcb->TickCtrMatch;} else { /* Task time is relative to current. */p_tcb->TickCtrMatch = OSTickCtr + time;p_tcb->TickRemain = time;}} else { /* Zero time delay; ... */p_tcb->TickCtrMatch = (OS_TICK )0u;p_tcb->TickRemain = (OS_TICK )0u;p_tcb->TickSpokePtr = (OS_TICK_SPOKE *)0;*p_err = OS_ERR_TIME_ZERO_DLY; /* ... do NOT delay. */return;}spoke = (OS_TICK_SPOKE_IX)(p_tcb->TickCtrMatch % OSCfg_TickWheelSize);p_spoke = &OSCfg_TickWheel[spoke];if (p_spoke->NbrEntries == (OS_OBJ_QTY)0u) { /* First entry in the spoke */p_tcb->TickNextPtr = (OS_TCB *)0;p_tcb->TickPrevPtr = (OS_TCB *)0;p_spoke->FirstPtr = p_tcb;p_spoke->NbrEntries = (OS_OBJ_QTY)1u;} else {p_tcb1 = p_spoke->FirstPtr; /* Point to current first TCB in the list */while (p_tcb1 != (OS_TCB *)0) {p_tcb1->TickRemain = p_tcb1->TickCtrMatch /* Compute time remaining of current TCB in list */- OSTickCtr;if (p_tcb->TickRemain > p_tcb1->TickRemain) { /* Do we need to insert AFTER current TCB in list? */if (p_tcb1->TickNextPtr != (OS_TCB *)0) { /* Yes, are we pointing at the last TCB in the list? */p_tcb1 = p_tcb1->TickNextPtr; /* No, Point to next TCB in the list */} else {p_tcb->TickNextPtr = (OS_TCB *)0;p_tcb->TickPrevPtr = p_tcb1;p_tcb1->TickNextPtr = p_tcb; /* Yes, TCB to add is now new last entry in the list */p_tcb1 = (OS_TCB *)0; /* Break loop */}} else { /* Insert before the current TCB */if (p_tcb1->TickPrevPtr == (OS_TCB *)0) { /* Are we inserting before the first TCB? */p_tcb->TickPrevPtr = (OS_TCB *)0;p_tcb->TickNextPtr = p_tcb1;p_tcb1->TickPrevPtr = p_tcb;p_spoke->FirstPtr = p_tcb;} else { /* Insert in between 2 TCBs already in the list */p_tcb0 = p_tcb1->TickPrevPtr;p_tcb->TickPrevPtr = p_tcb0;p_tcb->TickNextPtr = p_tcb1;p_tcb0->TickNextPtr = p_tcb;p_tcb1->TickPrevPtr = p_tcb;}p_tcb1 = (OS_TCB *)0; /* Break loop */}}p_spoke->NbrEntries++;}if (p_spoke->NbrEntriesMax < p_spoke->NbrEntries) { /* Keep track of maximum # of entries in each spoke */p_spoke->NbrEntriesMax = p_spoke->NbrEntries;}p_tcb->TickSpokePtr = p_spoke; /* Link back to tick spoke */*p_err = OS_ERR_NONE; }
OS_TickListInsert
4.取消任务延时
#if OS_CFG_TIME_DLY_RESUME_EN > 0u void OSTimeDlyResume (OS_TCB *p_tcb,OS_ERR *p_err) {CPU_SR_ALLOC();#ifdef OS_SAFETY_CRITICALif (p_err == (OS_ERR *)0) {OS_SAFETY_CRITICAL_EXCEPTION();return;} #endif#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0uif (OSIntNestingCtr > (OS_NESTING_CTR)0u) { /* Not allowed to call from an ISR */*p_err = OS_ERR_TIME_DLY_RESUME_ISR;return;} #endif#if OS_CFG_ARG_CHK_EN > 0uif (p_tcb == (OS_TCB *)0) { /* Not possible for the running task to be delayed! */*p_err = OS_ERR_TASK_NOT_DLY;return;} #endifCPU_CRITICAL_ENTER();if (p_tcb == OSTCBCurPtr) { /* Not possible for the running task to be delayed! */*p_err = OS_ERR_TASK_NOT_DLY;CPU_CRITICAL_EXIT();return;}switch (p_tcb->TaskState) {case OS_TASK_STATE_RDY: /* Cannot Abort delay if task is ready */CPU_CRITICAL_EXIT();*p_err = OS_ERR_TASK_NOT_DLY;break;case OS_TASK_STATE_DLY:OS_CRITICAL_ENTER_CPU_EXIT();p_tcb->TaskState = OS_TASK_STATE_RDY;OS_TickListRemove(p_tcb); /* Remove task from tick list */OS_RdyListInsert(p_tcb); /* Add to ready list */OS_CRITICAL_EXIT_NO_SCHED();*p_err = OS_ERR_NONE;break;case OS_TASK_STATE_PEND:CPU_CRITICAL_EXIT();*p_err = OS_ERR_TASK_NOT_DLY;break;case OS_TASK_STATE_PEND_TIMEOUT:CPU_CRITICAL_EXIT();*p_err = OS_ERR_TASK_NOT_DLY;break;case OS_TASK_STATE_SUSPENDED:CPU_CRITICAL_EXIT();*p_err = OS_ERR_TASK_NOT_DLY;break;case OS_TASK_STATE_DLY_SUSPENDED:OS_CRITICAL_ENTER_CPU_EXIT();p_tcb->TaskState = OS_TASK_STATE_SUSPENDED;OS_TickListRemove(p_tcb); /* Remove task from tick list */OS_CRITICAL_EXIT_NO_SCHED();*p_err = OS_ERR_TASK_SUSPENDED;break;case OS_TASK_STATE_PEND_SUSPENDED:CPU_CRITICAL_EXIT();*p_err = OS_ERR_TASK_NOT_DLY;break;case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:CPU_CRITICAL_EXIT();*p_err = OS_ERR_TASK_NOT_DLY;break;default:CPU_CRITICAL_EXIT();*p_err = OS_ERR_STATE_INVALID;break;}OSSched(); } #endif
OSTimeDlyResume
TickList数据结构:
μC/OS在一些变量 的处理上用到了一个技巧:
#ifdef OS_GLOBALS #define OS_EXT #else #define OS_EXT extern #endif
#if OS_CFG_APP_HOOKS_EN > 0u OS_EXT OS_APP_HOOK_TCB OS_AppTaskCreateHookPtr; /* Application hooks */ OS_EXT OS_APP_HOOK_TCB OS_AppTaskDelHookPtr; OS_EXT OS_APP_HOOK_TCB OS_AppTaskReturnHookPtr;OS_EXT OS_APP_HOOK_VOID OS_AppIdleTaskHookPtr; OS_EXT OS_APP_HOOK_VOID OS_AppStatTaskHookPtr; OS_EXT OS_APP_HOOK_VOID OS_AppTaskSwHookPtr; OS_EXT OS_APP_HOOK_VOID OS_AppTimeTickHookPtr; #endif/* IDLE TASK -------------------------------- */ OS_EXT OS_IDLE_CTR OSIdleTaskCtr; OS_EXT OS_TCB OSIdleTaskTCB;/* MISCELLANEOUS ---------------------------- */ OS_EXT OS_NESTING_CTR OSIntNestingCtr; /* Interrupt nesting level */ #ifdef CPU_CFG_INT_DIS_MEAS_EN OS_EXT CPU_TS OSIntDisTimeMax; /* Overall interrupt disable time */ #endifOS_EXT OS_STATE OSRunning; /* Flag indicating that kernel is running *//* ISR HANDLER TASK ------------------------- */ #if OS_CFG_ISR_POST_DEFERRED_EN > 0u OS_EXT OS_INT_Q *OSIntQInPtr; OS_EXT OS_INT_Q *OSIntQOutPtr; OS_EXT OS_OBJ_QTY OSIntQNbrEntries; OS_EXT OS_OBJ_QTY OSIntQNbrEntriesMax; OS_EXT OS_OBJ_QTY OSIntQOvfCtr; OS_EXT OS_TCB OSIntQTaskTCB; OS_EXT CPU_TS OSIntQTaskTimeMax; #endif
示例代码
对于声明了OS_GLOBALS的文件内后面的变量就是定义,否则就是声明;
转载于:https://www.cnblogs.com/w-smile/p/7857754.html
μC/OS-III---I笔记3---时间管理相关推荐
- 工作自动扩张的时间管理与柳比歇夫时间记录统计(时间管理讲座笔记)
之前一个让我觉得受益匪浅的时间管理讲座的笔记.如果看完笔记有兴趣,可以去看看讲座. 其中最让我触动的一个点: 时间管理并不是又快又好把工作上的事情做完. 工作会自动扩张.进入知识时代和信息时代的工作量 ...
- 【读书笔记】【时间管理:如何充分利用你的24小时】
书籍: https://book.douban.com/subject/7001106/ 笔记: 时间管理:如何充分利用你的24小时 一周只有24*7=168小时,其中有8*7=56小时要用来睡觉,剩 ...
- PL项目管理:时间管理
PL项目管理:时间管理 PL项目管理沙龙笔记 2009-8-11 时间管理的几个概念 时间可以被管理吗?时间是不能被管理的,时间管理的实质是自我管理 . 什么是时间的浪费?对目标毫无贡献的时间消耗. ...
- 嵌入式OS入门笔记-以RTX为案例:四.简单的时间管理
嵌入式OS入门笔记-以RTX为案例:四.简单的时间管理 上一节简单记录了进程task.有了进程以后,我们需要关心怎么样分配CPU资源(或者运行时间)给每个进程.那么就要引入排程(scheduling) ...
- UC/OS III操作系统学习笔记
UCOS操作系统学习笔记 1.UCOSIII任务 1.1任务管理 1.2 任务创建和删除.挂起和恢复 1.3 系统内部任务 2.UCOSIII中断和时间管理 2.1 中断管理 2.2 时间管理 3.U ...
- 《Linux内核设计与实现》读书笔记(十一)- 定时器和时间管理
系统中有很多与时间相关的程序(比如定期执行的任务,某一时间执行的任务,推迟一段时间执行的任务),因此,时间的管理对于linux来说非常重要. 主要内容: 系统时间 定时器 定时器相关概念 定时器执行流 ...
- [读书笔记]《番茄工作法图解:简单易行的时间管理方法》
买这本书根本就是个错误的决定, 除非, 我把它付诸实践, 并改善我的生活. 个人觉得<番茄工作法图解:简单易行的时间管理方法>不是时间管理的书,而是一本关于加强注意力和执行力的书. 这一篇 ...
- 如何在 FlowUs、Notion 等笔记软件中进行时间管理?
在这个繁忙的世界里,时间管理是很多人都必须面临的事情.高效的时间管理,不仅可以帮助你变得更有效率,而且可以辅助你实现个人和职业目标.为了明白时间管理是什么,人们做了很多尝试.很多人的做法是列出一个待办 ...
- 读《时间管理:如何充分利用你的24小时》笔记
读<时间管理:如何充分利用你的24小时>笔记 关于时间日志 心灵净化-冥想 空隙时间利用 对时间的感觉 记忆力提升 逃离舒适区,拒绝拖延症. 四象限去管理任务. 关提高工作效率和时间管理能 ...
- 【小毛驴的絮叨】笔记帮你做时间管理
目录 你有没有这样的烦恼:笔记分类应该怎么分类? [计算机是怎么做的] [我们VS计算机] [GTD?] [如何落实?] 小结: 你有没有这样的烦恼:笔记分类应该怎么分类? 记着记着,笔记就乱了,有的 ...
最新文章
- C++ 三五法则,看看你能不能理解
- Cross-site Scripting (XSS) 阅读笔记
- Java线程池如何合理配置核心线程数
- 使用 dynamic 类型让 ASP.NET Core 实现 HATEOAS 结构的 RESTful API
- 复旦大学长跑协会财务制度(初稿)
- IndexError:boolean index did not match indexed array along dimension 0
- go语言生成uuid
- PostgreSQL on Linux 最佳部署指南
- 31 天重构学习笔记9. 提取接口
- 矩阵的特征值和特征向量
- nodeJS打包安装和问题处理
- 一文看懂信用额度管理体系(三连)
- iOS-AppStore 审核加速
- Oracle的网络三大配置文件(sqlnet.ora、tnsnames.ora、listener.ora)
- Srping 中的AOP
- Android 界面设计尺寸规范
- 英达科技委任唐伟章教授担任非执行董事
- 德玛西亚服务器显示排队,告别一区高峰期排队10万? 马服艾欧尼亚迎来服务器扩容...
- [转]Half Life 2 Source 引擎介绍
- 男士最佳衣着选择搭配
热门文章
- 练习:C#---for循环(整数和、阶乘、楼梯)
- Eclipse更改默认工作目录的方法
- 存储过程中调用EXECUTE IMMEDIATE的“权限不足”问题
- 第三十六课:告别演出
- 线性表【01】线性表的类型定义
- SQL DATEADD (Transact-SQL)根据需要返回时间,
- virtualbox版oracle RAC环境搭建
- Python:序列化
- 10kv配电网潮流 matlab,关于用matlab计算配电网三相潮流计算,请大家帮忙检验下!...
- java画虚线_在java中绘制虚线