當前位置:首頁 » 編程軟體 » ostcb編譯條件

ostcb編譯條件

發布時間: 2024-10-05 11:28:24

⑴ 什麼是UCOS操作系統

u C / O S 是一種免費公開源代碼、結構小巧、具有可剝奪實時內核的實時操作系統。

μC/OS-II 的前身是μC/OS,最早出自於1992 年美國嵌入式系統專家Jean J.Labrosse 在《嵌入式系統編程》雜志的5 月和6 月刊上刊登的文章連載,並把μC/OS 的源碼發布在該雜志的B B S 上。

μC/OS 和μC/OS-II 是專門為計算機的嵌入式應用設計的,絕大部分代碼是用C語言編寫的。CPU 硬體相關部分是用匯編語言編寫的、總量約200行的匯編語言部分被壓縮到最低限度,為的是便於移植到任何一種其它的CPU 上。用戶只要有標準的ANSI 的C交叉編譯器,有匯編器、連接器等軟體工具,就可以將μC/OS-II嵌人到開發的產品中。μC/OS-II 具有執行效率高、佔用空間小、實時性能優良和可擴展性強等特點, 最小內核可編譯至 2KB 。μC/OS-II 已經移植到了幾乎所有知名的CPU 上。

嚴格地說uC/OS-II只是一個實時操作系統內核,它僅僅包含了任務調度,任務管理,時間管理,內存管理和任務間的通信和同步等基本功能。沒有提供輸入輸出管理,文件系統,網路等額外的服務。但由於uC/OS-II良好的可擴展性和源碼開放,這些非必須的功能完全可以由用戶自己根據需要分別實現。

uC/OS-II目標是實現一個基於優先順序調度的搶占式的實時內核,並在這個內核之上提供最基本的系統服務,如信號量,郵箱,消息隊列,內存管理,中斷管理等。

任務管理

uC/OS-II 中最多可以支持64 個任務,分別對應優先順序0~63,其中0 為最高優先順序。63為最低級,系統保留了4個最高優先順序的任務和4個最低優先順序的任務,所有用戶可以使用的任務數有56個。

uC/OS-II提供了任務管理的各種函數調用,包括創建任務,刪除任務,改變任務的優先順序,任務掛起和恢復等。

系統初始化時會自動產生兩個任務:一個是空閑任務,它的優先順序最低,改任務僅給一個整形變數做累加運算;另一個是系統任務,它的優先順序為次低,改任務負責統計當前cpu的利用率。

時間管理

uC/OS-II的時間管理是通過定時中斷來實現的,該定時中斷一般為10毫秒或100毫秒發生一次,時間頻率取決於用戶對硬體系統的定時器編程來實現。中斷發生的時間間隔是固定不變的,該中斷也成為一個時鍾節拍。

uC/OS-II要求用戶在定時中斷的服務程序中,調用系統提供的與時鍾節拍相關的系統函數,例如中斷級的任務切換函數,系統時間函數。

內存管理

在ANSI C中是使用malloc和free兩個函數來動態分配和釋放內存。但在嵌入式實時系統中,多次這樣的錯作會導致內存碎片,且由於內存管理演算法的原因,malloc和free的執行時間也是不確定。

uC/OS-II中把連續的大快內存按分區管理。每個分區中包含整數個大小相同的內存塊,但不同分區之間的內存快大小可以不同。用戶需要動態分配內存時,系統選擇一個適當的分區,按塊來分配內存。釋放內存時將該塊放回它以前所屬的分區,這樣能有效解決碎片問題,同時執行時間也是固定的。

任務間通信與同步

對一個多任務的操作系統來說,任務間的通信和同步是必不可少的。uC/OS-II中提供了4中同步對象,分別是信號量,郵箱,消息隊列和事件。所有這些同步對象都有創建,等待,發送,查詢的介面用於實現進程間的通信和同步。

任務調度

uC/OS-II 採用的是可剝奪型實時多任務內核。可剝奪型的實時內核在任何時候都運行就緒了的最高優先順序的任務。

