uCOS-II在51單片機(jī)上的移植_第1頁
uCOS-II在51單片機(jī)上的移植_第2頁
uCOS-II在51單片機(jī)上的移植_第3頁
uCOS-II在51單片機(jī)上的移植_第4頁
uCOS-II在51單片機(jī)上的移植_第5頁
已閱讀5頁,還剩40頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、1uc/os-II uc/os-II 操作系統(tǒng)的移植操作系統(tǒng)的移植q 所謂操作系統(tǒng)的移植,是指使一個實時操作系統(tǒng)能夠在某個特定的所謂操作系統(tǒng)的移植,是指使一個實時操作系統(tǒng)能夠在某個特定的微處理器平臺上運(yùn)行。微處理器平臺上運(yùn)行。q COS-IICOS-II的主要代碼都是由標(biāo)準(zhǔn)的的主要代碼都是由標(biāo)準(zhǔn)的C C語言寫成的,移植方便。語言寫成的,移植方便。但仍需但仍需要用匯編語言寫一些與處理器相關(guān)的代碼,這是因為要用匯編語言寫一些與處理器相關(guān)的代碼,這是因為C/OS-C/OS-在讀在讀寫處理器寄存器時只能通過匯編語言來實現(xiàn)。寫處理器寄存器時只能通過匯編語言來實現(xiàn)。 q 移植的主要工作是修改部分與處理器硬

2、件相關(guān)的代碼。移植的主要工作是修改部分與處理器硬件相關(guān)的代碼。2q處理器的C編譯器能產(chǎn)生可重入代碼。 q在程序中可以打開或者關(guān)閉中斷。 q處理器支持中斷,并且能產(chǎn)生定時中斷(通常在10-100Hz之間)。 q處理器支持能夠容納一定量數(shù)據(jù)的硬件堆棧(可能達(dá)幾KB) q處理器有將堆棧指針和其他CPU寄存器存儲和讀出到堆棧(或者內(nèi)存)的指令。 7.1.1 7.1.1移植移植uC/OS-IIuC/OS-II滿足的條件滿足的條件uC/OS-II是通過硬件中斷來實現(xiàn)系統(tǒng)時鐘,是通過硬件中斷來實現(xiàn)系統(tǒng)時鐘,并在時鐘中斷服務(wù)程序中來處理與時間相關(guān)并在時鐘中斷服務(wù)程序中來處理與時間相關(guān)的問題的。因此,用戶所選用

3、的處理器必須的問題的。因此,用戶所選用的處理器必須具有響應(yīng)中斷的能力。具有響應(yīng)中斷的能力。一般情況下應(yīng)該使用硬件定時器來作為一般情況下應(yīng)該使用硬件定時器來作為時鐘中斷源,這個定時器可以是與微處時鐘中斷源,這個定時器可以是與微處理器集成在一個芯片上的,也可以是分理器集成在一個芯片上的,也可以是分立的。立的。3v可重入的代碼指的是一段代碼(比如:一個函數(shù))可以被多個任務(wù)同時調(diào)用,而不必?fù)?dān)心會破壞數(shù)據(jù)。v也就是說,可重入型函數(shù)在任何時候都可以被中斷執(zhí)行,過一段時間以后又可以繼續(xù)運(yùn)行,而不會因為在函數(shù)中斷的時候被其他的任務(wù)重新調(diào)用,影響函數(shù)中的數(shù)據(jù)。v可重入的代碼的實現(xiàn)主要是編程技術(shù),所有嵌入式集成開

4、發(fā)環(huán)境都能產(chǎn)生可重入的代碼。 7.1.2 7.1.2 什么是可重入代碼什么是可重入代碼int temp;void Swap(int *x, int *y) temp = *x; *x = *y; *y = temp;例如,任務(wù)例如,任務(wù)A和任務(wù)和任務(wù)B都要調(diào)用函數(shù)都要調(diào)用函數(shù)Swap(),而該函數(shù)又使用了全局變量而該函數(shù)又使用了全局變量temp。于是當(dāng)任。于是當(dāng)任務(wù)務(wù)A調(diào)用調(diào)用Swap()函數(shù)期間,系統(tǒng)發(fā)生了任務(wù)函數(shù)期間,系統(tǒng)發(fā)生了任務(wù)切換而使任務(wù)切換而使任務(wù)B也調(diào)用了也調(diào)用了Swap(),那么任務(wù),那么任務(wù)B將要改變?nèi)肿兞繉⒁淖內(nèi)肿兞縯emp的值,使任務(wù)的值,使任務(wù)A傳遞傳遞給全局變量

5、給全局變量temp的值丟失而出現(xiàn)錯誤。的值丟失而出現(xiàn)錯誤。一般來說,一個可重入函數(shù)應(yīng)該在函數(shù)中只一般來說,一個可重入函數(shù)應(yīng)該在函數(shù)中只使用局部變量,因為函數(shù)的局部變量存儲在使用局部變量,因為函數(shù)的局部變量存儲在任務(wù)的堆棧中,所以可保證不同的任務(wù)在調(diào)任務(wù)的堆棧中,所以可保證不同的任務(wù)在調(diào)用同一個函數(shù)時不會發(fā)生沖突。用同一個函數(shù)時不會發(fā)生沖突。4 7.1.3 7.1.3 系統(tǒng)棧與任務(wù)棧的關(guān)系系統(tǒng)棧與任務(wù)棧的關(guān)系被中止運(yùn)行的任被中止運(yùn)行的任務(wù)堆棧務(wù)堆棧被運(yùn)行的任務(wù)堆棧被運(yùn)行的任務(wù)堆棧系統(tǒng)堆棧系統(tǒng)堆棧CPU SP圖圖7-1 系統(tǒng)棧與任務(wù)棧的關(guān)系系統(tǒng)棧與任務(wù)棧的關(guān)系有些處理器對于堆棧的設(shè)置有特殊的要求,

6、即要求堆棧必須設(shè)置在一個特定的有些處理器對于堆棧的設(shè)置有特殊的要求,即要求堆棧必須設(shè)置在一個特定的區(qū)域,比如片內(nèi)區(qū)域,比如片內(nèi)RAM。由于片內(nèi)的。由于片內(nèi)的RAM極其有限,不可能把應(yīng)用程序中所有極其有限,不可能把應(yīng)用程序中所有任務(wù)的堆棧都設(shè)置在片內(nèi)任務(wù)的堆棧都設(shè)置在片內(nèi)RAM中,所以就只能把應(yīng)用程序中各個任務(wù)堆棧的內(nèi)中,所以就只能把應(yīng)用程序中各個任務(wù)堆棧的內(nèi)容存放在片外容存放在片外RAM中,而只在片內(nèi)中,而只在片內(nèi)RAM中設(shè)置一個公用的堆棧。中設(shè)置一個公用的堆棧。片外的片外的RAM用來存放任務(wù)堆棧,片內(nèi)用來存放任務(wù)堆棧,片內(nèi)RAM中是系統(tǒng)的公共堆棧,當(dāng)系統(tǒng)運(yùn)行某個任務(wù)中是系統(tǒng)的公共堆棧,當(dāng)系統(tǒng)

