版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、移植c/os-ii這篇文章介紹如何將c/os-ii移植到不同的處理器上。所謂移植,就是使一個(gè)實(shí)時(shí)內(nèi)核能在其他的微處理器上運(yùn)行。為了方便移植,大部分c/os-ii的代碼是用c語(yǔ)言編寫(xiě)的:但是,仍需要用c語(yǔ)言和匯編語(yǔ)言編寫(xiě)一些與處理器硬件相關(guān)的代碼,這是因?yàn)閏/os-ii在讀/寫(xiě)處理器寄存器時(shí),只能通過(guò)匯編語(yǔ)言來(lái)實(shí)現(xiàn)。由于c/os-ii在設(shè)計(jì)前就已經(jīng)考慮了可移植性,所以它的移植相對(duì)來(lái)說(shuō)是比較容易的。要使c/os-ii正常運(yùn)行,處理器必須滿足以下要求:(1) 處理器的c編譯器能產(chǎn)生可重入型代碼:(2) 處理器支持中斷,并且能產(chǎn)生定時(shí)中斷(通常為10-100hz);(3) 用c語(yǔ)言就可以開(kāi)關(guān)中斷;(4
2、) 處理器能支持一定數(shù)量的數(shù)據(jù)存儲(chǔ)器的硬件堆棧;(5) 處理器有將堆棧指針以及其他cpu寄存器的內(nèi)容讀出、并存儲(chǔ)到堆?;騼?nèi)存中去的指令;如果已經(jīng)了解處理器和c編譯器的技術(shù)細(xì)節(jié),那么移植的工作是非常容易的,測(cè)試一個(gè)像c/os-ii這樣的實(shí)時(shí)內(nèi)核其實(shí)并不復(fù)雜,甚至可以在沒(méi)有任何應(yīng)用程序下測(cè)試,換句話說(shuō),就是讓內(nèi)核自己測(cè)試自己。有兩種原因要這樣做:第一,避免使本來(lái)就復(fù)雜的事情變的更加復(fù)雜化;第二,如果出現(xiàn)問(wèn)題可以知道問(wèn)題出在內(nèi)核代碼中,而不是應(yīng)用程序中。剛開(kāi)始時(shí),可以運(yùn)行一些簡(jiǎn)單的任務(wù)和時(shí)鐘節(jié)拍中斷程序。一旦多任務(wù)調(diào)度成功運(yùn)行了,再添加應(yīng)用程序的任務(wù)就更加容易了。1.1 開(kāi)發(fā)工具如前所述移植c/os
3、-ii需要標(biāo)準(zhǔn)的c交叉編譯器,并且是針對(duì)所使用的cpu的;因?yàn)樗且粋€(gè)可剝奪的內(nèi)核,只能通過(guò)c編譯器來(lái)產(chǎn)生可重入型代碼。同時(shí)c編譯器還要支持匯編語(yǔ)言程序。絕大部分為嵌入式系統(tǒng)設(shè)計(jì)的c編譯器都包括匯編器、鏈接器、定位器。鏈接器用來(lái)將不同的模塊(編譯過(guò)或匯編過(guò)的文件)鏈接成目標(biāo)文件;定位器則允許將代碼和數(shù)據(jù)放置在目標(biāo)處理器的指定內(nèi)存空間中。所用的c編譯器還提供另一種機(jī)制,能在c編譯器中開(kāi)中斷和關(guān)中斷。一些編譯器允許在c語(yǔ)言源代碼中直接插入?yún)R編語(yǔ)句,這就使得插入相應(yīng)的處理器中的指令開(kāi)中斷和關(guān)中斷變得容易了。1.2 文件(1)includes.h文件includes.h是一個(gè)頭文件,它出現(xiàn)在每個(gè).c文
4、件的第一行,如下:# include “ includes.h ”includes.h文件使得工程項(xiàng)目中的每個(gè).c文件無(wú)需分別考慮它實(shí)際上需要哪些頭文件。使用includes.h文件的唯一缺點(diǎn)就是它可能包含一些與當(dāng)前要編譯的.c文件實(shí)際上不相干的頭文件。這意味著每個(gè)文件的編譯時(shí)間都會(huì)增加;但由于他增加了代碼的可移植性,所以還是決定使用這種方法。也可以通過(guò)重新編譯includes.h文件來(lái)增加頭文件,但是頭文件必須添加在文件列表的最后。(2) os_cpu.h文件os_cpu.h包含了用#define語(yǔ)句定義的、與處理器相關(guān)的常數(shù)、宏以及類型。os_cpu.h文件的大體結(jié)構(gòu)如程序清單t1所列:#
5、ifdef os_cpu_globals#define os_cpu_ext#else#define os_cpu_ext extern#endiftypedef unsigned char boolean;typedef unsigned char int8u;/* 無(wú)符號(hào)8位整數(shù)*/typedef signed char int8s;/* 有符號(hào)8位整數(shù)*/typedef unsigned int int16u;/* 無(wú)符號(hào)16位整數(shù)*/typedef signed int int16s;/* 有符號(hào)16位整數(shù)*/typedef unsigned long int32u;/* 無(wú)符號(hào)32位
6、整數(shù) */typedef signed long int32s;/* 有符號(hào)32位整數(shù)*/typedef float fp32;/* 單精度浮點(diǎn)數(shù) */typedef double fp64;/* 雙精度浮點(diǎn)數(shù) */typedef unsigned int os_stk;/* 堆棧入口寬度為16位*/#define os_enter_critical() ?/* 關(guān)中斷*/#define os_exit_critical() ? /* 開(kāi)中斷s */ #define os_stk_growth 1 /* 定義堆棧方向:1=向下遞減,0=向上遞增 */#define os_task_sw() ?
7、 程序清單 t1 os_cpu.h,與編譯器相關(guān)的數(shù)據(jù)類型因?yàn)椴煌奈⑻幚砥饔胁煌淖珠L(zhǎng),所以c/os-ii的移植包括了一系列的數(shù)據(jù)類型的定義,而確保其可移植性。尤其是,c/os-ii代碼從不使用c語(yǔ)言中的 short, int 及l(fā)ong等數(shù)據(jù)類型,因?yàn)樗鼈兪桥c編譯器相關(guān)的,是不可移植的。相反,定義的數(shù)據(jù)結(jié)構(gòu)等既是可移植的,又很直觀。舉例來(lái)說(shuō),int16u數(shù)據(jù)類型總是代表16位的無(wú)符號(hào)整型數(shù)。這樣c/os-ii就可以斷定,聲明為該數(shù)據(jù)類型變量的范圍都是065535。將c/os-ii移植到32位的處理器上,就意味著int16u實(shí)際被聲明為無(wú)符號(hào)短整型數(shù),而不是無(wú)符號(hào)整數(shù),但是,c/os-ii處
8、理的仍然是int16u。你必須將任務(wù)堆棧的數(shù)據(jù)類型告訴c/os-ii。這是通過(guò)為os_stk聲明恰當(dāng)?shù)腸數(shù)據(jù)類型來(lái)實(shí)現(xiàn)的。如果處理器的堆棧是32位的,那么就應(yīng)該將os_stk聲明:為:unsigned int,所有的任務(wù)堆棧都必須聲明使用os_stk作為它的數(shù)據(jù)類型。用戶需要做的只是查閱編譯器文檔,找出對(duì)應(yīng)于c/os-ii的標(biāo)準(zhǔn)的c的相應(yīng)數(shù)據(jù)類型。 os_cpu.h,os_enter_critical()和os_exit_critical()像其它的實(shí)時(shí)內(nèi)核一樣,c/os-ii需要先關(guān)中斷再處理臨界段代碼,并且在處理完畢后再重新開(kāi)中段。這就能夠保證臨界段代碼免受多任務(wù)或中斷服務(wù)子程序的破壞。通
9、常每個(gè)處理器都會(huì)提供一定的匯編指令來(lái)開(kāi)關(guān)中斷,c編譯器必須有一定的機(jī)制直接從c語(yǔ)言中執(zhí)行這些操作。有些編譯器允許在c源代碼中直接加入?yún)R編語(yǔ)句,這就使得插入處理器指令來(lái)開(kāi)關(guān)中斷變的容易,有些其它的編譯器提供語(yǔ)言擴(kuò)展功能,可以直接從c語(yǔ)言中開(kāi)關(guān)中斷。為了隱藏編譯器廠商提供的不同實(shí)現(xiàn)方法,以增加可移植性,c/os-ii定義了2個(gè)宏,用來(lái)關(guān)開(kāi)中斷:os_enter_critical()和os_exit_critical(),如t1:它們都是成對(duì)出現(xiàn)的,分別加在臨界段代碼的前面和后面;c/os-ii service function os_enter_critical();/*臨界段代碼*/os_exi
10、t_critical();t1方法一:實(shí)現(xiàn)os_enter_critical()和os_exit_critical()這兩個(gè)宏的這種方法是最簡(jiǎn)單的方法,在中調(diào)用處理器指令關(guān)中斷,以及在中調(diào)用相應(yīng)處理器指令開(kāi)中斷;但是這個(gè)過(guò)程還存在小小的問(wèn)題:如果在禁止中斷的情況下調(diào)用c/os-ii函數(shù),那么從c/os-ii函數(shù)返回時(shí),中斷可能會(huì)變成允許的了。而實(shí)際上如果調(diào)用c/os-ii之前中斷是關(guān)掉的希望從c/os-ii函數(shù)返回時(shí),希望中斷還是關(guān)掉的。在這種情況下,僅靠這種方法是不適宜的。方法二:執(zhí)行os_enter_critical()時(shí),先將中斷狀態(tài)保存到堆棧中,然后關(guān)中斷;而當(dāng)執(zhí)行os_exit_cr
11、itical()時(shí),再?gòu)亩褩V谢謴?fù)原來(lái)的中斷開(kāi)關(guān)狀態(tài)。如果用這種方法,那么不管用戶是在中斷禁止,還是中斷允許的情況下調(diào)用c/os-ii的功能函數(shù),調(diào)用后都不會(huì)改變中斷狀態(tài)。應(yīng)用程序可以調(diào)用os_enter_critical()和os_exit_critical(),以保護(hù)臨界段代碼;但是,在使用這種方法時(shí)需特別小心,因?yàn)槿绻谡{(diào)用像ostimedly()之類的功能函數(shù)之前就關(guān)掉了中斷,應(yīng)用程序就會(huì)崩潰。發(fā)生這種情況的原因是,任務(wù)被掛起,知道延遲時(shí)間到,而中斷是關(guān)掉的。ostimedly()實(shí)際上是依靠時(shí)鐘節(jié)拍實(shí)現(xiàn)中斷的,而因?yàn)橹袛嗍顷P(guān)掉的,程序不可能獲得時(shí)鐘節(jié)拍中斷。明顯的,所有的pend調(diào)用
12、都會(huì)涉及到這個(gè)問(wèn)題,需十分小心。一個(gè)通用的辦法是,應(yīng)該在中斷允許的情況下調(diào)用c/os-ii的系統(tǒng)功能函數(shù)。 os_cpu.h, os_stk_growth絕大多數(shù)微處理器和微控制器的堆棧都是從上往下遞減的,但是也有某些處理器使用的是相反的方式,c/os-ii被設(shè)計(jì)成對(duì)這兩種情況都可以處理,只要再用配置常數(shù)os_stk_growth指定堆棧的方向就可以了:置os_stk_growth為0,表示堆棧從下(低地址)往上(高地址)遞增:置os_stk_growth為1,表示堆棧從上(高地址)往下(低地址)遞減。 os_cpu.h, os_task_sw()os_task_sw()是一個(gè)宏,是在c/os
13、-ii從低優(yōu)先級(jí)任務(wù)切換到高優(yōu)先級(jí)任務(wù)時(shí)須用到的。os_task_sw()總是在任務(wù)級(jí)代碼中被調(diào)用。另一個(gè)函數(shù)osintexit()用在中斷服務(wù)子程序isr中。任務(wù)切換只是簡(jiǎn)單地將處理器的寄存器保存到將被掛起的任務(wù)的堆棧中,并且從堆棧中恢復(fù)要運(yùn)行的更高優(yōu)先級(jí)的任務(wù)。在c/os-ii中,處于就緒態(tài)任務(wù)的堆棧結(jié)構(gòu)看起來(lái)就像剛剛發(fā)生過(guò)中斷一樣,所有的寄存器都保存在堆棧中。換句話說(shuō),c/os-ii要運(yùn)行處于就緒態(tài)的任務(wù)必須要做的事是,從任務(wù)堆棧中恢復(fù)所有的寄存器,并且執(zhí)行中斷返回指令。為了任務(wù)調(diào)度,可以通過(guò)執(zhí)行os_task_sw()模仿中斷的產(chǎn)生。絕大多數(shù)處理器會(huì)提供軟中斷或指令陷阱來(lái)完成這項(xiàng)功能。
14、中斷服務(wù)子程序或指令陷阱處理函數(shù)(也叫做異常處理函數(shù))的中斷向量地址必須指向匯編語(yǔ)言函數(shù)osctxsw()。例如,在intel或者amd80x86處理器上可以使用int指令,但是中斷向量必須指向osctxsw()。有些處理器如z80,并不提供軟中斷機(jī)制。在這種情況下需要想辦法將堆棧結(jié)構(gòu)設(shè)置成與軟中斷發(fā)生后的堆棧結(jié)構(gòu)一樣。在os_task_sw()函數(shù)中調(diào)用osctxsw(),而不是將某個(gè)中斷向量指向osctxsw()。實(shí)際上c/os-ii已經(jīng)被移植到了z80處理器上,c/os-ii也同樣是可以的。(3) os_cpu_a.asmc/os-ii的移植實(shí)例要求用戶編寫(xiě)4個(gè)簡(jiǎn)單的匯編程序:ossta
15、rthighrdy()osctxsw()osintctxsw()ostickisr()如果編譯器支持插入行匯編代碼,就可以將所有與處理器相關(guān)的代碼放到os_cpu.c文件中,而不必再有單獨(dú)的匯編語(yǔ)言文件。 os_cpu_a.asm, osstarthighrdy()osstart()函數(shù)調(diào)用osstarthighrdy()來(lái)使就緒態(tài)任務(wù)中優(yōu)先級(jí)最高的任務(wù)開(kāi)始運(yùn)行,在調(diào)用它之前,要已經(jīng)建立了至少一個(gè)應(yīng)用任務(wù)。osstarthighrdy()假設(shè)ostcbhighrdy指向最高優(yōu)先級(jí)任務(wù)的任務(wù)控制塊。就像先前提到的,在c/os-ii中處于就緒態(tài)任務(wù)的堆棧結(jié)構(gòu)看起來(lái)就像剛發(fā)生過(guò)中斷一樣,所有的寄存器
16、都保存在堆棧中。要想運(yùn)行最高優(yōu)先級(jí)任務(wù),需將所有處理器按順序從任務(wù)堆棧中恢復(fù)出來(lái),并且執(zhí)行中斷返回指令。為簡(jiǎn)單起見(jiàn),堆棧指針總是存儲(chǔ)字任務(wù)控制塊的開(kāi)頭。換句話說(shuō),也就是需要恢復(fù)的任務(wù)堆棧指針總是存儲(chǔ)在任務(wù)控制塊的偏移地址為0的位置。注意到osstarthighrdy()必須調(diào)用ostaskswhook()函數(shù),但osstarthighrdy()函數(shù)只是做了任務(wù)切換工作的一半只是完成了高優(yōu)先級(jí)任務(wù)寄存器的恢復(fù),而并沒(méi)有保存當(dāng)前任務(wù)的寄存器。ostaskswhook()函數(shù)必須檢查osrunning位,以確定ostaskswhook()函數(shù)是被osstarthighrdy()調(diào)用的(osrunni
17、ng是false),還是在正常的任務(wù)切換之中(osrunning是true)被調(diào)用的。 os_cpu_a.asm, osctxsw()任務(wù)級(jí)的切換是通過(guò)執(zhí)行軟中段指令,或者依據(jù)處理器的不同,執(zhí)行trap指令來(lái)實(shí)現(xiàn)的。中斷服務(wù)子程序,陷阱或異常處理的向量地址必須指向osctxsw()。如果當(dāng)前任務(wù)調(diào)用c/os-ii提供的功能函數(shù),并使得更高優(yōu)先級(jí)任務(wù)進(jìn)入了就緒態(tài),在系統(tǒng)服務(wù)調(diào)用的最后,c/os-ii會(huì)調(diào)用ossched(),并由此推斷出當(dāng)前任務(wù)不是需要運(yùn)行的最重要的任務(wù)了,ossched()先將最高優(yōu)先級(jí)任務(wù)的地址裝載到ostcbhighrdy,再通過(guò)調(diào)用os_task_sw()執(zhí)行軟中斷或陷阱
18、指令。注意變量ostcbcur已經(jīng)包含了指向當(dāng)前任務(wù)控制塊的指針。軟中斷指令會(huì)強(qiáng)制將處理器的一些寄存器保存到當(dāng)前任務(wù)的堆棧中并使處理器執(zhí)行osctxsw()。osctxsw()示意性代碼如t2,這些代碼必須用匯編語(yǔ)言編寫(xiě),因?yàn)橛脩舨荒苤苯釉赾語(yǔ)言中訪問(wèn)cpu寄存器。void osctxsw(void)保存處理器寄存器;在當(dāng)前任務(wù)的任務(wù)控制塊中保存當(dāng)前任務(wù)的堆棧指針:ostcbcur-ostcbstkptr = stack pointer;call user definable ostaskswhook();ostcbcur = ostcbhighrdy; ospriocur = osprioh
19、ighrdy;得到將要重新開(kāi)始運(yùn)行的任務(wù)的堆棧指針:stack pointer = ostcbhighrdy-ostcbstkptr;從新任務(wù)的任務(wù)堆棧中恢復(fù)處理器所有寄存器的值;執(zhí)行中斷返回指令; t2 osctxsw()的示意性代碼 os_cpu_a.asm, osintctxsw()osintexit()通過(guò)調(diào)用osintctxsw(),在isr中執(zhí)行任務(wù)切換功能。因?yàn)閛sintctxsw()是在isr中被調(diào)用的,所以假定所有的處理器都被正確地保存到了被中斷任務(wù)的堆棧之中。osintctxsw()的示意性代碼如t3所示,這些代碼必須用匯編語(yǔ)言編寫(xiě),因?yàn)樵赾語(yǔ)言中不能直接訪問(wèn)cpu寄存器。
20、如果編譯器支持插入?yún)R編語(yǔ)言代碼,就可以將osintctxsw()的代碼放在os_cpu_c.c文件中,而不放在os_cpu_a.asm文件中。實(shí)際上如果需要,可以跳轉(zhuǎn)到osctxsw()中相同的代碼,以減少代碼量。void osintctxsw(void)調(diào)用用戶定義的 ostaskswhook();ostcbcur = ostcbhighrdy;ospriocur = ospriohighrdy;得到將要重新執(zhí)行任務(wù)的堆棧指針:stack pointer = ostcbhighrdy-ostcbstkptr;從新任務(wù)堆棧中恢復(fù)所有處理器寄存器;執(zhí)行中斷返回指令;t3 osintctxsw()
21、的示意性代碼 os_cpu_a.asm, ostickisr()c/os-ii要求用戶提供一個(gè)周期性的時(shí)鐘源,來(lái)實(shí)現(xiàn)時(shí)間的延遲和超時(shí)功能。時(shí)鐘節(jié)拍應(yīng)該每秒發(fā)生10100次/秒。為了完成該任務(wù),可以使用硬件定時(shí)器,也可以從交流點(diǎn)中獲得50/60hz的時(shí)鐘頻率。必須在開(kāi)始多任務(wù)后,即調(diào)用osstart()后,啟動(dòng)時(shí)鐘節(jié)拍中斷;然后,可以在osstart()運(yùn)行后,c/os-ii啟動(dòng)運(yùn)行的第一個(gè)任務(wù)中初始化節(jié)拍中斷。通常容易犯的錯(cuò)誤是,在調(diào)用osinit()和osstart()之間打開(kāi)了時(shí)鐘節(jié)拍。(如程序清單t4所列)。 void main(void)osinit(); /* 初始化 c/os-ii
22、 */* 應(yīng)用程序初始化代碼 */* 調(diào)用 ostaskcreate() 建立至少1個(gè)任務(wù) */開(kāi)時(shí)鐘節(jié)拍中斷; /* 千萬(wàn)不要在這里開(kāi)中斷 */osstart(); /* 開(kāi)始多任務(wù) */t4 在不正確的位置啟動(dòng)節(jié)拍中斷porting c/os-iithis article describes in general terms what needs to be done in order to adapt c/os-ii to different processors. adapting a real-time kernel to a microprocessor or a microcon
23、troller is called a port. most of c/os-ii is written in c for portability, however, it is still necessary to write some processor specific code in c and assembly language. specifically, c/os-ii manipulates processor registers which can only be done through assembly language. porting c/os-ii to diffe
24、rent processors is relatively easy because c/os-ii was designed to be portable. a processor can run c/os-ii if it satisfies the following general requirements:(1) you must have a c compiler for the processor and the c compiler must be able to produce reentrant code. (2) you must be able to disable a
25、nd enable interrupts from c.(3) the processor must support interrupts and you need to provide an interrupt that occurs at regular intervals (typically between 10 to 100 hz).(4) the processor must support a hardware stack, and the processor must be able to store a fair amount of data on the stack (po
26、ssibly many kbytes).(5) the processor must have instructions to load and store the stack pointer and other cpu registers either on the stack or in memory.porting c/os-ii is actually quite straightforward once you understand the subtleties of the target processor and the c compiler you will be using.
27、 depending on the processor, a port can consist of writing or changing between 50 and 300 lines of code! porting c/os-ii could take you anywhere between a few hours to about a week.once you have a port of c/os-ii for your processor, you will need to verify its operation. testing a multitasking real-
28、time kernel such as c/os-ii is not as complicated as you may think. you should test your port without application code. in other words, test the operations of the kernel by itself. there are two reasons to do this. first, you dont want to complicate things anymore than they need to be. second, if so
29、mething doesnt work, you know that the problem lies in the port as opposed to your application. start with a couple of simple tasks and only the ticker interrupt service routine. once you get multitasking going, its quite simple to add your application tasks.1.1 development toolsas previously stated
30、, you need a c compiler for the processor you intend to use in order to port c/os-ii. because c/os-ii is a preemptive kernel, you should only use a c compiler that generates reentrant code. your c compiler must also be able to support assembly language programming. most c compiler designed for embed
31、ded systems will, in fact, also include an assembler, a linker, and a locator. the linker is used to combine object files (compiled and assembled files) from different modules while the locator will allow you to place the code and data anywhere in the memory map of the target processor. your c compi
32、ler must also provide a mechanism to disable and enable interrupts from c. some compilers will allow you to insert in-line assembly language statements in your c source code. this makes it quite easy to insert the proper processor instructions to enable and disable interrupts. 1.2 files(1) includes.
33、h includes.h is a master include file and is found at the top of all .c files as follows:# include “includes.h”includes.h allows every .c file in your project to be written without concerns about which header file will actually be needed. the only drawback to having a master include file is that inc
34、ludes.h may include header files that are not pertinent to the actual .c file being compiled. this means that each file will require extra time to compile. this inconvenience is offset by code portability. you can edit includes.h to add your own header files but, your header files should be added at
35、 the end of the list.(2) os_cpu.hos_cpu.h contains processor and implementation specific #defines constants, macros, and typedefs. the general layout of os_cpu.h is shown in listing #ifdef os_cpu_globals#define os_cpu_ext#else#define os_cpu_ext extern#endiftypedef unsigned char boolean;typedef unsig
36、ned char int8u;/* unsigned 8 bit quantity*/ (1)typedef signed char int8s;/* signed 8 bit quantity*/typedef unsigned int int16u;/* unsigned 16 bit quantity*/typedef signed int int16s;/* signed 16 bit quantity*/typedef unsigned long int32u;/* unsigned 32 bit quantity*/typedef signed long int32s;/* sig
37、ned 32 bit quantity*/typedef float fp32;/*single precision floating point*/ (2)typedef double fp64;/* double precision floating point */typedef unsignedint os_stk;/*each stack entryis 16-bit wide*/#define os_enter_critical() ? /* disable interrupts*/ (3)#define os_exit_critical() ? /* enable interru
38、pts*/ #define os_stk_growth 1 /* define stack growth: 1 = down, 0 = up*/ (4)#define os_task_sw() ? os_cpu.h, compiler specific data types because different microprocessors have different word length, the port of c/os-ii includes a series of type definitions that ensures portability. specifically, c/
39、os-iis code never makes use of cs short, int and, long data types because they are inherently non-portable. instead, i defined integer data types that are both portable and intuitive the int16u data type, for example, always represents a 16-bit unsigned integer. c/os-ii and your application code can
40、 now assume that the range of values for variables declared with this type is from 0 to 65535. a c/os-ii port to a 32-bit processor could mean that an int16u is actually declared as an unsigned short instead of an unsigned int. where c/os-ii is concerned, however, it still deals with an int16u.you m
41、ust tell c/os-ii the data type of a tasks stack. this is done by declaring the proper c data type for os_stk. if stack elements on your processor are 32-bit and your compiler documentation specify that an int is 32-bit then, you would declare os_stk as being of type unsigned int. all task stacks mus
42、t be declared using os_stk as its data type.all you have to do is to consult the compilers manual and find the standard c data types that corresponds to the types expected by c/os-ii.os_cpu.h, os_enter_critical() and os_exit_critical()c/os-ii like all real-time kernels need to disable interrupts in
43、order to access critical sections of code, and re-enable interrupts when done. this allows c/os-ii to protect critical code from being entered simultaneously from either multiple tasks or interrupt service routines (isrs). every processor generally provide instructions to disable/enable interrupts a
44、nd your c compiler must have a mechanism to perform these operations directly from c. some compilers will allow you to insert in-line assembly language statements in your c source code. this makes it quite easy to insert processor instructions to enable and disable interrupts. other compilers will a
45、ctually contain language extensions to enable and disable interrupts directly from c. to hide the implementation method chosen by the compiler manufacturer, c/os-ii defines two macros to disable and enable interrupts: os_enter_critical() and os_exit_critical(), respectivelyt1.c/os-iis critical secti
46、ons are wrapped with os_enter_critical() and os_exit_critical() as shown below:c/os-ii service functionos_enter_critical(); /* c/os-ii critical code section */os_exit_critical();t1method #1:the first and simplest way to implement these two macros is to invoke the processor instruction to disable int
47、errupts for os_enter_critical() and the enable interrupts instruction for os_exit_critical(). there is, however, a little problem with this scenario. if you called the c/os-ii function with interrupts disabled then, upon return from c/os-ii, interrupts would be enabled! if you had interrupts disable
48、d, you may have wanted them to be disabled upon return from the c/os-ii function. in this case, the above implementation would not be adequate.method #2:the second way to implement os_enter_critical() is to save the interrupt disable status onto the stack and then, disable interrupts. os_exit_critic
49、al() would simply be implemented by restoring the interrupt status from the stack. using this scheme, if you called a c/os-ii service with either interrupts enabled or disabled then, the status would be preserved across the call.your application can use os_enter_critical()and os_exit_critical() to a
50、lso protect critical sections of code. be careful, however, because your application will crash if you have interrupts disabled before calling a service such as ostimedly(). this will happen because the task will be suspended until time expires but, because interrupts are disabled, you would never s
51、ervice the tick interrupt! obviously, all the pend calls are also subject to this problem so, be careful. as a general rule, you should always call c/os-ii services with interrupts enabled! os_cpu.h, os_stk_growththe stack on most microprocessors and microcontrollers grows from high-memory to low-me
52、mory. there are, however, some processors that work the other way around. c/os-ii has been designed to be able to handle either flavor. this is accomplished by specifying to c/os-ii which way the stack grows through the configuration constant os_stk_growth as shown below:set os_stk_growth to 0 for l
53、ow to high memory stack growth.set os_stk_growth to 1 for high to low memory stack growth. os_cpu.h, os_task_sw()os_task_sw() is a macro that is invoked when c/os-ii switches from a low-priority task to the highest-priority task. os_task_sw() is always called from task level code. another mechanism,
54、 osintexit(), is used to perform a context switch when an isr makes a higher priority task ready for execution. a context switch simply consist of saving the processor registers on the stack of the task being suspended, and restoring the registers of the higher-priority task from its stack.in c/os-i
55、i, the stack frame for a ready task always looks as if an interrupt has just occurred and all processor registers were saved onto it. in other words, all that c/os-ii has to do to run a ready task is to restore all processor registers from the tasks stack and execute a return from interrupt. to swit
56、ch context, you should implement os_task_sw() so that you simulate an interrupt. most processors provide either software interrupt or trap instructions to accomplish this. the isr or trap handler (also called the exception handler) must vector to the assembly language function osctxsw()for example,
57、a port for an intel or amd 80x86 processor would use an int instruction. the interrupt handler would need to vector to osctxsw(). there are some processors like the zilog z80 that do not provide a software interrupt mechanism. in this case, you would need to simulate the stack frame as closely to an interrupt stack frame as you can. in this case, os_
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 電梯機(jī)房管理規(guī)章
- 名著閱讀《紅星照耀中國(guó)》-八年級(jí)語(yǔ)文上冊(cè)同步備課精講(統(tǒng)編版)
- 西京學(xué)院《信息檢索導(dǎo)論》2023-2024學(xué)年第一學(xué)期期末試卷
- 西京學(xué)院《商務(wù)應(yīng)用文寫(xiě)作》2022-2023學(xué)年第一學(xué)期期末試卷
- 人教版五年級(jí)上冊(cè)第11課新型玻璃
- 西京學(xué)院《機(jī)電一體化系統(tǒng)設(shè)計(jì)》2021-2022學(xué)年期末試卷
- 幼兒園小班兒歌《曬太陽(yáng)》課件
- 西華師范大學(xué)《組織行為學(xué)》2022-2023學(xué)年第一學(xué)期期末試卷
- 人教版初中課件
- 西華師范大學(xué)《小學(xué)課程設(shè)計(jì)與評(píng)價(jià)》2023-2024學(xué)年第一學(xué)期期末試卷
- 培訓(xùn)學(xué)校校長(zhǎng)績(jī)效考核表
- 1厘米方格紙電子版本
- 防水材料檢驗(yàn)作業(yè)指導(dǎo)書(shū)
- X鄉(xiāng)初級(jí)中學(xué)留守兒童家長(zhǎng)學(xué)校章程
- 三角形的重心
- 我國(guó)綠色化工未來(lái)發(fā)展戰(zhàn)略與思考
- 蘇里南商業(yè)機(jī)會(huì)多多
- Himalaya藏文輸入法的安裝過(guò)程及其鍵盤(pán)布局介紹
- 高考數(shù)學(xué)小題狂練:每題都附有詳細(xì)解析
- 浮動(dòng)碼頭施工方案
- Poka-Yoke防錯(cuò)技術(shù)(完整版)
評(píng)論
0/150
提交評(píng)論