浅析μC/OS-II OSTimeDly()函数和OSTimeTick()函数工作原理
生活随笔
收集整理的這篇文章主要介紹了
浅析μC/OS-II OSTimeDly()函数和OSTimeTick()函数工作原理
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
淺析μC
/
OS
-
II v2
.
85內(nèi)核OSTimeDly
(
)
函數(shù)工作原理
文章來源 : http : //gliethttp.cublog.cn[轉(zhuǎn)載請(qǐng)聲明出處]
//----------------------------------------------------------------------
//1.OSTimeDly()函數(shù)
void ?OSTimeDly? ( INT16U ticks )
{
????INT8U y ;
# if ?OS_CRITICAL_METHOD? = = ?3
????OS_CPU_SR cpu_sr? = ?0 ;
# endif
???? if ? ( OSIntNesting? > ?0 ) ? {
???????? return ; //在中斷處理函數(shù)中調(diào)用了OSTimeDly(),那么直接退出
???? }
???? if ? ( ticks? > ?0 ) ? {
????????OS_ENTER_CRITICAL ( ) ;
//調(diào)用OSTimeDly()的進(jìn)程自己把自己從就緒控制矩陣中拿下來,
//即:去掉調(diào)度器(x,y)矩形陣列(OSRdyTbl,OSRdyGrp)中該task對(duì)應(yīng)的bit位,使得調(diào)度器不考慮
//該task的調(diào)度
????????y? = ?OSTCBCur - > OSTCBY ;
????????OSRdyTbl [ y ] ? & = ? ~ OSTCBCur - > OSTCBBitX ;
???????? if ? ( OSRdyTbl [ y ] ? = = ?0 ) ? {
????????????OSRdyGrp? & = ? ~ OSTCBCur - > OSTCBBitY ;
???????? }
//延時(shí)ticks值,放入OSTCBDly單元,在os時(shí)鐘滴答處理函數(shù)OSTimeTick()中,會(huì)處理該單元[gliethttp]
????????OSTCBCur - > OSTCBDly? = ?ticks ;
????????OS_EXIT_CRITICAL ( ) ;
//因?yàn)楸総ask正在運(yùn)行,所以本task現(xiàn)在的優(yōu)先級(jí)最高,現(xiàn)在本task已經(jīng)將自己從就緒控制矩陣中--調(diào)度器(x,y)矩形陣列
//把自己摘掉,所以調(diào)度函數(shù)OS_Sched()一定會(huì)切換到另一個(gè)task中執(zhí)行新task的代碼[gliethttp]
????????OS_Sched ( ) ; //具體參見《淺析μC/OS-II v2.85內(nèi)核調(diào)度函數(shù)》
???? } //ticks==0,那么什么也不做
}
//----------------------------------------------------------------------
//2.OSTimeTick()--在定時(shí)中斷里引用的系統(tǒng)滴答函數(shù)
void ?OSTimeTick? ( void )
{
????OS_TCB? * ptcb ;
# if ?OS_TICK_STEP_EN? > ?0
????BOOLEAN step ;
# endif
# if ?OS_CRITICAL_METHOD? = = ?3
????OS_CPU_SR cpu_sr? = ?0 ; //該3方式將使中斷狀態(tài)寄存器放入堆棧中
# endif
# if ?OS_TIME_TICK_HOOK_EN? > ?0
????OSTimeTickHook ( ) ;
# endif
# if ?OS_TIME_GET_SET_EN? > ?0
????OS_ENTER_CRITICAL ( ) ;
????OSTime + + ;
????OS_EXIT_CRITICAL ( ) ;
# endif
???? if ? ( OSRunning? = = ?OS_TRUE ) ? {
# if ?OS_TICK_STEP_EN? > ?0
//控制內(nèi)核的tick
???????? switch ? ( OSTickStepState ) ? {
???????????? case ?OS_TICK_STEP_DIS :
?????????????????step? = ?OS_TRUE ;
????????????????? break ;
???????????? case ?OS_TICK_STEP_WAIT :
?????????????????step? = ?OS_FALSE ;
????????????????? break ;
???????????? case ?OS_TICK_STEP_ONCE :
//本次tick將將影響到task的OSTCBDly域
//但以后的tick將一直被屏蔽,不會(huì)影響到OSTCBDly域
//直到外部將OSTickStepState改變?yōu)橹筟gliethttp]
?????????????????step? = ?OS_TRUE ;
?????????????????OSTickStepState? = ?OS_TICK_STEP_WAIT ;
????????????????? break ;
???????????? default :
?????????????????step? = ?OS_TRUE ; //本次tick將影響到task的OSTCBDly域
?????????????????OSTickStepState? = ?OS_TICK_STEP_DIS ;
????????????????? break ;
???????? }
???????? if ? ( step? = = ?OS_FALSE ) ? {
???????????? return ;
???????? }
# endif
????????ptcb? = ?OSTCBList ;
//2007-09-08 gliethttp
//OSTCBList是一個(gè)按進(jìn)程創(chuàng)建的先后順序鏈接成的task單向鏈表,最后創(chuàng)建的task在最前面,最先創(chuàng)建的
//task在單向鏈表的尾端,
//所以O(shè)S_TaskIdle空閑進(jìn)程在鏈表的最后,因?yàn)樗钕葎?chuàng)建
???????? while ? ( ptcb - > OSTCBPrio? ! = ?OS_TASK_IDLE_PRIO ) ? {
????????????OS_ENTER_CRITICAL ( ) ;
???????????? if ? ( ptcb - > OSTCBDly? ! = ?0 ) ? {
???????????????? if ? ( - - ptcb - > OSTCBDly? = = ?0 ) ? {
//該task的延時(shí)時(shí)間已到,解析此次延時(shí)是OSTimeDly()引起的,還是OSQPend()之類超時(shí)引起的[gliethttp]
???????????????????? if ? ( ( ptcb - > OSTCBStat? & ?OS_STAT_PEND_ANY ) ? ! = ?OS_STAT_RDY ) ? {
???????????????????????? //2007-09-08 gliethttp
???????????????????????? //如:由OSSemPend (pevent,timeout,perr);定義的timeout已經(jīng)到了,對(duì)應(yīng)task需要運(yùn)行了
???????????????????????? //超時(shí)時(shí)間到,所以不論當(dāng)前進(jìn)程是在做什么,只要時(shí)間一到
???????????????????????? //該task就可以運(yùn)行了,所以清除所有事件標(biāo)志,之后狀態(tài)標(biāo)示為OS_STAT_PEND_TO(超時(shí))
????????????????????????ptcb - > OSTCBStat? & = ? ~ ( INT8U ) OS_STAT_PEND_ANY ;
????????????????????????ptcb - > OSTCBStatPend? = ?OS_STAT_PEND_TO ; //超時(shí)異常
???????????????????? } ? else ? {
???????????????????????? //2007-09-08 gliethttp
???????????????????????? //說明該task調(diào)用的是OSTimeDly()
????????????????????????ptcb - > OSTCBStatPend? = ?OS_STAT_PEND_OK ; //正常結(jié)束
???????????????????? }
???????????????????? if ? ( ( ptcb - > OSTCBStat? & ?OS_STAT_SUSPEND ) ? = = ?OS_STAT_RDY ) ? {
???????????????????????? //2007-09-08 gliethttp
???????????????????????? //如果該task沒有suspend,那么把當(dāng)前就緒的task加入到運(yùn)行調(diào)度器的就緒控制矩陣中
???????????????????????? //等待被調(diào)度
????????????????????????OSRdyGrp? | = ?ptcb - > OSTCBBitY ;
????????????????????????OSRdyTbl [ ptcb - > OSTCBY ] ? | = ?ptcb - > OSTCBBitX ;
???????????????????? }
???????????????? }
???????????? }
????????????ptcb? = ?ptcb - > OSTCBNext ; //繼續(xù)運(yùn)算下一個(gè)task的OSTCBDly時(shí)間域
????????????OS_EXIT_CRITICAL ( ) ;
???????? }
???? }
}
文章來源 : http : //gliethttp.cublog.cn[轉(zhuǎn)載請(qǐng)聲明出處]
//----------------------------------------------------------------------
//1.OSTimeDly()函數(shù)
void ?OSTimeDly? ( INT16U ticks )
{
????INT8U y ;
# if ?OS_CRITICAL_METHOD? = = ?3
????OS_CPU_SR cpu_sr? = ?0 ;
# endif
???? if ? ( OSIntNesting? > ?0 ) ? {
???????? return ; //在中斷處理函數(shù)中調(diào)用了OSTimeDly(),那么直接退出
???? }
???? if ? ( ticks? > ?0 ) ? {
????????OS_ENTER_CRITICAL ( ) ;
//調(diào)用OSTimeDly()的進(jìn)程自己把自己從就緒控制矩陣中拿下來,
//即:去掉調(diào)度器(x,y)矩形陣列(OSRdyTbl,OSRdyGrp)中該task對(duì)應(yīng)的bit位,使得調(diào)度器不考慮
//該task的調(diào)度
????????y? = ?OSTCBCur - > OSTCBY ;
????????OSRdyTbl [ y ] ? & = ? ~ OSTCBCur - > OSTCBBitX ;
???????? if ? ( OSRdyTbl [ y ] ? = = ?0 ) ? {
????????????OSRdyGrp? & = ? ~ OSTCBCur - > OSTCBBitY ;
???????? }
//延時(shí)ticks值,放入OSTCBDly單元,在os時(shí)鐘滴答處理函數(shù)OSTimeTick()中,會(huì)處理該單元[gliethttp]
????????OSTCBCur - > OSTCBDly? = ?ticks ;
????????OS_EXIT_CRITICAL ( ) ;
//因?yàn)楸総ask正在運(yùn)行,所以本task現(xiàn)在的優(yōu)先級(jí)最高,現(xiàn)在本task已經(jīng)將自己從就緒控制矩陣中--調(diào)度器(x,y)矩形陣列
//把自己摘掉,所以調(diào)度函數(shù)OS_Sched()一定會(huì)切換到另一個(gè)task中執(zhí)行新task的代碼[gliethttp]
????????OS_Sched ( ) ; //具體參見《淺析μC/OS-II v2.85內(nèi)核調(diào)度函數(shù)》
???? } //ticks==0,那么什么也不做
}
//----------------------------------------------------------------------
//2.OSTimeTick()--在定時(shí)中斷里引用的系統(tǒng)滴答函數(shù)
void ?OSTimeTick? ( void )
{
????OS_TCB? * ptcb ;
# if ?OS_TICK_STEP_EN? > ?0
????BOOLEAN step ;
# endif
# if ?OS_CRITICAL_METHOD? = = ?3
????OS_CPU_SR cpu_sr? = ?0 ; //該3方式將使中斷狀態(tài)寄存器放入堆棧中
# endif
# if ?OS_TIME_TICK_HOOK_EN? > ?0
????OSTimeTickHook ( ) ;
# endif
# if ?OS_TIME_GET_SET_EN? > ?0
????OS_ENTER_CRITICAL ( ) ;
????OSTime + + ;
????OS_EXIT_CRITICAL ( ) ;
# endif
???? if ? ( OSRunning? = = ?OS_TRUE ) ? {
# if ?OS_TICK_STEP_EN? > ?0
//控制內(nèi)核的tick
???????? switch ? ( OSTickStepState ) ? {
???????????? case ?OS_TICK_STEP_DIS :
?????????????????step? = ?OS_TRUE ;
????????????????? break ;
???????????? case ?OS_TICK_STEP_WAIT :
?????????????????step? = ?OS_FALSE ;
????????????????? break ;
???????????? case ?OS_TICK_STEP_ONCE :
//本次tick將將影響到task的OSTCBDly域
//但以后的tick將一直被屏蔽,不會(huì)影響到OSTCBDly域
//直到外部將OSTickStepState改變?yōu)橹筟gliethttp]
?????????????????step? = ?OS_TRUE ;
?????????????????OSTickStepState? = ?OS_TICK_STEP_WAIT ;
????????????????? break ;
???????????? default :
?????????????????step? = ?OS_TRUE ; //本次tick將影響到task的OSTCBDly域
?????????????????OSTickStepState? = ?OS_TICK_STEP_DIS ;
????????????????? break ;
???????? }
???????? if ? ( step? = = ?OS_FALSE ) ? {
???????????? return ;
???????? }
# endif
????????ptcb? = ?OSTCBList ;
//2007-09-08 gliethttp
//OSTCBList是一個(gè)按進(jìn)程創(chuàng)建的先后順序鏈接成的task單向鏈表,最后創(chuàng)建的task在最前面,最先創(chuàng)建的
//task在單向鏈表的尾端,
//所以O(shè)S_TaskIdle空閑進(jìn)程在鏈表的最后,因?yàn)樗钕葎?chuàng)建
???????? while ? ( ptcb - > OSTCBPrio? ! = ?OS_TASK_IDLE_PRIO ) ? {
????????????OS_ENTER_CRITICAL ( ) ;
???????????? if ? ( ptcb - > OSTCBDly? ! = ?0 ) ? {
???????????????? if ? ( - - ptcb - > OSTCBDly? = = ?0 ) ? {
//該task的延時(shí)時(shí)間已到,解析此次延時(shí)是OSTimeDly()引起的,還是OSQPend()之類超時(shí)引起的[gliethttp]
???????????????????? if ? ( ( ptcb - > OSTCBStat? & ?OS_STAT_PEND_ANY ) ? ! = ?OS_STAT_RDY ) ? {
???????????????????????? //2007-09-08 gliethttp
???????????????????????? //如:由OSSemPend (pevent,timeout,perr);定義的timeout已經(jīng)到了,對(duì)應(yīng)task需要運(yùn)行了
???????????????????????? //超時(shí)時(shí)間到,所以不論當(dāng)前進(jìn)程是在做什么,只要時(shí)間一到
???????????????????????? //該task就可以運(yùn)行了,所以清除所有事件標(biāo)志,之后狀態(tài)標(biāo)示為OS_STAT_PEND_TO(超時(shí))
????????????????????????ptcb - > OSTCBStat? & = ? ~ ( INT8U ) OS_STAT_PEND_ANY ;
????????????????????????ptcb - > OSTCBStatPend? = ?OS_STAT_PEND_TO ; //超時(shí)異常
???????????????????? } ? else ? {
???????????????????????? //2007-09-08 gliethttp
???????????????????????? //說明該task調(diào)用的是OSTimeDly()
????????????????????????ptcb - > OSTCBStatPend? = ?OS_STAT_PEND_OK ; //正常結(jié)束
???????????????????? }
???????????????????? if ? ( ( ptcb - > OSTCBStat? & ?OS_STAT_SUSPEND ) ? = = ?OS_STAT_RDY ) ? {
???????????????????????? //2007-09-08 gliethttp
???????????????????????? //如果該task沒有suspend,那么把當(dāng)前就緒的task加入到運(yùn)行調(diào)度器的就緒控制矩陣中
???????????????????????? //等待被調(diào)度
????????????????????????OSRdyGrp? | = ?ptcb - > OSTCBBitY ;
????????????????????????OSRdyTbl [ ptcb - > OSTCBY ] ? | = ?ptcb - > OSTCBBitX ;
???????????????????? }
???????????????? }
???????????? }
????????????ptcb? = ?ptcb - > OSTCBNext ; //繼續(xù)運(yùn)算下一個(gè)task的OSTCBDly時(shí)間域
????????????OS_EXIT_CRITICAL ( ) ;
???????? }
???? }
}
總結(jié)
以上是生活随笔為你收集整理的浅析μC/OS-II OSTimeDly()函数和OSTimeTick()函数工作原理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 与中断相关的问题
- 下一篇: C语言 迷宫问题求解(顺序栈应用示例)