gliethttp 发表于 2007-9-14 08:17

浅析μC/OS-II v2.85内核OSTimeDly()函数工作原理

浅析μC/OS-II&nbsp;v2.85内核OSTimeDly()函数工作原理<br /><br />**来源:http://gliethttp.cublog.cn[转载请声明出处]<br /><br />//----------------------------------------------------------------------<br />//1.OSTimeDly()函数<br />void&nbsp;OSTimeDly&nbsp;(INT16U&nbsp;ticks)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;INT8U&nbsp;y;<br />#if&nbsp;OS_CRITICAL_METHOD&nbsp;==&nbsp;3<br />&nbsp;&nbsp;&nbsp;&nbsp;OS_CPU_SR&nbsp;cpu_sr&nbsp;=&nbsp;0;<br />#endif<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(OSIntNesting&nbsp;&gt&nbsp;0)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;//在中断处理函数中调用了OSTimeDly(),那么直接退出<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(ticks&nbsp;&gt&nbsp;0)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OS_ENTER_CRITICAL();<br />//调用OSTimeDly()的进程自己把自己从就绪控制矩阵中拿下来,<br />//即:去掉调度器(x,y)矩形阵列(OSRdyTbl,OSRdyGrp)中该task对应的bit位,使得调度器不考虑<br />//该task的调度<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y&nbsp;=&nbsp;OSTCBCur-&gtOSTCBY;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OSRdyTbl&nbsp;&=&nbsp;~OSTCBCur-&gtOSTCBBitX;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(OSRdyTbl&nbsp;==&nbsp;0)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OSRdyGrp&nbsp;&=&nbsp;~OSTCBCur-&gtOSTCBBitY;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />//延时ticks值,放入OSTCBDly单元,在os时钟滴答处理函数OSTimeTick()中,会处理该单元<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OSTCBCur-&gtOSTCBDly&nbsp;=&nbsp;ticks;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OS_EXIT_CRITICAL();<br />//因为本task正在运行,所以本task现在的优先级最高,现在本task已经将自己从就绪控制矩阵中--调度器(x,y)矩形阵列<br />//把自己摘掉,所以调度函数OS_Sched()一定会切换到另一个task中执行新task的代码<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OS_Sched();//具体参见《浅析μC/OS-II&nbsp;v2.85内核调度函数》<br />&nbsp;&nbsp;&nbsp;&nbsp;}//ticks==0,那么什么也不做<br />}<br />//----------------------------------------------------------------------<br />//2.OSTimeTick()--在定时中断里引用的系统滴答函数<br />void&nbsp;OSTimeTick&nbsp;(void)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;OS_TCB&nbsp;*ptcb;<br />#if&nbsp;OS_TICK_STEP_EN&nbsp;&gt&nbsp;0<br />&nbsp;&nbsp;&nbsp;&nbsp;BOOLEAN&nbsp;step;<br />#endif<br />#if&nbsp;OS_CRITICAL_METHOD&nbsp;==&nbsp;3<br />&nbsp;&nbsp;&nbsp;&nbsp;OS_CPU_SR&nbsp;cpu_sr&nbsp;=&nbsp;0;//该3方式将使中断状态寄存器放入堆栈中<br /><br />#endif<br /><br />#if&nbsp;OS_TIME_TICK_HOOK_EN&nbsp;&gt&nbsp;0<br />&nbsp;&nbsp;&nbsp;&nbsp;OSTimeTickHook();<br />#endif<br />#if&nbsp;OS_TIME_GET_SET_EN&nbsp;&gt&nbsp;0<br />&nbsp;&nbsp;&nbsp;&nbsp;OS_ENTER_CRITICAL();<br />&nbsp;&nbsp;&nbsp;&nbsp;OSTime++;<br />&nbsp;&nbsp;&nbsp;&nbsp;OS_EXIT_CRITICAL();<br />#endif<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(OSRunning&nbsp;==&nbsp;OS_TRUE)&nbsp;{<br />#if&nbsp;OS_TICK_STEP_EN&nbsp;&gt&nbsp;0<br />//控制内核的tick<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch&nbsp;(OSTickStepState)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;OS_TICK_STEP_DIS:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;step&nbsp;=&nbsp;OS_TRUE;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;OS_TICK_STEP_WAIT:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;step&nbsp;=&nbsp;OS_FALSE;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;OS_TICK_STEP_ONCE:<br />//本次tick将将影响到task的OSTCBDly域<br />//但以后的tick将一直被屏蔽,不会影响到OSTCBDly域<br />//直到外部将OSTickStepState改变为止<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;step&nbsp;=&nbsp;OS_TRUE;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OSTickStepState&nbsp;=&nbsp;OS_TICK_STEP_WAIT;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;step&nbsp;=&nbsp;OS_TRUE;//本次tick将影响到task的OSTCBDly域<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OSTickStepState&nbsp;=&nbsp;OS_TICK_STEP_DIS;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(step&nbsp;==&nbsp;OS_FALSE)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />#endif<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ptcb&nbsp;=&nbsp;OSTCBList;<br />//2007-09-08&nbsp;gliethttp<br />//OSTCBList是一个按进程创建的先后顺序链接成的task单向链表,最后创建的task在最前面,最先创建的<br />//task在单向链表的尾端,<br />//所以OS_TaskIdle空闲进程在链表的最后,因为它最先创建<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(ptcb-&gtOSTCBPrio&nbsp;!=&nbsp;OS_TASK_IDLE_PRIO)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OS_ENTER_CRITICAL();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(ptcb-&gtOSTCBDly&nbsp;!=&nbsp;0)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(--ptcb-&gtOSTCBDly&nbsp;==&nbsp;0)&nbsp;{<br />//该task的延时时间已到,解析此次延时是OSTimeDly()引起的,还是OSQPend()之类超时引起的<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;((ptcb-&gtOSTCBStat&nbsp;&&nbsp;OS_STAT_PEND_ANY)&nbsp;!=&nbsp;OS_STAT_RDY)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//2007-09-08&nbsp;gliethttp<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//如:由OSSemPend&nbsp;(pevent,timeout,perr);定义的timeout已经到了,对应task需要运行了<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//超时时间到,所以不论当前进程是在做什么,只要时间一到<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//该task就可以运行了,所以清除所有事件标志,之后状态标示为OS_STAT_PEND_TO(超时)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ptcb-&gtOSTCBStat&nbsp;&=&nbsp;~(INT8U)OS_STAT_PEND_ANY;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ptcb-&gtOSTCBStatPend&nbsp;=&nbsp;OS_STAT_PEND_TO;//超时异常<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//2007-09-08&nbsp;gliethttp<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//说明该task调用的是OSTimeDly()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ptcb-&gtOSTCBStatPend&nbsp;=&nbsp;OS_STAT_PEND_OK;//正常结束<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;((ptcb-&gtOSTCBStat&nbsp;&&nbsp;OS_STAT_SUSPEND)&nbsp;==&nbsp;OS_STAT_RDY)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//2007-09-08&nbsp;gliethttp<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//如果该task没有suspend,那么把当前就绪的task加入到运行调度器的就绪控制矩阵中<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//等待被调度<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OSRdyGrp&nbsp;|=&nbsp;ptcb-&gtOSTCBBitY;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OSRdyTbl&nbsp;|=&nbsp;ptcb-&gtOSTCBBitX;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ptcb&nbsp;=&nbsp;ptcb-&gtOSTCBNext;//继续运算下一个task的OSTCBDly时间域<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OS_EXIT_CRITICAL();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br />

yqliu29 发表于 2007-9-18 20:34

做产品用这个的多不多??

页: [1]
查看完整版本: 浅析μC/OS-II v2.85内核OSTimeDly()函数工作原理