7、運(yùn)行某個任務(wù)時,就要把該任務(wù)的堆棧映像復(fù)制到系統(tǒng)堆時,就要把該任務(wù)的堆棧映像復(fù)制到系統(tǒng)堆棧中;而在中止這個任務(wù)時,再把系統(tǒng)堆棧棧中;而在中止這個任務(wù)時,再把系統(tǒng)堆棧中的內(nèi)容復(fù)制回任務(wù)堆棧映像中。中的內(nèi)容復(fù)制回任務(wù)堆棧映像中。5 7.1.4 7.1.4 uC/OS-II文件結(jié)構(gòu)文件結(jié)構(gòu)圖圖7-2 uC/OS-II的文件結(jié)構(gòu)的文件結(jié)構(gòu)6名稱函數(shù)/宏定義所在文件語言功能OS_CRITICAL_METHOD宏定義OS_CPU.HC語言處理臨界段方式選擇OS_STK_GROWTH宏定義OS_CPU.HC語言堆棧增長方向OS_ENTER_CRITICAL()宏定義OS_CPU.HC語言進(jìn)入臨界區(qū)OS_EX

8、IT_CRITICAL()宏定義OS_CPU.HC語言退出臨界區(qū)OSStartHighRdy()函數(shù)OS_CPU_A.ASM匯編就緒態(tài)最高優(yōu)先級任務(wù)運(yùn)行OSCtxSw()函數(shù)OS_CPU_A.ASM匯編任務(wù)級任務(wù)切換OSIntCtxSw()函數(shù)OS_CPU_A.ASM匯編中斷級任務(wù)切換OSTickISR()函數(shù)OS_CPU_A.ASM匯編時鐘節(jié)拍OSTaskStkInit()函數(shù)OS_CPU_C.CC語言任務(wù)堆棧初始化表表7-1 需要修改的關(guān)鍵函數(shù)和宏定義需要修改的關(guān)鍵函數(shù)和宏定義 7.1.5 7.1.5 需要修改的關(guān)鍵函數(shù)和宏定義需要修改的關(guān)鍵函數(shù)和宏定義7 7.1.6 7.1.6 INCL

9、UDES.Hv 使得項目中的每個使得項目中的每個.c文件不用分別考慮它實際上需要那些頭文件。文件不用分別考慮它實際上需要那些頭文件。v 它會包含一些不相關(guān)的頭文件它會包含一些不相關(guān)的頭文件v INCLUDES.H 是一個頭文件,它在所有的是一個頭文件,它在所有的.c文件的第一行被包含。文件的第一行被包含。v #include “includes.h”/ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

10、 * * * * * * * * * * * * * * * * uC/OS-II uC/OS-II 實時內(nèi)核實時內(nèi)核* * (c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL(c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL* * 版權(quán)所有版權(quán)所有* * MCU-51 MCU-51 專用代碼專用代碼 KEIL C51KEIL C51大模式編譯大模式編譯* * * 文件名文件名 : INCLUDES.H: INCLUDES.H* * 作者作者 : Jean J. La

11、brosse: Jean J. Labrosse* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /#include os_cpu.h#include os_cfg.h#include ucos_ii.h#include #include 8 7.1.7 7.1.7 OS_CPU.H/ /* * * * * * * * * * * * *

12、 * * * * * * * 數(shù)據(jù)類型數(shù)據(jù)類型 ( (與編譯器相關(guān)的內(nèi)容與編譯器相關(guān)的內(nèi)容) ) * * * * * * * * * * * * * * * * * * * * */ /typedef unsigned charBOOLEAN;typedef unsigned char INT8U; typedef signed char INT8S; typedef unsigned int INT16U; typedef signed intINT16S; typedef unsigned long INT32U; typedef signed long INT32S; typedef f

13、loat FP32; typedef double FP64; typedef unsigned int OS_STK; 2OS_CPU.H中包括與處理器相關(guān)的常量、宏以及類型。中包括與處理器相關(guān)的常量、宏以及類型。9 7.1.7 7.1.7 OS_CPU.H( (續(xù)續(xù)) )/ / * * * * * * * * * * * * * * * * * * * * 與處理器相關(guān)的代碼與處理器相關(guān)的代碼 * * * * * * * * * * * * * * * * * * * * */ /#define OS_CRITICAL_METHOD ?#if OS_CRITICAL_METHOD = =

14、1 #define OS_ENTER_CRITICAL() ?#define OS_EXIT_CRITICAL() ?#endif #if OS_CRITICAL_METHOD = = 2 #define OS_ENTER_CRITICAL() ?#define OS_EXIT_CRITICAL() ?#endif#if OS_CRITICAL_METHOD = = 3 #define OS_ENTER_CRITICAL() ?#define OS_EXIT_CRITICAL() ?#endif#define OS_STK_GROWTH1#define OS_TASK_SW()?10 7.1.

15、8 7.1.8 OS_ENTER_CRITICAL()()和和OS_EXIT_CRITICAL()()p 臨界代碼的概念。臨界代碼的概念。p uC/OS-IIuC/OS-II定義的兩個宏。定義的兩個宏。 OS_ENTER_CRITICAL(); OS_ENTER_CRITICAL(); / /* * C/OS-II C/OS-II 臨界代碼段臨界代碼段 * */ / OS_EXIT_CRITICAL(); OS_EXIT_CRITICAL(); p 三種實現(xiàn)方法。三種實現(xiàn)方法。 方法方法1:1: 在在OS_ENTER_CRITICAL()OS_ENTER_CRITICAL()中調(diào)用處理器指令來

16、禁止中斷,以及在中調(diào)用處理器指令來禁止中斷,以及在 OS_EXIT_CRITICAL()OS_EXIT_CRITICAL()中調(diào)用允許中斷指令。中調(diào)用允許中斷指令。 方法方法2:2: 是先將中斷禁止?fàn)顟B(tài)保存到堆棧中,然后禁止中斷。是先將中斷禁止?fàn)顟B(tài)保存到堆棧中,然后禁止中斷。 方法方法3:3: 有些編譯器提供擴(kuò)展功能,可以得到當(dāng)前處理器狀態(tài)字的值。有些編譯器提供擴(kuò)展功能,可以得到當(dāng)前處理器狀態(tài)字的值。#define OS_ENTER_CRITICAL() EA=0#define OS_EXIT_CRITICAL() EA=1 #define OS_ENTER_CRITICAL() asm(“P

