Ⅰ、寫在前面
學習本文之前可以參考我前面基於STM32硬件平台移植UCOS2的幾篇文章,我將其匯總在一起:
要想學習,或使用系統配套的資源(如:信號量、消息郵箱、消息隊列等),就需要先了解一下系統內核大致的原理,也就是先了解大致,在研究細節的東西(從外到內),本文就是接着前面移植的文章來講述關於系統內核的知識。
本文主要是結合前面移植好、可以運行的源代碼來進行講述關於最新版本UCOS2系統內部代碼。
關於本文的更多詳情請往下看。
Ⅱ、UCOS操作系統配置
看過我前面移植UCOS的文章,或打開過我移植成功的軟件工程,都應該大體知道一個簡單的UCOS系統大概需要一些什么配置,包含哪些部分等。
本節將對UCOS軟件工程總體的一些知識進行講述(從大方向來描述一下),也算是對某些知識的再次回顧。
UCOS系統配置就是修改os_cfg.h文件,就是使能或失能某些功能,也就是所謂的系統裁剪。

比如:
我們不使能APP應用HOOK函數,則#define OS_APP_HOOKS_EN 0u
如果使能APP應用HOOK函數, 則#define OS_APP_HOOKS_EN 1u
再比如:
我們定義最低優先級(值)為63,則#define OS_LOWEST_PRIO 63u
定義最大數10個任務,則#define OS_MAX_TASKS 10u
其實這里的配置在系統中很多通過預處理(配置了的才編譯,未配置不編譯)來實現的,也就是直接影響程序編譯的大小,所以叫系統裁剪。
我提供(移植完成)的實例里面有很多資源(如:信號量、消息郵箱、消息隊列等)都沒有實現,所以那些都是失能的(即都配置為0)。
Ⅲ、主函數描述
主函數在裸機程序和操作系統程序中都是有的,也是程序的入口函數,這里大體講述一下UCOS操作系統主函數中重要的三個函數:
OSInit操作系統初始化
OSTaskCreateExt創建任務
OSStart啟動任務

1. OSInit系統初始化
跟蹤代碼可以知道,這個函數的函數體位於os_core.c文件中。操作系統初始化顧名思義就是對UCOS系統的初始化,其中包含內核與系統資源這些的初始化,如下面代碼截圖:

從上面截圖就可以看得出來,紅色框標記的是系統內核必須初始化部分,藍色框標記是選配(由系統配置決定)。
我們上面說的“系統配置”,在這里就能體現的出來。比如:我藍色框標記的部分中,沒有使能“事件標志”也就是在配置中沒有使能使能該選項,那么程序也不會初始化事件標志組。接着的其他選項一樣的道理。
2. OSTaskCreateExt創建任務
跟蹤代碼可以知道,這個函數的函數體位於os_task.c文件中。該函數從命名及意思上可以知道,它就是創建任務的函數。我們使用“擴展版本”創建任務,主要是配置及初始化任務相關的堆棧、優先級、以及檢測參數的正確性等,如下面代碼截圖:

注意:在os_cfg中需要使能“創建任務-擴展”,也就是需要配置:#define OS_TASK_CREATE_EXT_EN 1u
創建任務有兩個函數(請看os_task.c文件):
OSTaskCreate基本版本
OSTaskCreateExt擴展版本
擴展版本是在后面升級系統新增加的一個函數,主要是新增加了5個參數(具體請見源代碼),但為了使程序兼容以前系統,這后面的系統中也是保留了基本版本的創建任務函數接口。
我在主函數里面創建的任務是“AppTaskStart”,也是“開始任務”,后面的一些關於應用所需的初始化都是在“AppTaskStart”下面創建的,子任務也是基於該函數創建的。
3. OSStart開啟任務
跟蹤代碼可以知道,這個函數的函數體位於os_core.c文件中。在操作系統初始化、任務創建完成之后,調用OSStart就可以開啟並執行任務了。
該函數也是屬於內核級的,由系統調用,主要包含幾步操作:
1.查找最高優先級任務,使其進入就緒;
2.將當前優先級指向就緒任務的最高優先級;
3.執行目標代碼,開始任務(OSRunning = OS_TRUE)。