uC/os-II的任務調度是完全基於任務優先順序的搶占式調度,也就是最高優先順序的任務一旦處於就緒狀態,則立即搶占正在運行的低優先順序任務的處理器資源。為了簡化系統設計,uC/OS-II規定所有任務的優先順序不同,因為任務的優先順序也同時唯一標志了該任務本身。

任務調度將在以下情況下發生:

1) 高優先順序的任務因為需要某種臨界資源,主動請求掛起,讓出處理器,此時將調度就緒狀態的低優先順序任務獲得執行,這種調度也稱為任務級的上下文切換。

2) 高優先順序的任務因為時鍾節拍到來,在時鍾中斷的處理程序中,內核發現高優先順序任務獲得了執行條件(如休眠的時鍾到時),則在中斷態直接切換到高優先順序任務執行。這種調度也稱為中斷級的上下文切換。

這兩種調度方式在uC/OS-II的執行過程中非常普遍,一般來說前者發生在系統服務中,後者發生在時鍾中斷的服務程序中。

調度工作的內容可以分為兩部分:最高優先順序任務的尋找和任務切換。其最高優先順序任務的尋找是通過建立就緒任務表來實現的。u C / O S 中的每一個任務都有獨立的堆棧空間,並有一個稱為任務控制塊TCB(Task Control Block)的數據結構,其中第一個成員變數就是保存的任務堆棧指針。任務調度模塊首先用變數OSTCBHighRdy 記錄當前最高級就緒任務的TCB 地址,然後調用OS_TASK_SW()函數來進行任務切換。

μC/OS-II的組成部分

μC/OS-II可以大致分成核心、任務處理、時間處理、任務同步與通信,CPU的移植等5個部分。

1) 核心部分(OSCore.c)

是操作系統的處理核心,包括操作系統初始化、操作系統運行、中斷進出的前導、時鍾節拍、任務調度、事件處理等多部分。能夠維持系統基本工作的部分都在這里。

2) 任務處理部分(OSTask.c)

任務處理部分中的內容都是與任務的操作密切相關的。包括任務的建立、刪除、掛起、恢復等等。因為μC/OS-II是以任務為基本單位調度的,所以這部分內容也相當重要。

3) 時鍾部分(OSTime.c)

μC/OS-II中的最小時鍾單位是timetick(時鍾節拍)。任務延時等操作是在這里完成的。

4) 任務同步和通信部分

為事件處理部分,包括信號量、郵箱、郵箱隊列、事件標志等部分;主要用於任務間的互相聯系和對臨界資源的訪問

5) 與CPU的介面部分

是指μC/OS-II針對所使用的CPU的移植部分。由於μC/OS-II是一個通用性的操作系統,所以對於關鍵問題上的實現,還是需要根據具體CPU的具體內容和要求作相應的移植。這部分內容由於牽涉到SP等系統指針,所以通常用匯編語言編寫。主要包括中斷級任務切換的底層實現、任務級任務切換的底層實現、時鍾節拍的產生和處理、中斷的相關處理部分等內容。

⑵ 嵌入式實時操作系統uc/uo-II在ARM上的移植 這個設計有做過嗎,給點線索 非常感謝

