2009年6月16日 星期二

chapter 5

※ Time Management
所以的OS都必須面臨怎麼管理時間,
包括micro kernel都要將這部分放在kernel裡面,
否則很難寫。
1. OSTimeDly()
2. OSTimeDlyHMSM() 和OSTimeDly()設計方法幾乎一樣,
多一個時間的轉換,把小時.分...轉成tick
3. OSTimeDlyResume() 有人想睡5個tick的時間,
因為有緊急事件,不能睡那麼久,用OSTimeDlyResume()叫他
4. OSTimeGet() 沒啥意義,字面上
5. OSTimeSet() 同上

※ Delay a task until tx
t=OSTimeGet()
if(tx-t>0)
OSTimeDly(tx-t)
OSTimeDly()睡多久,OSTimeGet()得到現在時間
利用這兩個函式,寫出要睡到下午5點鐘的程式。
----->會發生錯誤,t會有誤差

※ OSTimeDly()
1. 把task從rdyQ裡移除
2. TCB裡的欄位OSTCBDly代表想要睡多久,要睡幾個tick
3. 最高優先權的task跑去睡覺,所以要呼叫OS_Sched()

※ OSTimeDlyHMSM()
1. 和OSTimeDly差不多
2. 將時分秒轉換成幾個tick(毫秒)
3. 因為integer,所以最大65535,如果大於65535就用loop解決
OSTimeDly(32768)不用65535因為怕溢位.....

※ OSTimeTick() Timer(1)
1. timer為interrupt進來,CPU去做ISR,前半段和後半段用組語寫,
前半段組語,將CPU目前的狀態全部存下來,將來就可以回復。
後半段,把記憶體的值搬到CPU。從哪邊被打斷就從哪邊重新執行。
中間用C語言寫就可以。
2. OSTimeTick()
完全使用C語言撰寫,演算法和資料結構最為重要.....,
3. 從組語裡去呼叫OSTimeTick()
5. OSTCBList將uCOSII裡所有的task串接在一起
4. OSTimeTick()裡的foreach(....)
去OSTCBList裡每個task做檢查看OSTCBDly是否>0,
如果大於0就-1,代表經過1個tick的時間,
如果等於1,將從1變0的時候,代表等的時間已經到了,即讓task變ready
5. task最多:uCOSII2.5.2->64,uCOSII2.8.x->256,linux->以k來計算
6. OSTimeTick()是function call,執行時間會很長,
就會造成I/O的performance會不好,中斷會被disable掉太久的時間。
要自己enable interrupt。
timer這個interrupt的priority非常高,較低優先的的那些task和interrupt會進不來,
為了讓這個情況不發生,所以driver最好不要這樣寫。

※ OSTimeTick() Timer(2)
1. 這種寫法比較好,但程式碼比較複雜,執行時間更長。
2. 中斷進來呼叫ISR,ISR只執行OSMBoxPost,就結束了,因此ISR長度很短。
3. OSMBoxPost送出一個message,只是把某一個或某幾個flag設為1,就執行完了。
4. interrupt進來,CPU收到並呼叫ISR,執行OSMBoxPost,往下執行,ISR結束。
接下來由task當作kernel thread接手,此時中斷被打開,優先權很高。
TickTask()
{
OSMBoxPend()
OSTimeTick()
OS_Sched() //這裡要重新排程 因為是系統裡自己寫的程式
}
OSTimeTick() Timer(1)不用自己call OS_Sched()是因為
ISR結束時會呼叫OSINTExit(),裡面就會call OS_Sched(),所以不用再去call
6. 在linux裡,ISR為top half,kernel thread為bottom half(可延遲的function)
7. 在uCOSII裡,OSTickISR()為top half,OSTimeTick()為bottom half

沒有留言:

張貼留言