當你初始接觸UCOS系統時,先了解它主要的意思是啟動任務就行了,至於怎樣啟動的,需后續研究系統內核這一塊,我在后面也會講述。
Ⅳ、AppTaskStart任務描述
應用程序(任務)的執行可以說就是從AppTaskStart這個函數(在上面main中創建的任務)開始一步一步執行的。
在AppTaskStart函數體里面主要做了三類事情:
1. BSP_Initializes:初始化應用底層一些代碼,基本實例就是LED的IO驅動;
2. OSTick_Init:滴答時鍾初始化,這個是屬於系統,在前面移植的過程中說過由我們自己定義,所以這里需要初始化。
3. OSTaskCreateExt:創建子任務(Demo程序創建了3個子任務)。

為什么在這里還要創建任務呢?
這種寫法是參考UCOS官方提供實例代碼的寫法(在main主函數只創建一個AppTaskStart任務,再在AppTaskStart函數創建子任務、系統資源等)。
當然,這個格式寫法不是死的,可根據自己習慣或要求來寫。
1. BSP_Initializes
跟蹤代碼可以知道,這個函數的函數體位於bsp.c文件中。這個函數是我們自己建的文件,我將它歸類為“應用程序底層代碼初始化”,自己可更加實際情況修改。由於是Demo程序(LED閃爍燈),這里主要是對LED燈IO口的初始化。
2. OSTick_Init
跟蹤代碼可以知道,這個函數的函數體位於app_cfg.c文件中。這個函數也是我們自己設計的源代碼,在前面移植的過程中要求自己初始化系統滴答,這里就需要初始化。當然也可以在UCOS提供的文件“os_cpu_c.c”里面初始化該函數。
系統滴答是系統的心臟,沒有它就等於沒有心臟。這里需要搭配滴答中斷函數(如下圖)。


3. OSTaskCreateExt子任務
提供的Demo程序創建了一個開始任務和3個子任務,任務都是實現LED閃爍的內容。更加閃爍的頻率(亮滅間隔時間)不同,可以區分出不同的任務。

開始任務、子任務1、子任務2、子任務3依次LED亮滅間隔時間加長。是由OSTimeDly函數決定的,OSTimeDly函數是系統延時的意思,它這個延時和我們平常使用的延時相似,但又不同。它在各自的任務了看似屬於自身“阻塞延時”了那么長時間,但自系統看來其實是將該任務掛起了那么長時間。
OSTimeDly延時函數屬於系統級延時,需要了解系統內核之后對它的理解就容易了。
Ⅴ、實例工程下載
筆者針對於初學者提供的例程都是去掉了許多不必要的功能,精簡了官方的代碼,對初學者一看就明白,以簡單明了的工程供大家學習。
筆者提供的實例工程都是在板子上經過多次測試並沒有問題才上傳至360雲盤,歡迎下載測試、參照學習。
我將最新UCOS2.92操作系統移植到F0、F1、F3、F4各個硬件平台上,可以根據你芯片系列選擇下載。
UCOS基於STM32F0系列實例:
https://yunpan.cn/cRCZrQ3dzeVQq 訪問密碼
UCOS基於STM32F1系列實例:
https://yunpan.cn/cRCZxGFsqHa6Q 訪問密碼
UCOS基於STM32F3系列實例:
https://yunpan.cn/cRCZqPRCWs8UW 訪問密碼
UCOS基於STM32F4系列實例:
https://yunpan.cn/cRCZPqbFqXSPR 訪問密碼
Ⅵ、說明
相關的文章也可以到我博客上查看,我也會定期更新,新內容第一時間在微信分享。
當你掌握UCOS在一種平台上的移植,其他平台移植原理類似,請不要局限某一平台。
以上總結僅供參考,若有不對之處,敬請諒解。
Ⅶ、最后
更多精彩文章我將第一時間在微信公眾號里面分享,對本文有什么疑問可微信留言。
本着免費分享的原則,方便大家手機學習知識,定期在微信平台分享技術知識。如果你覺得分享的內容對你有用,又想了解更多相關的文章,請用微信搜索“EmbeddDeveloper” 或者掃描下面二維碼、關注,將有更多精彩內容等着你。