所謂移植,就是使一個實時內核能在某個微處理器或微控制器上運行。為了方便移植,大部分的µC/OS-Ⅱ代碼是用C語言寫的;但仍需要用C和匯編語言寫一些與處理器相關的代碼,這是因為µC/OS-Ⅱ在讀寫處理器寄存器時只能通過匯編語言來實現。由於µC/OS-Ⅱ在設計時就已經充分考慮了可移植性,所以µC/OS-Ⅱ的移植相對來說是比較容易的。[5,6]
要使µC/OS-Ⅱ正常運行,處理器必須滿足以下要求:
(1) 處理器的C編譯器能產生可重入代碼。
(2) 用C語言就可以打開和關閉中斷。
(3) 處理器支持中斷,並且能產生定時中斷(通常在10至100Hz之間)。
(4) 處理器支持能夠容納一定量數據(可能是幾千位元組)的硬體堆棧。
(5) 處理器有將堆棧指針和其它CPU寄存器讀出和存儲的指令
圖2-1說明了µC/OS-Ⅱ的結構以及它與硬體的關系。從圖中可以看到整個系統的架構。最底層是硬體層,該層主要涉及到CPU處理器的架設,以及它與外部各功能模塊的連接,對於CPU處理器的初始化也是構架嵌入式系統的重要內容,特別是對定時器的設置,將是構建操作系統的基礎,它決定整個系統的性能。對於軟體部分,最底層是與處理器相關的程序代碼,該段代碼直接對CPU處理器進行初始化,這部分代碼就是移植操作系統的主要內容,也是最難以理解的部分。這段代碼絕大部分程序是用匯編語言編寫的,因為在程序運行的時候,這部分代碼的調用次數最頻繁。在向上的代碼就與處理器沒有任何的關系,其中一部分包括操作系統的配置文件,像OS_CORE.c,OS_FLAG.c等文件。這部分代碼是用來編寫一些基本的底層函數,這些函數將作為以後應用部分的基本函數庫進行調用,這部分函數構成了操作系統的基本構架,不同的操作系統所對應的系統的設計思想不同,主要體現在這些函數的設計中。除了系統的基本函數外,還有應用部分的基本配置文件。該文件聲明的是與具體的應用配置有關的一些設置文件。比如,各任務的一些基本參數,所使用的信號量的聲明,以及液晶的參數配置等。不同的應用程序對應的該文件參數配置也不同。有了底層的基本配置文件,就可以編寫具體的應用程序了,最上層就是應用程序,針對不同的應用需求,編寫不同的應用程序。
μCOS-II不使用C語言中的short、int、long等數據類型的定義,因為它們與處理器類型有關,隱含著不可移植性。代之以移植性強的整數數據類型,這樣,既直觀又可移植,不過這就成了必須移植的代碼。根據ADS編譯器的特性,這些代碼如程序清單圖2-2所示。
與所有的實時內核一樣,µC/OS-Ⅱ需要先禁止中斷再訪問代碼的臨界段,並且在訪問完畢後重新允許中斷。這就使得µC/OS-Ⅱ能夠保護臨界段代碼免受多任務或中斷服務常式(ISRs)的破壞。為了隱藏編譯器廠商提供的具體實現方法,µC/OS-Ⅱ定義了兩個宏來禁止和允許中斷:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()。
μCOS-II使用結構常量OS_STK_GROWTH中指定堆棧的生長方式:置OS_STK_GROWTH為0表示堆棧從下往上長。置OS_STK_GROWTH為1表示堆棧從上往下長。雖然ARM處理器核對於兩種方式均支持,但ADS的C語言編譯器僅支持一種方式,即從上往下長,並且必須是滿遞減堆棧,所以OS_STK_GROWTH的值為1。
µC/OS-Ⅱ的移植實例要求用戶編寫四個簡單的匯編語言函數: OSStartHighRdy();OSCtxSw();OSIntCtxSw();OSTickISR()。如果用戶的編譯器支持插入匯編語言代碼的話,用戶就可以將所有與處理器相關的代碼放到OS_CPU_C.C文件中,而不必再擁有一些分散的匯編語言文件。
使就緒狀態的任務開始運行的函數叫做OSStart(),如下示意函數所示。在用戶調用OSStart()之前,用戶必須至少已經建立了一個任務。OSStartHighRdy()假設OSTCBHighRdy指向的是優先順序最高的任務的任務控制塊。為了簡單一點,堆棧指針總是儲存在任務控制塊(即它的OS_TCB)的開頭。換句話說,也就是要想恢復的任務堆棧指針總是儲存在OS_TCB的0偏址內存單元中。
如果當前任務調用µC/OS-Ⅱ提供的系統服務,並使得更高優先順序任務處於就緒狀態,µC/OS-Ⅱ就會藉助上面提到的向量地址找到OSCtxSw()。在系統服務調用的最後,µC/OS-Ⅱ會調用OSSched(),並由此來推斷當前任務不再是要運行的最重要的任務了。軟中斷 (或陷阱) 指令會強制一些處理器寄存器(比如返回地址和處理器狀態字)到當前任務的堆棧中,並使處理器執行OSCtxSw()。這些代碼必須寫在匯編語言中,因為用戶不能直接從C中訪問CPU寄存器。注意在OSCtxSw()和用戶定義的函數OSTaskSwHook()的執行過程中,中斷是禁止的。