17、USH PSW”); asm(“DI”);#define OS_EXIT_CRITICAL() asm(“POP PSW”);void some_ucos_ii_service() OS_CPU_SR cpu_sr; cpu_sr = get_processor_psw(); disable_interrupts(); /* C/OS-II 臨界代碼段臨界代碼段 */ set_processor_psw(cpu_sr);11 7.1.9 7.1.9 OS_STK_GROWTH4 絕大多數(shù)的微處理器和微控制器的堆棧是從上往下長的。但是某些處理器絕大多數(shù)的微處理器和微控制器的堆棧是從上往下長的。但

18、是某些處理器是用另外一種方式工作的。是用另外一種方式工作的。C/OS-C/OS-被設(shè)計成兩種情況都可以處理,只要被設(shè)計成兩種情況都可以處理,只要在結(jié)構(gòu)常量在結(jié)構(gòu)常量OS_STK_GROWTHOS_STK_GROWTH(在(在OS_CPU.H中)中) 中指定堆棧的生長方式中指定堆棧的生長方式( (如下所示如下所示) )就可以了。就可以了。置置OS_STK_GROWTH為為0表示堆棧從下往上長。表示堆棧從下往上長。置置OS_STK_GROWTH為為1表示堆棧從上往下長。表示堆棧從上往下長。12 7.1.10 OS_TASK_SW() 7.1.10 OS_TASK_SW()p OS_TASK_SW(

19、) OS_TASK_SW()是一個宏,它是在是一個宏,它是在C/OS-C/OS-從低優(yōu)先級任務(wù)切換到最高優(yōu)先級任從低優(yōu)先級任務(wù)切換到最高優(yōu)先級任務(wù)時被調(diào)用的。務(wù)時被調(diào)用的。p在在C/OS-C/OS-中,處于就緒狀態(tài)的任務(wù)的堆棧結(jié)構(gòu)看起來就像剛發(fā)生過中斷并將所中,處于就緒狀態(tài)的任務(wù)的堆棧結(jié)構(gòu)看起來就像剛發(fā)生過中斷并將所有的寄存器保存到堆棧中的情形一樣。換句話說,有的寄存器保存到堆棧中的情形一樣。換句話說,C/OS-C/OS-要運(yùn)行處于就緒狀態(tài)的要運(yùn)行處于就緒狀態(tài)的任務(wù)必須要做的事就是將所有處理器寄存器從任務(wù)堆棧中恢復(fù)出來,并且執(zhí)行中斷的任務(wù)必須要做的事就是將所有處理器寄存器從任務(wù)堆棧中恢復(fù)出來,

20、并且執(zhí)行中斷的返回。為了切換任務(wù)可以通過執(zhí)行返回。為了切換任務(wù)可以通過執(zhí)行OS_TASK_SW()OS_TASK_SW()來產(chǎn)生中斷。大部分的處理器會提來產(chǎn)生中斷。大部分的處理器會提供軟中斷或是陷阱(供軟中斷或是陷阱(TRAPTRAP)指令來完成這個功能。)指令來完成這個功能。p 例如,在例如,在IntelIntel或者或者80 x8680 x86處理器上可以使用處理器上可以使用INTINT指令。但是中斷處理向量需要指向指令。但是中斷處理向量需要指向OSCtxSw()OSCtxSw()。p 一些處理器并不提供軟中斷機(jī)制。在這種情況下,用戶需要盡自己的所能將堆棧結(jié)一些處理器并不提供軟中斷機(jī)制。在

21、這種情況下,用戶需要盡自己的所能將堆棧結(jié)構(gòu)設(shè)置成與中斷堆棧結(jié)構(gòu)一樣,再用函數(shù)調(diào)用方式來實現(xiàn)任務(wù)切換,也就是說通過函構(gòu)設(shè)置成與中斷堆棧結(jié)構(gòu)一樣,再用函數(shù)調(diào)用方式來實現(xiàn)任務(wù)切換,也就是說通過函數(shù)來模仿軟中斷指令。如數(shù)來模仿軟中斷指令。如#define OS_TASK_SW() OSCtxSw()#define OS_TASK_SW() OSCtxSw()當(dāng)多任務(wù)內(nèi)核決定運(yùn)行另外的任務(wù)時,它保存正在當(dāng)多任務(wù)內(nèi)核決定運(yùn)行另外的任務(wù)時,它保存正在運(yùn)行任務(wù)的當(dāng)前狀態(tài),即運(yùn)行任務(wù)的當(dāng)前狀態(tài),即CPU寄存器中的全部內(nèi)容。寄存器中的全部內(nèi)容。這些內(nèi)容保存在任務(wù)的當(dāng)前狀態(tài)保存區(qū),也就是任這些內(nèi)容保存在任務(wù)的當(dāng)前狀

22、態(tài)保存區(qū),也就是任務(wù)自己的堆棧區(qū)中。入棧工作完成后,就是把下一務(wù)自己的堆棧區(qū)中。入棧工作完成后,就是把下一個將要運(yùn)行任務(wù)的當(dāng)前狀態(tài)從該任務(wù)的堆棧中重新個將要運(yùn)行任務(wù)的當(dāng)前狀態(tài)從該任務(wù)的堆棧中重新裝入裝入CPU寄存器,并開始下一個任務(wù)的運(yùn)行,這個寄存器,并開始下一個任務(wù)的運(yùn)行,這個過程叫任務(wù)切換。過程叫任務(wù)切換。13 7.1.11 OS_CPU_C.C 7.1.11 OS_CPU_C.COSTaskStkInit()OSTaskStkInit()OSTaskCreateHook()OSTaskDelHook()OSTaskSwHook()OSTaskIdleHook()OSTaskStatHoo

23、k()OSTimeTickHook()OSInitHookBegin()OSInitHookEnd() OSTCBInitHook() OS_CPU_C.C文件包含文件包含10個個C函數(shù):函數(shù):唯一必要的函數(shù)是唯一必要的函數(shù)是OSTaskStkInit(),其它九個屬于鉤子函數(shù),必須得聲明但沒,其它九個屬于鉤子函數(shù),必須得聲明但沒必要包含代碼。必要包含代碼。14 7.1.11.1 OSTaskStkInit() 7.1.11.1 OSTaskStkInit()OSTaskCreate()OSTaskCreate()和和OSTaskCreateExt()OSTaskCreateExt()通過調(diào)用

