uC OS II原始碼分析(四)

2021-09-20 14:52:12 字數 2785 閱讀 8192

核心結構

1,  臨界區,os_enter_critical和os_exit_critical

為了處理臨界區**,必須關中斷,等處理完畢後,再開中斷。關中斷可以避免其他任務或中斷進入臨界區**。uc/os-ii定義了這兩個巨集來實現,但注意一條:呼叫uc/os-ii功能函式時,中斷應該總是開著的。

1)當os_critical_method= = 1時,簡單實現如下:

#define os_enter_critical() disable_int() 

# define os_exit_critical() enable_int()

但這樣有乙個問題,如果禁止中斷的情況下呼叫uc/os-ii功能函式,那麼從功能函式返回時,中斷可能變成允許的了,而實際上還是希望是禁止的。

2)當os_critical_method= = 2時,實現如下:

#define os_enter_critical()    

asm(「push psw」);

asm(「di」);

#define os_exit_critical()

asm(「pop psw」);

執行os_enter_critical()時,先將中斷狀態儲存到堆疊,然後關中斷;執行os_exit_critical()時,再從堆疊中恢復原來的中斷開/關狀態。這種方法不會改變中斷狀態,避免前面的問題。

3)當os_critical_method= = 3時,實現如下:

#define os_enter_critical()    

cpu_sr = get_processor_psw();

disable_interrupts();

#define os_exit_critical()

set_ processor_psw(cpu_sr);

將處理器狀態字儲存在區域性變數中。

2,  任務是乙個無限迴圈,返回型別為void,引數void*,用於傳資料給任務。任務可以呼叫ostaskdel(os_prio_self)進行自我刪除。任務有5種狀態:

1)     睡眠態。任務駐留在程式空間(rom或ram),還未交給uc/os-ii來管理。

2)     就緒態。ostaskcreate()或ostaskcreateext()來建立乙個任務後,就進入就緒態。任務可以呼叫ostaskdel返回到睡眠態,或呼叫該函式讓另乙個任務進入睡眠態。

3)     執行態。osstart()啟動多工執行。它只在啟動時呼叫一次,執行就緒列表中優先順序最高的任務。就緒的任務只有當所以優先順序比其高的任務轉為等待狀態,或者是被刪除了,才能進入執行態。

4)     等待狀態。正在執行的任務可以呼叫ostimedly()或ostimedlyhmsm()將自身延遲一段時間進入等待狀態,一直到延遲時間到來。這兩個函式會強制執行任務切換,選擇下乙個優先順序最高的任務執行。等待時間過去後,系統服務函式ostimetick()使延遲了的任務進入就緒態。

正在執行的任務也可能需要等待某一事件的發生,可以呼叫:osflagpend(),ossempend(),osmutexpend(),osmboxpend(),osqpend()等函式。若某事件未發生,則任務進入等待狀態,直到事件發生。當任務因等待事件被掛起時,下乙個優先順序最高的任務得到cpu。當事件發生了或超時,被掛起的任務進入就緒態。事件發生的報告可能來自另乙個任務或中斷服務子程式。

5)     中斷服務態 。被中斷的任務進入中斷服務態,從而被掛起,中斷服務子程式得到cpu,後者可能報告乙個或多個事件發生,從而使乙個或多個任務進入就緒態。因此從中斷服務子程式返回前,uc/os-ii要判斷被中斷的任務的優先順序和就緒列表中其他任務的優先順序高低,選擇最高的任務進入執行態。

6)     當所以任務都在等待事件發生或等待延遲的時間結束時,uc/os-ii執行ostaskidle()任務。

3,  任務控制塊(os_tcb)

建立乙個任務時,乙個os_tcb就被賦值。當任務的cpu被剝奪時,用它來儲存任務的狀態,當任務重新得到cpu時,它也能保證任務從當時被中斷的那一點繼續執行。os_tcb全部駐留在ram中。

typedef struct os_tcb 

os_tcb;

uc/os-ii在通過os_max_tasks定義了最大的任務數目,這也決定了分配給使用者程式的任務控制塊os_tcb的數目,但此外uc/os-ii還分配給系統任務os_n_sys_tasks若干個額外的任務控制塊,供其內部使用。uc/os-ii初始化時,所以任務控制塊都被鏈結成單向空任務鍊錶,任務一旦建立,空任務控制塊指標ostcbfreelist指向的任務控制塊就賦給該任務,然後ostcbfreelist調整為指向鍊錶中下乙個空任務控制塊。一旦任務被刪除,任務控制塊被還給空任務鍊錶。

任務建立時,os_tcbinit()初始化任務控制塊,函式ostaskcreate()或ostaskcreateext()呼叫任務控制塊初始化函式tcbinit。

int8u  os_tcbinit (int8u prio, os_stk *ptos, os_stk *pbos, int16u id, int32u stk_size, void *pext, int16u opt)

ostcblist               = ptcb;

osrdygrp               |= ptcb->ostcbbity;         /*讓使用者進入就緒態*/

osrdytbl[ptcb->ostcby] |= ptcb->ostcbbitx;

os_exit_critical();

return (os_no_err);

}os_exit_critical();

return (os_no_more_tcb);

}

出處:本部落格遵從

uC OS II原始碼分析(四)

核心結構 1,臨界區,os enter critical 和os exit critical 為了處理臨界區 必須關中斷,等處理完畢後,再開中斷。關中斷可以避免其他任務或中斷進入臨界區 uc os ii 定義了這兩個巨集來實現,但注意一條 呼叫 uc os ii 功能函式時,中斷應該總是開著的。1 ...

uC OS II原始碼分析(四)

核心結構 1,臨界區,os enter critical 和os exit critical 為了處理臨界區 必須關中斷,等處理完畢後,再開中斷。關中斷可以避免其他任務或中斷進入臨界區 uc os ii 定義了這兩個巨集來實現,但注意一條 呼叫 uc os ii 功能函式時,中斷應該總是開著的。1 ...

uC OS II原始碼分析(四)

核心結構 1,臨界區,os enter critical和os exit critical 為了處理臨界區 必須關中斷,等處理完畢後,再開中斷。關中斷可以避免其他任務或中斷進入臨界區 uc os ii定義了這兩個巨集來實現,但注意一條 呼叫uc os ii功能函式時,中斷應該總是開著的。1 當os ...