OSIntExit()通過調用OSIntCtxSw()來從ISR中執行切換功能。因為OSIntCtxSw()是在ISR中被調用的,所以可以斷定所有的處理器寄存器都被正確地保存到了被中斷的任務的堆棧之中。實際上除了需要的東西外,堆棧結構中還有其它的一些東西。OSIntCtxSw()必須要清理堆棧,這樣被中斷的任務的堆棧結構內容才能滿足人們的需要。
要想了解OSIntCtxSw(),大家可以看看µC/OS-Ⅱ調用該函數的過程。假定中斷不能嵌套(即ISR不會被中斷),中斷是允許的,並且處理器正在執行任務級的代碼。當中斷來臨的時候,處理器會結束當前的指令,識別中斷並且初始化中斷處理過程,包括將處理器的狀態寄存器和返回被中斷的任務的地址保存到堆棧中。至於究竟哪些寄存器保存到了堆棧上,以及保存的順序是怎樣的,並不重要。
接著,CPU會調用正確的ISR。µC/OS-Ⅱ要求ISR在開始時要保存剩下的處理器寄存器。一旦寄存器保存好了,µC/OS-Ⅱ就要求或者調用OSIntEnter(),或者將變數OSIntNesting加1。在這個時候,被中斷任務的堆棧中只包含了被中斷任務的寄存器內容。現在,ISR可以執行中斷服務了。並且如果ISR發消息給任務(通過調用OSMboxPost()或OSQPost()),恢復任務(通過調用OSTaskResume()),或者調用OSTimeTick()或OSTimeDlyResume()的話,有可能使更高優先順序的任務處於就緒狀態。
假設有一個更高優先順序的任務處於就緒狀態。µC/OS-Ⅱ要求用戶的ISR在完成中斷服務的時候調用OSIntExit()。OSIntExit()會告訴µC/OS-Ⅱ到了返回任務級代碼的時間了。調用OSIntExit()會導致調用者的返回地址被保存到被中斷的任務的堆棧中。
OSIntExit()剛開始時會禁止中斷,因為它需要執行臨界段的代碼。根據OS_ENTER_CRITICAL()的不同執行過程,處理器的狀態寄存器會被保存到被中斷的任務的堆棧中。OSIntExit()注意到由於有更高優先順序的任務處於就緒狀態,被中斷的任務已經不再是要繼續執行的任務了。在這種情況下,指針OSTCBHighRdy會被指向新任務的OS_TCB,並且OSIntExit()會調用OSIntCtxSw()來執行任務切換。調用OSIntCtxSw()也同樣使返回地址被保存到被中斷的任務的堆棧中。
用戶切換任務的時候,用戶只想將某些項保留在堆棧中,並忽略其它項。這是通過調整堆棧指針(加一個數在堆棧指針上)來完成的。加在堆棧指針上的數必須是明確的,而這個數主要依賴於移植的目標處理器(地址空間可能是16,32或64位),所用的編譯器,編譯器選項,內存模式等等。另外,處理器狀態字可能是8,16,32甚至64位寬,並且OSIntExit()可能會分配局部變數。有些處理器允許用戶直接增加常量到堆棧指針中,而有些則不允許。在後一種情況下,可以通過簡單的執行一定數量的pop(出棧)指令來實現相同的功能。一旦堆棧指針完成調整,新的堆棧指針會被保存到被切換出去的任務的OS_TCB中。
這些代碼必須寫在匯編語言中,因為用戶不能直接從C語言中訪問CPU寄存器。如果用戶的編譯器支持插入匯編語言代碼的話,用戶就可以將OSIntCtxSw()代碼放到OS_CPU_C.C文件中,而不放到OS_CPU_A.ASM文件中。正如用戶所看到的那樣,除了第一行以外,OSIntCtxSw()的代碼與OSCtxSw()是一樣的。這樣在移植實例中,用戶可以通過「跳轉」到OSCtxSw()中來減少OSIntCtxSw()代碼量。
µC/OS-Ⅱ要求用戶提供一個時鍾資源來實現時間的延時和期滿功能。時鍾節拍應該每秒鍾發生10-100次。為了完成該任務,可以使用硬體時鍾,也可以從交流電中獲得50/60Hz的時鍾頻率。
這些代碼必須寫在匯編語言中,因為用戶不能直接從C語言中訪問CPU寄存器。如果用戶的處理器可以通過單條指令來增加OSIntNesting,那麼用戶就沒必要調用OSIntEnter()了。增加OSIntNesting要比通過函數調用和返回快得多。OSIntEnter()只增加OSIntNesting,並且作為臨界段代碼中受到保護。
µC/OS-Ⅱ的移植實例要求用戶編寫六個簡單的C函數:OSTaskStkInit(); OSTaskCreateHook();OSTaskDelHook();OSTaskSwHook();OSTaskStatHook(); OSTimeTickHook()。唯一必要的函數是OSTaskStkInit(),其它五個函數必須得聲明但沒必要包含代碼。
OSTaskCreate()和OSTaskCreateExt()通過調用OSTaskStkInt()來初始化任務的堆棧結構,因此,堆棧看起來就像剛發生過中斷並將所有的寄存器保存到堆棧中的情形一樣。顯示了OSTaskStkInt()放到正被建立的任務堆棧中的東西。注意,在這里我假定了堆棧是從上往下長的。下面的討論同樣適用於從下往上長的堆棧。
在用戶建立任務的時候,用戶會傳遞任務的地址,pdata指針,任務的堆棧棧頂和任務的優先順序給OSTaskCreate()和OSTaskCreateExt()。雖然OSTaskCreateExt()還要求有其它的參數,但這些參數在討論OSTaskStkInt()的時候是無關緊要的。為了正確初始化堆棧結構,OSTaskStkInt()只要求剛才提到的前三個參數和一個附加的選項,這個選項只能在OSTaskCreateExt()中得到。
該函數主要是對相關的幾個寄存器進行初始化工作,初始化的寄存器對應於