24、通過調(diào)用OSTaskStkInt()OSTaskStkInt()來初始化任務(wù)的堆來初始化任務(wù)的堆棧結(jié)構(gòu),因此,堆??雌饋砭拖駝偘l(fā)生過中斷并將所有的寄存器保存到堆棧中的情棧結(jié)構(gòu),因此,堆??雌饋砭拖駝偘l(fā)生過中斷并將所有的寄存器保存到堆棧中的情形一樣。形一樣。編寫編寫OSTaskStkInit()OSTaskStkInit()函數(shù)的第一步就是堆棧設(shè)計。需要考慮以下因素函數(shù)的第一步就是堆棧設(shè)計。需要考慮以下因素: : CPU自動入棧的寄存器及壓棧順序。自動入棧的寄存器及壓棧順序。 需要額外保存哪些寄存器。需要額外保存哪些寄存器。 所采用的編譯器對形式參數(shù)的傳遞方法。所采用的編譯器對形式參數(shù)的傳遞方法

25、。 堆棧的增長方向。堆棧的增長方向。 堆棧指針是指向下一個可用空間還是指向上次入棧數(shù)據(jù)。堆棧指針是指向下一個可用空間還是指向上次入棧數(shù)據(jù)。 所采用的所采用的CPU是否存在系統(tǒng)堆棧。是否存在系統(tǒng)堆棧。 堆棧深度。堆棧深度。任務(wù)按函數(shù)形式編寫,但永遠(yuǎn)不被調(diào)用,而是通過模仿中斷的方式來運(yùn)行其中的代碼。任務(wù)按函數(shù)形式編寫,但永遠(yuǎn)不被調(diào)用,而是通過模仿中斷的方式來運(yùn)行其中的代碼。既然任務(wù)通過既然任務(wù)通過模仿中斷的方式來進(jìn)行,而且擁有自己單獨(dú)的任務(wù)棧,那么需要做的就是執(zhí)行中斷返回指令,讓任務(wù)模仿中斷的方式來進(jìn)行,而且擁有自己單獨(dú)的任務(wù)棧,那么需要做的就是執(zhí)行中斷返回指令,讓任務(wù)中的內(nèi)容出棧,讓系統(tǒng)覺得該任

26、務(wù)(或者說是所謂的中的內(nèi)容出棧,讓系統(tǒng)覺得該任務(wù)(或者說是所謂的“函數(shù)函數(shù)”)剛剛被中斷過,現(xiàn)在需要繼續(xù)執(zhí)行。)剛剛被中斷過,現(xiàn)在需要繼續(xù)執(zhí)行。但在系統(tǒng)剛開始運(yùn)行的時候,任務(wù)是沒有被系統(tǒng)中斷過的,也沒有被切換過,任務(wù)棧里沒有內(nèi)容。所但在系統(tǒng)剛開始運(yùn)行的時候,任務(wù)是沒有被系統(tǒng)中斷過的,也沒有被切換過,任務(wù)棧里沒有內(nèi)容。所以需要通過以需要通過OSTaskStkInit()來初始化任務(wù)棧,模擬一次壓棧動作,使得系統(tǒng)認(rèn)為任務(wù)剛剛被中斷過。來初始化任務(wù)棧,模擬一次壓棧動作,使得系統(tǒng)認(rèn)為任務(wù)剛剛被中斷過。15 7.1.11.2 HOOK 7.1.11.2 HOOK類函數(shù)類函數(shù)OSTaskCreateHoo

27、k()當(dāng)用當(dāng)用OSTaskCreate()或或OSTaskCreateExt()建立任務(wù)的時候就會調(diào)用建立任務(wù)的時候就會調(diào)用OSTaskCreateHook()。OSTaskDelHook() 當(dāng)任務(wù)被刪除的時候就會調(diào)用當(dāng)任務(wù)被刪除的時候就會調(diào)用OSTaskDelHook()。 OSTaskSwHook() 當(dāng)發(fā)生任務(wù)切換的時候調(diào)用當(dāng)發(fā)生任務(wù)切換的時候調(diào)用OSTaskSwHook()。 OSTaskStatHook() OSTaskStatHook()每秒鐘都會被每秒鐘都會被OSTaskStat()調(diào)用一次。用戶可以用調(diào)用一次。用戶可以用OSTaskStatHook()來擴(kuò)展統(tǒng)計功能。來擴(kuò)展統(tǒng)

28、計功能。 OSTimeTickHook() OSTaskTimeHook()在每個時鐘節(jié)拍都會被在每個時鐘節(jié)拍都會被OSTaskTick()調(diào)用。調(diào)用。HOOK類函數(shù)主要的作用是類函數(shù)主要的作用是擴(kuò)展擴(kuò)展uC/OS-II的功能,可以不的功能,可以不包含代碼,但必須聲明。一般包含代碼,但必須聲明。一般在移植中不予考慮。在移植中不予考慮。16 7.1.12 OS_CPU_A.ASM 7.1.12 OS_CPU_A.ASM4 C/OS-C/OS-的移植要求用戶編寫四個簡單的匯編語言函數(shù)的移植要求用戶編寫四個簡單的匯編語言函數(shù): :OSStartHighRdy()OSStartHighRdy()OSC

29、txSw()OSCtxSw()OSIntCtxSw()OSIntCtxSw()OSTickISR()OSTickISR()如果用戶的編譯器支持插入?yún)R編語言代碼的話,用戶就可以將所有與處理器相關(guān)的如果用戶的編譯器支持插入?yún)R編語言代碼的話,用戶就可以將所有與處理器相關(guān)的代碼放到代碼放到OS_CPU_C.COS_CPU_C.C文件中,而不必再擁有一些分散的匯編語言文件。文件中,而不必再擁有一些分散的匯編語言文件。這這4個匯編函數(shù)幾乎占據(jù)了移植個匯編函數(shù)幾乎占據(jù)了移植70%的工作量,也是移植最關(guān)鍵的部分。的工作量,也是移植最關(guān)鍵的部分。17 7.1.12.1 OSStartHighRdy() 7.1.

