2.臨界段代碼學習

臨界段代碼的定義

臨界段代碼,也稱作臨界域,是一段不可分割的代碼。uC/OS-III中包含了很多臨界段代碼。如果臨界段可能被中斷,那麼就需要關中斷以保護臨界段。如果臨界段可能被任務級代碼打斷,那麼需要鎖調度器保護臨界段。uC/OS-III 中的臨界段的保護方法決定於ISR 中對消息的處理方式。詳見 “ 中斷管理” 。如果OS_CFG_ISR_POST_DEFERRED_EN 被設爲0(見OS_CFG.H),在進入臨界段之前uC/OS-III 會關中斷,在離開臨界段之後開中斷。如果OS_CFG_ISR_POST_DEFERRED_EN 被設爲1,在進入大多數臨界段之前會關調度器。

uC/OS-III 定義了一個進入臨界段的宏和兩個出臨界段的宏。

OS_CRITICAL_ENTER(),

OS_CRITICAL_EXIT(),

OS_CRITICAL_EXIT_NO_SCHED()

這些是uC/OS-III 的內部宏,不能被用戶代碼調用。然而,如果你需要進入你自己定義的臨界段。請查閱"資源管理"。

一:關中斷

1.在上面我們說過的,當OS_CFG_ISR_POST_DEFERRED_EN 被設爲0,在進入臨界段之前uC/OS-III 會關中斷,在離開臨界段之後開中斷。OS_CRITICAL_ENTER() 調用uC/CPU 的宏CPU_CRITICAL_ENTER() , 然後調用CPU_SR_Save() 。CPU_SR_Save()是用匯編寫的用於保存當前CPU 寄存器並關中斷。寄存器值以類型爲“cpu_sr”的變量存於調用者堆棧。

OS_CRITICAL_EXIT() 和OS_CRITICAL_EXIT_NO_SCHED() 都會調用uC/CPU 的宏CPU_CRITICAL_EXIT() 。CPU_CRITICAL_EXIT()調用CPU_SR_Restore()。CPU_SR_Restore()恢復所保存寄存器值到CPU 寄存器,也就是OS_CRITICAL_ENTER()調用前的狀態。如下:

#define  OS_CRITICAL_ENTER()                    CPU_CRITICAL_ENTER()
#define  OS_CRITICAL_ENTER_CPU_EXIT()
#define  OS_CRITICAL_EXIT()                     CPU_CRITICAL_EXIT()
#define  OS_CRITICAL_EXIT_NO_SCHED()            CPU_CRITICAL_EXIT()

2.測量關中斷的時間

uC/CPU 提供了測量關中斷時間的功能。通過設置CPU_CFG.H 中的CPU_CFG_TIME_MEAS_INT_DIS_EN (CPU_configure_time_measure_intrrupt_distance_enable其實是很好記的)爲1 啓用該功能。每次關中斷前開始測量,開中斷後結束測量。每個任務的關中斷時間在上文保存的時候被保存於OS_TCB(詳見OS_CPU.C 中的OSTaskSwHook()和第八章"上下文切換")

二:鎖住調度器

1.當設置OS_CFG_ISR_POST_DEFERRED_EN 爲1 時,在進入臨界段前uC/OS-III 會鎖住調度器,退出臨界段後開啓調度器。OS_CRITICAL_ENTER()遞增OSSchedLockNestingCtr,給調度器加鎖。這是一個決定調度器是否被開啓的變量。如果它不爲0 則調度器被鎖。{稱它爲調度器鎖嵌套值,表示調度器被加了幾把鎖}

OS_CRITICAL_EXIT()將OSSchedLockNestingCtr 遞減,給調度器解鎖。{調度器鎖嵌套值被減爲0 時,就會調用調度器}
OS_CRITICAL_EXIT_NO_SCHED() 也遞減OSSchedLockNestingCtr 的值,不同的是當其值減爲0 時,不調用調度器。

2.測量鎖調度器時間uC/OS-III 提供了測量鎖調度器時間的功能,通過設置OS_CFG.H中的OS_CFG_SCHED_LOCK_TIME_MEAS_EN 爲1 開啓。加鎖調度器前測量開始,解鎖調度器後測量結束。測得的兩種值爲:總的鎖調度器時間,每個任務的鎖調度器時間。因此,用戶可以知道每個任務的鎖調度器時間,並根據此優化代碼。

三.uC/OS-III與長臨界段

瞭解

四.總結
uC/OS-III 中會用到臨界段, 用關中斷(OS_CFG.H 中設置OS_CFG_ISR_POST_DEFERRED_EN 爲0) 或者鎖調度器( 設置OS_CFG_ISR_POST_DEFERRED_EN 爲1)實現保護臨界段的功能。用戶程序不能使用這些代碼:
OS_CRITICAL_ENTER()
OS_CRITICAL_EXIT()
OS_CRITICAL_EXIT_NO_SCHED()
如果設置了CPU_CFG.H 中的CPU_CFG_TIME_MEAS_INT_DIS_EN 爲1 時。uC/CPU 將會任務總的關中斷時間和每個任務的關中斷時間。

如果設置了OS_CFG.H 中的OS_CFG_SCHED_LOCK_TIME_MEAS_EN 爲1 時。uC/OS-III 會測量任務總的鎖調度器時間和每個任務鎖調度器時間。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章