⑶ uC/OS-II的解決方法

對於這樣的設計方式,CPU必須能夠:
◆ 有相應的CPU寄存器能夠模仿SP的一些功能,能使用相應的指令來完成類似SP的一些操作;
◆ 作為SP使用的寄存器在編譯過程中最好不被編譯器默認使用。在IAR的編譯器中,有一個選項可以避免在編譯過程中使用到R4、R5。
這兩點MSP430都可以做到。
下面對一個正在運行的優先順序為6的任務中斷後,會發生的幾種情況進行分析。
1)在中斷的處理過程中沒有更高優先順序的中斷產生,即不會產生中斷嵌套。
圖3所示為中斷發生後對於任務優先順序為6的任務堆棧所進行的操作。中斷發生後,PC和SR被系統壓棧②,對於IAR C編譯器來說,會按照復雜度不同的中斷服務程序的要求,默認地進行一些寄存器的壓棧操作③。因為我們要求的堆棧格式是如圖2所示的,我們要把SP調整到SR後面④,然後進行R4~R15的壓棧操作,形成我們所要求的堆棧格式⑤。
進行任務堆棧的壓棧工作以後,就可以調整SP的指針到系統堆棧了,如圖4所示。壓棧後的SP指向最後一個壓棧內容①。我們把SP的值賦值給優先順序6任務的TCB->OSTCBStkPtr,以便進行任務調度的時候出棧使用②。接著,就把SP調整到系統堆棧處③。在中斷處理過程中,可能會出現壓棧的操作,那麼這種情況下SP的指針會隨之移動。由於是中斷堆棧中,所以不會破壞任務堆棧的格式。
由於沒有中斷嵌套,在中斷處理中沒有別的中斷發生,那麼返回的步驟和上述的進棧操作正好相反。在中斷處理完了以後,SP會自動回到圖4中③的SP位置。接著,系統會查詢到優先順序最高的任務,然後把SP的指針移到優先順序最高的任務的任務堆棧,進行R15~R4的出棧工作,最後用RETI中斷返回指令返回到新的任務。因為我們把所有的任務堆棧都規定成相同的格式,所以它們之間不會產生問題。這里需要注意的是,因為系統在C編譯器的中斷處理中會對中斷進入時默認壓棧的寄存器出棧,所以在設計出棧的程序時,要先把這些內容壓棧,這樣才能正確出棧。
2)在中斷的處理過程中,有別的中斷產生,產生中斷嵌套。
如圖5所示,由於在處理中斷的時候,SP已經被移到系統堆棧去了,只有當中斷退出的時候才可能把SP移到別的任務的任務堆棧中。所以在中斷的時候進行中斷嵌套,那麼對於中斷的處理和第一次是一樣的,所不同的是,這次保存在堆棧中的不是任務運行中的寄存器,而是中斷處理中的寄存器,而且是保存在系統堆棧中而不是任務堆棧中。從這里就可以看出優化內存的效果。所有的中斷嵌套中的寄存器壓棧都壓在系統堆棧中,這樣對於任務堆棧內存大小的要求大大降低。
因為μC/OS-II在進入中斷中,會把全局變數OSIntNesting++;在退出中斷的時候,又會把OSIntNesting--。在退出中斷進行任務切換之前,μC/OS-II會先判斷OSIntNesting是否為0,是0才會進行任務調度。當第二中斷運行結束以後,退出中斷嵌套的時候,OSIntNesting不為0,也就不會進行任務調度。因此,仍舊在系統堆棧出棧,那麼系統會繼續前面沒有完成的中斷服務程序。
接著退出中斷的順序和非中斷嵌套的順序是一樣的。在中斷處理完以後,SP會自動回到圖4中③的SP位置。接著,系統會查詢到優先順序最高的任務,然後把SP的指針移到優先順序最高的任務的任務堆棧。進行R15~R4的出棧工作,最後用RETI中斷返回指令返回到新的任務。
中斷的情況基本上就是上述兩種。對於有些文獻中提到的在中斷中會調度到更高優先順序的任務的情況,筆者覺得是不應該發生的。因為從上面的分析可以看出,默認的(μC/OS-II的設計思路)中斷處理會同時對全局變數OSIntNesting進行增減處理,以給出是否需要任務調度的條件。那麼即使在中斷服務程序中把更高優先順序的任務就緒,也會等到中斷退出以後再進行調度,除非是在中斷中直接調用更高優先順序的任務函數。但這種方法應該是和μC/OS-II的原則相違背的,沿用的是以前前後台設計的思路。
對於這樣的設計方式,時鍾節拍的處理方式必須和一般的中斷處理方式是一樣的。一般來說,MSP430使用WATCHDOG時鍾中斷作為時鍾節拍的產生源。從本質上來說,時鍾節拍本身也是中斷處理過程,所以對於時鍾節拍的處理應該和其它的中斷處理過程相同。實際上,在時鍾節拍的處理過程中也可能會存在中斷嵌套的問題。
中斷堆棧和任務堆棧分離設計的程序流程如圖6所示。