30、12.1 OSStartHighRdy()4 OSStartHighRdy()在在OSStart()函數(shù)中調(diào)用,用來使就緒態(tài)任務(wù)中優(yōu)先級最高的函數(shù)中調(diào)用,用來使就緒態(tài)任務(wù)中優(yōu)先級最高的任務(wù)開始運(yùn)行。在用戶調(diào)用任務(wù)開始運(yùn)行。在用戶調(diào)用OSStart()之前,用戶必須至少已經(jīng)通過之前,用戶必須至少已經(jīng)通過OSTaskCreate()或或OSTaskCreateExt()建立自己的一個任務(wù)。因為建立自己的一個任務(wù)。因為OSStart()永不返回,在永不返回,在OSStartHighRdy()執(zhí)行完畢后,執(zhí)行完畢后,uC/OS-II正式開始接管系統(tǒng),不會再有機(jī)會創(chuàng)建正式開始接管系統(tǒng),不會再有機(jī)會創(chuàng)建任

31、務(wù)。任務(wù)。4 OSStartHighRdy()與與OSStart()一樣,永遠(yuǎn)只運(yùn)行一次。一樣,永遠(yuǎn)只運(yùn)行一次。void OSStart(void)INT8U x,y; if(OSRunning=FALSE)OSStartHighRdy(); 18 7.1.12.2 OSCtxSw() 7.1.12.2 OSCtxSw()4 在在uC/OS-II與處理器無關(guān)的代碼中,為了屏蔽不同的與處理器無關(guān)的代碼中,為了屏蔽不同的CPU帶來的不同的處理方法,帶來的不同的處理方法,使用使用OS_TASK_SW()宏實現(xiàn)任務(wù)切換。在()宏實現(xiàn)任務(wù)切換。在uC/OS-II中,任務(wù)級的任務(wù)調(diào)度由中,任務(wù)級的任務(wù)調(diào)度

32、由OS_Sched()函數(shù)完成,該函數(shù)為了實現(xiàn)任務(wù)級的任務(wù)切換,確定了等待調(diào)度的最高函數(shù)完成,該函數(shù)為了實現(xiàn)任務(wù)級的任務(wù)切換,確定了等待調(diào)度的最高優(yōu)先級任務(wù)后,調(diào)用優(yōu)先級任務(wù)后,調(diào)用OS_TASK_SW()宏實現(xiàn)任務(wù)的切換。()宏實現(xiàn)任務(wù)的切換。void OSCtxSw(void) 保存處理器寄存器; 將當(dāng)前任務(wù)的堆棧指針保存到當(dāng)前任務(wù)的OS_TCB中: OSTCBCur-OSTCBStkPtr = Stack pointer; 調(diào)用用戶定義的OSTaskSwHook(); OSTCBCur = OSTCBHighRdy; OSPrioCur = OSPrioHighRdy; 得到需要恢復(fù)的任

33、務(wù)的堆棧指針: Stack pointer = OSTCBHighRdy-OSTCBStkPtr; 將所有處理器寄存器從新任務(wù)的堆棧中恢復(fù)出來; 執(zhí)行中斷返回指令;19 7.1.12.3 OSIntCtxSw()7.1.12.3 OSIntCtxSw()1 OSIntExit() OSIntExit()通過調(diào)用通過調(diào)用OSIntCtxSw()OSIntCtxSw()來從來從ISRISR中執(zhí)行切換功能。因為中執(zhí)行切換功能。因為OSIntCtxSw()OSIntCtxSw()是在是在ISRISR中被中被調(diào)用的,所以可以斷定所有的處理器寄存器都被正確地保存到了被中斷的任務(wù)的堆棧之中。實調(diào)用的,所以可

34、以斷定所有的處理器寄存器都被正確地保存到了被中斷的任務(wù)的堆棧之中。實際上除了我們需要的東西外,堆棧結(jié)構(gòu)中還有其它的一些東西。際上除了我們需要的東西外,堆棧結(jié)構(gòu)中還有其它的一些東西。OSIntCtxSw()OSIntCtxSw()必須要清理堆棧,必須要清理堆棧,這樣被中斷的任務(wù)的堆棧結(jié)構(gòu)內(nèi)容才能滿足我們的需要。這樣被中斷的任務(wù)的堆棧結(jié)構(gòu)內(nèi)容才能滿足我們的需要。void OSIntCtxSw(void) 調(diào)用用戶定義的OSTaskSwHook(); OSTCBCur = OSTCBHighRdy; OSPrioCur = OSPrioHighRdy; 得到需要恢復(fù)的任務(wù)的堆棧指針: 堆棧指針 =

35、OSTCBHighRdy-OSTCBStkPtr; 將所有處理器寄存器從新任務(wù)的堆棧中恢復(fù)出來; 執(zhí)行中斷返回指令;OSIntCtxSw()函數(shù)的絕大多數(shù)代碼與函數(shù)的絕大多數(shù)代碼與OSCtxSw()是一樣的。在中斷服務(wù)子程序中已經(jīng)保存了是一樣的。在中斷服務(wù)子程序中已經(jīng)保存了CPU的寄的寄存器,因此不需要在存器,因此不需要在OSIntCtxSw()函數(shù)中保存函數(shù)中保存CPU寄存器,其他的步驟幾乎都是一樣的。很多人在編寄存器,其他的步驟幾乎都是一樣的。很多人在編寫這個函數(shù)的時候,基本上都跳轉(zhuǎn)到寫這個函數(shù)的時候,基本上都跳轉(zhuǎn)到OSCtxSw()中執(zhí)行相同的代碼,可以減少一部分代碼量。中執(zhí)行相同的代碼

36、,可以減少一部分代碼量。20 7.1.12.4 OSTickISR() 7.1.12.4 OSTickISR()1 C/OS-C/OS-要求用戶提供一個時鐘資源來實現(xiàn)時間的延時和期滿功能。時鐘節(jié)拍應(yīng)該每秒鐘要求用戶提供一個時鐘資源來實現(xiàn)時間的延時和期滿功能。時鐘節(jié)拍應(yīng)該每秒鐘發(fā)生發(fā)生1010100100次。為了完成該任務(wù),可以使用硬件時鐘,也可以從交流電中獲得次。為了完成該任務(wù),可以使用硬件時鐘,也可以從交流電中獲得50/60Hz50/60Hz的時鐘的時鐘頻率。頻率。1 用戶必須在開始多任務(wù)調(diào)度后用戶必須在開始多任務(wù)調(diào)度后( (即調(diào)用即調(diào)用OSStart()OSStart()后后) )允許時鐘

37、節(jié)拍中斷。換句話說,就是用戶允許時鐘節(jié)拍中斷。換句話說,就是用戶應(yīng)該在應(yīng)該在OSStart()OSStart()運(yùn)行后,運(yùn)行后,C/OS-C/OS-啟動運(yùn)行的第一個任務(wù)中初始化節(jié)拍中斷。通常所犯的錯啟動運(yùn)行的第一個任務(wù)中初始化節(jié)拍中斷。通常所犯的錯誤是在調(diào)用誤是在調(diào)用OSInit()OSInit()和和OSStart()OSStart()之間允許時鐘節(jié)拍中斷之間允許時鐘節(jié)拍中斷。void main(void) OSInit(); /初始化 C/OS-II /* 應(yīng)用程序初始化代碼 . */ /* . 調(diào)用OSTaskCreate()建立至少一個任務(wù) */ 允許時鐘節(jié)拍中斷; / 千萬不要在這里