⑷ UC/OS與linux操作系統的區別

uc/os比較簡單一點,開始學的uc/os,感覺沒意思了就開始學linux,感覺ucos只是在單片機上跑跑,像arm9的一般是跑linux。其實先學哪個都差不多,因為學習方法大不相同,差別太大了,ucos太簡單,就一些信號量,郵箱什麼的,懂了也就會了,linux有點難,涉及知識太多,光是涉及內核以外的編程就需要大把大把的經典書籍去看。興趣很重要,都靠興趣過來的。

熱點內容
林肯冒險家怎麼查看配置 發布:2024-11-05 15:55:12 瀏覽:112
可以上傳球球的照片 發布:2024-11-05 15:42:59 瀏覽:738
拉箱怎麼改密碼 發布:2024-11-05 15:38:02 瀏覽:862
http怎麼配置 發布:2024-11-05 15:02:45 瀏覽:461
12級緩存 發布:2024-11-05 14:52:09 瀏覽:578
神武4腳本 發布:2024-11-05 14:48:50 瀏覽:702
王者榮耀反復解壓 發布:2024-11-05 14:31:58 瀏覽:853
存儲引擎有哪些品牌 發布:2024-11-05 14:25:59 瀏覽:39
紅薯的存儲方法 發布:2024-11-05 14:17:32 瀏覽:757
腳本錯誤彈窗口在哪裡 發布:2024-11-05 14:01:16 瀏覽:967