38、允許千萬不要在這里允許! OSStart(); / 開始多任務(wù)調(diào)度 有可能在有可能在 C/OS-開始執(zhí)行第一開始執(zhí)行第一個任務(wù)前時鐘節(jié)拍中斷就發(fā)生了。個任務(wù)前時鐘節(jié)拍中斷就發(fā)生了。在這種情況下,在這種情況下, C/OS-的運(yùn)行的運(yùn)行狀態(tài)不確定,用戶的應(yīng)用程序也可狀態(tài)不確定,用戶的應(yīng)用程序也可能會崩潰。能會崩潰。21 7.1.13 7.1.13 測試移植代碼測試移植代碼O 當(dāng)完成當(dāng)完成uC/OS-II的移植后,系統(tǒng)是否能夠正常工作,需要檢驗,只有通過了測的移植后,系統(tǒng)是否能夠正常工作,需要檢驗,只有通過了測試,試,uC/OS-II的移植才算完成。的移植才算完成。#include “include

39、s.h”void main(void)OSInit();OSStart();q 首先,不添加任務(wù)應(yīng)用代碼,測試內(nèi)核自身的運(yùn)行狀況。這樣可以避免問題復(fù)首先,不添加任務(wù)應(yīng)用代碼,測試內(nèi)核自身的運(yùn)行狀況。這樣可以避免問題復(fù)雜化,同時可以排除應(yīng)用代碼的問題,使反映出的問題清晰化。雜化,同時可以排除應(yīng)用代碼的問題,使反映出的問題清晰化。 q 在在OS_CFG.H中允許所有的中允許所有的uC/OS-II功能,然后在主程序中不添加任何復(fù)雜代功能,然后在主程序中不添加任何復(fù)雜代碼,列如:碼,列如:22 7.1.13.1 7.1.13.1 測試測試OSTaskStkInit()OSTaskStkInit()與與

40、OSStartHighRdy()OSStartHighRdy()v 采用源碼調(diào)試器采用源碼調(diào)試器單步執(zhí)行單步執(zhí)行main()main()程序程序-跳過跳過OS_Init()OS_Init()函數(shù)函數(shù)-單步進(jìn)入單步進(jìn)入OSStart()OSStart()函數(shù)函數(shù)-一直運(yùn)行到一直運(yùn)行到OSStartHighRdy()OSStartHighRdy()應(yīng)切換到匯編模式應(yīng)切換到匯編模式- OSStartHighRdy()- OSStartHighRdy()會開始的一個任務(wù),因會開始的一個任務(wù),因為沒有任何應(yīng)用任務(wù),只有為沒有任何應(yīng)用任務(wù),只有OS_TaskIdle()OS_TaskIdle()可以運(yùn)行可

41、以運(yùn)行-單步執(zhí)行觀察堆棧內(nèi)容及單步執(zhí)行觀察堆棧內(nèi)容及CPUCPU寄存器內(nèi)容變化寄存器內(nèi)容變化- OSStartHighRdy()- OSStartHighRdy()最后一條語句會中斷返回,指向最后一條語句會中斷返回,指向OS_TaskIdle()OS_TaskIdle()第一條語句。如果能夠在第一條語句。如果能夠在OS_TaskIdle()OS_TaskIdle()中循環(huán),則證明中循環(huán),則證明OSTaskStkInit()OSTaskStkInit()與與OSStartHighRdy()OSStartHighRdy()是成功的。是成功的。 運(yùn)行運(yùn)行/不運(yùn)行測試法不運(yùn)行測試法 如 果 目 標(biāo) 系

42、 統(tǒng) 存 在如 果 目 標(biāo) 系 統(tǒng) 存 在 L E DL E D , 可 以 先 關(guān) 閉, 可 以 先 關(guān) 閉 L E DL E D 。 如 果。 如 果 O S T a s k S t k I n i t ( )O S T a s k S t k I n i t ( ) 與與OSStartHighRdy()OSStartHighRdy()正常,再由正常,再由OS_TaskIdle()OS_TaskIdle()點(diǎn)亮點(diǎn)亮LEDLED。 q 首先修改首先修改OS_CFG.H文件,設(shè)置文件,設(shè)置OS_TASK_STAT_EN為為0,禁止統(tǒng)計任務(wù),仍然,禁止統(tǒng)計任務(wù),仍然不添加用戶應(yīng)用任務(wù),此時運(yùn)行的

43、唯一任務(wù)就是空閑任務(wù)。不添加用戶應(yīng)用任務(wù),此時運(yùn)行的唯一任務(wù)就是空閑任務(wù)。23 7.1.13.2 7.1.13.2 測試測試OSCtxSw()OSCtxSw()# include “includes.h”O(jiān)S_STK Task1Stk100;void main(void)OSInit();關(guān)關(guān)LED;OSTaskCreate(Task1,(void*)0,&Task1Stk99,0);OSStart();void Task1(void *pdata)pdata=pdata;for(;) OSTimeDly(1);可采用源碼調(diào)試器及運(yùn)行可采用源碼調(diào)試器及運(yùn)行/不運(yùn)行測試法。不運(yùn)行測試法。

44、q 如果前兩節(jié)測試通過,證明堆棧結(jié)構(gòu)正確,可以添加一個簡單的應(yīng)用任務(wù),從該如果前兩節(jié)測試通過,證明堆棧結(jié)構(gòu)正確,可以添加一個簡單的應(yīng)用任務(wù),從該任務(wù)切換到空閑任務(wù)。任務(wù)切換到空閑任務(wù)。24 7.1.13.3 7.1.13.3 測試測試OSIntCtxSw()OSIntCtxSw()和和OSTickISR()OSTickISR()測試程序如下測試程序如下:#include “includes.h”O(jiān)S_STK Task1Stk100;void main(void)OSInit();關(guān)關(guān)LED;OSTaskCreate(Task1,(void*)0,&Task1Stk99,0);OSSta

45、rt();void Task1(void *pdata)pdata=pdata;初始化時鐘節(jié)拍總線初始化時鐘節(jié)拍總線;使能中斷使能中斷;LED_State = FALSE;點(diǎn)亮點(diǎn)亮LED;for(;)OSTimeDly(1);if(LED_State = FALSE) LED_State = TURE; 點(diǎn)亮點(diǎn)亮LED;else LED_State = FALSE; 關(guān)關(guān)LED;25 7.2 uC/OS-II 7.2 uC/OS-II在在MCS-51MCS-51上的移植上的移植要使要使uC/OS-IIuC/OS-II正常運(yùn)行,必須滿足以下要求:正常運(yùn)行,必須滿足以下要求:處理器的處理器的C C

46、編譯器能產(chǎn)生可重入代碼。編譯器能產(chǎn)生可重入代碼。 在程序中可以打開或者關(guān)閉中斷。在程序中可以打開或者關(guān)閉中斷。 處理器支持中斷,并且能產(chǎn)生定時中斷(通常在處理器支持中斷,并且能產(chǎn)生定時中斷(通常在10-100Hz10-100Hz之間)。之間)。 處理器支持能夠容納一定量數(shù)據(jù)的硬件堆棧(可能達(dá)幾處理器支持能夠容納一定量數(shù)據(jù)的硬件堆棧(可能達(dá)幾KBKB) 處理器有將堆棧指針和其他處理器有將堆棧指針和其他CPUCPU寄存器存儲和讀出到堆棧(或者內(nèi)存)的寄存器存儲和讀出到堆棧(或者內(nèi)存)的指令。指令。 MCS-51MCS-51與與KEIL Cx51KEIL Cx51編譯器可以滿足以上條件。編譯器可以滿

47、足以上條件。移植與移植與4個文件相關(guān):個文件相關(guān):匯編文件匯編文件 OS_CPU_A.ASMOS_CPU_A.ASM處理器相關(guān)處理器相關(guān)C文件文件 OS_CPU.HOS_CPU.H、OS_CPU_C.COS_CPU_C.C配置文件配置文件 OS_CFG.HOS_CFG.H26 7.2.1 7.2.1 建立工程建立工程 首先建立一個工程,這里輸入的文件名也是工程名。首先建立一個工程,這里輸入的文件名也是工程名。KeilKeil會在指定的會在指定的目錄建立一個目錄建立一個.uv2.uv2文件,用來保存相關(guān)的工程信息。文件,用來保存相關(guān)的工程信息。圖圖7-3 建立工程建立工程-127 7.2.1 7

48、.2.1 建立工程建立工程( (續(xù)續(xù)) ) Keil Keil會要求選擇所使用的會要求選擇所使用的CPUCPU,這里選擇,這里選擇WINBONDWINBOND公司的公司的W78E58BW78E58B。圖圖7-4 建立工程建立工程-228 7.2.1 7.2.1 建立工程建立工程( (續(xù)續(xù)) ) Keil Keil會詢問是否添加標(biāo)準(zhǔn)的會詢問是否添加標(biāo)準(zhǔn)的80518051啟動代碼,一般來說都選擇添加,啟動代碼,一般來說都選擇添加,然后在此基礎(chǔ)上修改。然后在此基礎(chǔ)上修改。在完成以上在完成以上3 3個步驟后,一個工程的框架就基本建立了,接下來向工程個步驟后,一個工程的框架就基本建立了,接下來向工程添加

49、必要的代碼。添加必要的代碼。圖圖7-5 建立工程建立工程-329 7.2.1 7.2.1 建立工程建立工程( (續(xù)續(xù)) ) uC/OS-IIuC/OS-II分為與處理器相關(guān)代碼和與處理器無關(guān)代碼。首先將與處理器無關(guān)代碼復(fù)制到工分為與處理器相關(guān)代碼和與處理器無關(guān)代碼。首先將與處理器無關(guān)代碼復(fù)制到工程文件夾。將程文件夾。將UCOS_II.CUCOS_II.C添加至源碼組,接下來將添加至源碼組,接下來將OS_CFG.HOS_CFG.H與與INCLUDES.HINCLUDES.H復(fù)制到工程文復(fù)制到工程文件夾。再將與移植相關(guān)的文件件夾。再將與移植相關(guān)的文件OS_CPU.HOS_CPU.H、OS_CPU_

50、A.ASMOS_CPU_A.ASM與與OS_CPU_C.COS_CPU_C.C復(fù)制到主文件復(fù)制到主文件夾,并將夾,并將OS_CPU_A.ASMOS_CPU_A.ASM、OS_CPU_C.COS_CPU_C.C加入源碼組。最后再添加一個存放加入源碼組。最后再添加一個存放main()main()的的CC文文件。件。圖圖7-6 建立工程建立工程-430 7.2.1 7.2.1 建立工程建立工程( (續(xù)續(xù)) ) 在完成以上步驟后,要選擇內(nèi)存模式為大模式在完成以上步驟后,要選擇內(nèi)存模式為大模式(Large)(Large),否則在編譯時會出現(xiàn),否則在編譯時會出現(xiàn)段過大的錯誤。段過大的錯誤。圖圖7-7 建立

51、工程建立工程-531 7.2.1 7.2.1 建立工程建立工程( (續(xù)續(xù)) ) 如果在程序中使用了嵌入?yún)R編,就需要在源碼組打開相應(yīng)的選項激活。如果在程序中使用了嵌入?yún)R編,就需要在源碼組打開相應(yīng)的選項激活。至此,工程的建立基本完成。下面需要進(jìn)行具體代碼的編寫。至此,工程的建立基本完成。下面需要進(jìn)行具體代碼的編寫。圖圖7-8 建立工程建立工程-632 7.2.2 OS_CPU.H 7.2.2 OS_CPU.HOS_CPU.HOS_CPU.H中包括與處理器相關(guān)的常量、宏以及類型。這個文件大體分為兩部分中包括與處理器相關(guān)的常量、宏以及類型。這個文件大體分為兩部分- -與編譯器相關(guān)的數(shù)據(jù)類型和與處理器相

52、關(guān)的代碼。與編譯器相關(guān)的數(shù)據(jù)類型和與處理器相關(guān)的代碼。首先,查詢首先,查詢Keil Cx51Keil Cx51編譯器手冊,確定與編譯器相關(guān)的數(shù)據(jù)類型,選擇需要的數(shù)編譯器手冊,確定與編譯器相關(guān)的數(shù)據(jù)類型,選擇需要的數(shù)據(jù)類型,并用據(jù)類型,并用typedeftypedef關(guān)鍵字定義成關(guān)鍵字定義成uC/OS-IIuC/OS-II所需要的數(shù)據(jù)類型。在所需要的數(shù)據(jù)類型。在UC/OS-IIUC/OS-II與與處理器無關(guān)的代碼中,至少需要使用以下處理器無關(guān)的代碼中,至少需要使用以下8 8種數(shù)據(jù)類型:種數(shù)據(jù)類型: 無符號無符號8 8位數(shù)(位數(shù)(INT8UINT8U)無符號無符號3232位數(shù)(位數(shù)(INT32UI

53、NT32U) 有符號有符號8 8位數(shù)(位數(shù)(INT8SINT8S)有符號有符號3232位數(shù)(位數(shù)(INT32SINT32S) 無符號無符號1616位數(shù)(位數(shù)(INT16UINT16U)布爾型(布爾型(BooleanBoolean) 有符號有符號1616位數(shù)(位數(shù)(INT16SINT16S)任務(wù)堆棧(任務(wù)堆棧(OS_STKOS_STK)33 7.2.2 OS_CPU.H( 7.2.2 OS_CPU.H(續(xù)續(xù)) )/*與編譯器相關(guān)數(shù)據(jù)類型與編譯器相關(guān)數(shù)據(jù)類型 */typedef unsigned char BOOLEAN; typedef unsigned char INT8U; /無符號無符號8

54、位數(shù)位數(shù)typedef signed char INT8S; /有符號有符號8位數(shù)位數(shù)typedef unsigned int INT16U; /無符號無符號16位數(shù)位數(shù)typedef signed int INT16S; /有符號有符號16位數(shù)位數(shù)typedef unsigned long INT32U; /無符號無符號32位數(shù)位數(shù)typedef signed long INT32S; /有符號有符號32位數(shù)位數(shù)typedef float FP32; /單精度浮點(diǎn)數(shù)單精度浮點(diǎn)數(shù)typedef double FP64; /雙精度浮點(diǎn)數(shù)雙精度浮點(diǎn)數(shù)typedef unsigned char OS

55、_STK; /棧單元寬度為棧單元寬度為8比特比特typedef unsigned char OS_CPU_SR; / Define size of CPU status register (PSW = 8 bits)#define BYTE INT8S /兼容以前版本的數(shù)據(jù)類型兼容以前版本的數(shù)據(jù)類型#define UBYTE INT8U /uC/OS-II可以不用這些數(shù)據(jù)類型可以不用這些數(shù)據(jù)類型#define WORD INT16S#define UWORD INT16U#define LONG INT32S#define ULONG INT32U34 7.2.2 OS_CPU.H( 7.2.

56、2 OS_CPU.H(續(xù)續(xù)) )在完成與編譯器相關(guān)的數(shù)據(jù)類型的設(shè)定后,進(jìn)行與處理器相關(guān)的代碼的編寫,分在完成與編譯器相關(guān)的數(shù)據(jù)類型的設(shè)定后,進(jìn)行與處理器相關(guān)的代碼的編寫,分為以下幾個部分:為以下幾個部分:v 對臨階段的處理。對臨階段的處理。 #define OS_ENTER_CRITICAL()#define OS_ENTER_CRITICAL()EA=0EA=0 #define OS_EXIT_CRITICAL() #define OS_EXIT_CRITICAL()EA=1EA=1v 確定堆棧的增長方向。確定堆棧的增長方向。 MCS-51MCS-51堆棧從低地址往高地址增長,因此將堆棧從低

57、地址往高地址增長,因此將OS_STK_GROWTHOS_STK_GROWTH定義為定義為0 0。 #define OS_STK_GROWTH 0#define OS_STK_GROWTH 0定義定義OS_TASK_SW()OS_TASK_SW()宏。宏。 MCS-51MCS-51無軟中斷指令,只能通過函數(shù)調(diào)用模仿。無軟中斷指令,只能通過函數(shù)調(diào)用模仿。 #define OS_TASK_SW() OSCtxSw()#define OS_TASK_SW() OSCtxSw()35 7.2.3 OS_CPU_C.C 7.2.3 OS_CPU_C.C堆棧設(shè)計時需要考慮的因素:堆棧設(shè)計時需要考慮的因素:

58、CPU自動入棧的寄存器及壓棧順序。自動入棧的寄存器及壓棧順序。 需要額外保存哪些寄存器。需要額外保存哪些寄存器。 所采用的編譯器對形式參數(shù)的傳遞方法。所采用的編譯器對形式參數(shù)的傳遞方法。 堆棧的增長方向。堆棧的增長方向。 堆棧指針是指向下一個可用空間還是指向上次入棧數(shù)據(jù)。堆棧指針是指向下一個可用空間還是指向上次入棧數(shù)據(jù)。 所采用的所采用的CPU是否存在系統(tǒng)堆棧。是否存在系統(tǒng)堆棧。 堆棧深度。堆棧深度。OS_CPU_C.C文件包含文件包含10個個C函數(shù):函數(shù):OSTaskStkInit()、OSTaskCreateHook()、OSTaskDelHook()、OSTaskSwHook()、OST

59、askIdleHook()、OSTaskStatHook()、OSTimeTickHook()、OSInitHookBegin()、OSInitHookEnd()、OSTCBInitHook() 唯一必要的函數(shù)是唯一必要的函數(shù)是OSTaskStkInit()OSTaskStkInit()。OSTaskCreate()和和OSTaskCreateExt()通過調(diào)用通過調(diào)用OSTaskStkInit()來初始化任務(wù)的堆棧結(jié)來初始化任務(wù)的堆棧結(jié)構(gòu)。在編寫這個函數(shù)的時候,堆棧結(jié)構(gòu)必須已知,設(shè)計堆棧結(jié)構(gòu)勢在必行。構(gòu)。在編寫這個函數(shù)的時候,堆棧結(jié)構(gòu)必須已知,設(shè)計堆棧結(jié)構(gòu)勢在必行。36 7.2.3 OS_C

60、PU_C.C( 7.2.3 OS_CPU_C.C(續(xù)續(xù)) )查詢查詢MCS-51相關(guān)資料,對以上因素加以分析:相關(guān)資料,對以上因素加以分析: 傳統(tǒng)的傳統(tǒng)的8051處理器在中斷來臨時只將程序計數(shù)器處理器在中斷來臨時只將程序計數(shù)器PC的值壓入堆棧。的值壓入堆棧。 按照按照uC/OS-II的要求,保存全部寄存器,的要求,保存全部寄存器,MCS-51的寄存器有的寄存器有PSW、ACC、B、 DPL、DPH、R0R7和和SP。 Cx51編譯器允許用編譯器允許用CPU寄存器傳遞寄存器傳遞3個參數(shù)。個參數(shù)。 堆棧從低地指向高地址增長。堆棧從低地指向高地址增長。 堆棧指針指向上次入棧地址。堆棧指針指向上次入棧地址。 MCS-

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論