欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
我的ucos學(xué)習分析

                              2009.9.10
1.在uC/OS-II的幫助手冊?xún)?作者特地強調絕對不能在OSInit()或者OSStart()內
調用Timer初始化程序,那會(huì )破壞系統的可移植性同時(shí)帶來(lái)性能上的損失。

所以,一個(gè)折中的辦法就是:
在優(yōu)先級最高的程序內調用,這樣可以保證當OSStart()調用系統內部函數
OSStartHighRdy()開(kāi)始多任務(wù)后,首先執行的就是Timer初始化程序?;蛘?br>專(zhuān)門(mén)開(kāi)一個(gè)優(yōu)先級最高的任務(wù),只做一件事情,那就是執行 Timer初始化,
之后通過(guò)調用OSTaskSuspend()將自己掛起來(lái),永遠不再執行。不過(guò)這樣會(huì )
浪費一個(gè)TCB空間。對于那些RAM吃緊的系統來(lái)說(shuō),還是不用為好。
2.(三) 一些重要的uC/OS-II API介紹

任何一個(gè)操作系統都會(huì )提供大量的API供程序員使用,uC/OS-II也不例外。由于uC/OS-II面向
的是嵌入式開(kāi)發(fā),并不要求大而全,所以?xún)群颂峁┑腁PI也就大多和多任務(wù)息息相關(guān)。
主要的有以下幾類(lèi):

1)任務(wù)類(lèi)

2)消息類(lèi)

3)同步類(lèi)

4)時(shí)間類(lèi)

5)臨界區與事件類(lèi)

我個(gè)人認為對于初級程序員而言,任務(wù)類(lèi)和時(shí)間類(lèi)是必須要首先掌握的兩種類(lèi)型的API。
下面我就來(lái)介紹比較重要的:

1) OSTaskCreate函數

這個(gè)函數應該至少再main函數內調用一次,在OSInit函數調用之后調用。作用就是創(chuàng )建
一個(gè)任務(wù)。目前有四個(gè)參數,分別是任務(wù)的入口地址,任務(wù)的參數, 任務(wù)堆棧的首地址和
任務(wù)的優(yōu)先級。調用本函數后,系統會(huì )首先從TCB空閑列表內申請一個(gè)空的TCB指針,然后
將會(huì )根據用戶(hù)給出參數初始化任務(wù)堆棧,并在內部的任務(wù)就緒表內標記該任務(wù)為就緒狀態(tài)。
最后返回,這樣一個(gè)任務(wù)就創(chuàng )建成功了。

2) OSTaskSuspend函數

這個(gè)函數很簡(jiǎn)單,一看名字就該明白它的作用,它可以將指定的任務(wù)掛起。如果掛起的是
當前任務(wù)的話(huà),那么還會(huì )引發(fā)系統執行任務(wù)切換先導函數OSShed來(lái)進(jìn)行一次任務(wù)切換。
這個(gè)函數只有一個(gè)參數,那就是指定任務(wù)的優(yōu)先級。那為什么是優(yōu)先級呢?事實(shí)上在系統
內部,優(yōu)先級除了表示一個(gè)任務(wù)執行的先后次序外,還起著(zhù)分別每一個(gè)任務(wù)的作用,換句話(huà)
說(shuō),優(yōu)先級也就是任務(wù)的ID。所以uC/OS-II不允許出現相同優(yōu)先級的任務(wù)。

3) OSTaskResume函數

這個(gè)函數和上面的函數正好相反,它用于將指定的已經(jīng)掛起的函數恢復成就緒狀態(tài)。如果
恢復任務(wù)的優(yōu)先級高于當前任務(wù),那么還為引發(fā)一次任務(wù)切換。其參數類(lèi)似 OSTaskSuspend
函數,為指定任務(wù)的優(yōu)先級。需要特別說(shuō)明是,本函數并不要求和OSTaskSuspend函數成對使
用。

4) OS_ENTER_CRITICAL宏

很多人都以為它是個(gè)函數,其實(shí)不然,仔細分析一下OS_CPU.H文件,它和下面馬上要談到的
OS_EXIT_CRITICAL都是宏。他們都是涉及特定 CPU的實(shí)現。一般都被替換為一條或者幾條
嵌入式匯編代碼。由于系統希望向上層程序員隱藏內部實(shí)現,故而一般都宣稱(chēng)執行此條指
令后系統進(jìn)入臨界區。其實(shí), 它就是關(guān)個(gè)中斷而已。這樣,只要任務(wù)不主動(dòng)放棄CPU使用權,
別的任務(wù)就沒(méi)有占用CPU的機會(huì )了,相對這個(gè)任務(wù)而言,它就是獨占了。所以說(shuō)進(jìn)入臨界區了。
這個(gè)宏能少用還是少用,因為它會(huì )破壞系統的一些服務(wù),尤其是時(shí)間服務(wù)。并使系統對外界響
應性能降低。

5) OS_EXIT_CRITICAL宏

這個(gè)是和上面介紹的宏配套使用另一個(gè)宏,它在系統手冊里的說(shuō)明是退出臨界區。其實(shí)它就
是重新開(kāi)中斷。需要注意的是,它必須和上面的宏成對出現,否則會(huì )帶來(lái)意想不到的后果。
最壞的情況下,系統會(huì )崩潰。我們推薦程序員們盡量少使用這兩個(gè)宏調用,因為他們的確會(huì )
破壞系統的多任務(wù)性能。

6) OSTimeDly函數

這應該程序員們調用最多的一個(gè)函數了,這個(gè)函數完成功能很簡(jiǎn)單,就是先掛起當起當前任務(wù),
然后進(jìn)行任務(wù)切換,在指定的時(shí)間到來(lái)之后,將當前任務(wù)恢復為就緒狀態(tài),但是并不一定運行,
如果恢復后是優(yōu)先級最高就緒任務(wù)的話(huà),那么運行之。簡(jiǎn)單點(diǎn)說(shuō),就是可以任務(wù)延時(shí)一定時(shí)間
后再次執行它,或者說(shuō),暫時(shí)放棄CPU的使用權。一個(gè)任務(wù)可以不顯式的調用這些可以導致放棄CPU使用權的API,但那樣多任務(wù)性能會(huì )大大降低,因為此時(shí)僅僅依靠時(shí)鐘機制在進(jìn)行任務(wù)切換。一個(gè)好的任務(wù)應該在完成一些操作主動(dòng)放棄使用權,好東西要大家分享嘛!


3.我們推薦程序員們盡量少使用OS_ENTER_CRITICAL宏和 OS_EXIT_CRITICAL宏兩個(gè)宏調用,
因為他們的確會(huì )破壞系統的多任務(wù)性能。why??


4.在以uC/OS為操作系統的項目中,系統可能要處理各種不同的中斷請求,如果某個(gè)中斷處理
程序需要調用uC/OS的各種Post函數向任務(wù)發(fā)出消息,那么uC/OS建議中斷服務(wù)程序的寫(xiě)法是:

1、保存全部CPU寄存器
2、調用OSIntEnter或OSIntNesting直接加1
3、執行用戶(hù)代碼做中斷服務(wù)
4、調用OSIntExit
5、恢復所有CPU寄存器
6、執行中斷返回指令
暫且稱(chēng)為“標準中斷”方式,這種方式實(shí)際上是將這個(gè)中斷處理加入了任務(wù)調度系統,也就是
說(shuō)這個(gè)中斷可以引起任務(wù)的切換。

如果在中斷處理中沒(méi)有調用各種Post函數的話(huà),則可以用一般的、象原來(lái)沒(méi)有操作系統時(shí)的
寫(xiě)法:
1、保存中斷處理程序需要用到的CPU寄存器
2、執行中斷處理
3、恢復保存了的CPU寄存器
4、執行中斷返回指令
暫且稱(chēng)為“快中斷”方式,按照這種方法定義的中斷永遠不會(huì )引起任務(wù)切換。

在uC/OS系統中,每個(gè)任務(wù)都要定義獨立的??臻g,一個(gè)??臻g的使用包括5個(gè)部分:
1、任務(wù)包括的各個(gè)函數的調用返回地址
2、任務(wù)包括的各個(gè)函數中可能在棧上分配的局部變量
3、發(fā)生了“標準中斷”方式定義的中斷或任務(wù)被掛起時(shí),所要保存的任務(wù)上下文
4、發(fā)生了“快中斷”方式定義的中斷時(shí),中斷處理程序所需要的??臻g
5、中斷嵌套時(shí),所要保存的中斷嵌套上下文

在這些使用的部分中,1,2,3,4的內存占用量是比較容易估算的,最精確和保險的確定
方法是:查看由C生成的asm文件,并計算各個(gè)函數的棧使用量。但是第5部分的??臻g使用
量是隨中斷嵌套的深度而不斷增加的,是不確定的,一般的方法只能定義一個(gè)充分大的棧
空間,使之不會(huì )溢出。

為每個(gè)任務(wù)都定義一個(gè)充分大的??臻g,這在某些內存稀缺的小項目中是非常痛苦的,
有時(shí)不得不增擴內存,這就會(huì )使成本增加。

我深入研究了uC/OS后,認為,可以將所有任務(wù)??臻g使用的第5部分合并,這樣將會(huì )大大的
降低整個(gè)系統對內存的需求。

uC/OS的任務(wù)調度是靠OS_Sched和 OSIntExit來(lái)完成的,這兩個(gè)函數中都要先判斷一個(gè)叫
OSIntNesting的系統變量,如果OSIntNesting不為0,則不進(jìn)行任務(wù)切換。也就是說(shuō):
在OSIntNesting為1(當前只有一個(gè)中斷在處理中,并且沒(méi)有嵌套的中斷)時(shí)起,
如果發(fā)生了嵌套的中斷(不管嵌套的層數有深),那么在所有嵌套的中斷一層一層地都返回
直到 OSIntNesting再次為1時(shí)止,任務(wù)棧是不會(huì )切換的(棧指針都在一個(gè)任務(wù)的??臻g中變
化)。

據此,我們可以這樣改動(dòng):設置一個(gè)緩沖區OSInterruptStk,作為嵌套中斷的??臻g,
由所有任務(wù)共享,中斷服務(wù)程序改為:
1、保存全部CPU寄存器
2、調用OSIntEnter或OSIntNesting直接加1
增加:2.1、判斷OSIntNesting是否等于1,如果不是則轉到3
增加:2.2、將棧指針SP保存到OSTCBCur->OSTCBStkPtr
增加:2.3、將SP指向OSInterruptStk的棧頂(注意棧增長(cháng)的方向)。
3、執行用戶(hù)代碼做中斷服務(wù)
4、調用OSIntExit
增加:4.1、判斷OSIntNesting是否等于0,如果不是則轉到5
增加:4.2、從OSTCBCur->OSTCBStkPtr中恢復棧指針SP
5、恢復所有CPU寄存器
6、執行中斷返回指令

并且要修改OSIntCtxSw函數,原始的OSIntCtxSw函數的寫(xiě)法是:
1、調整棧指針來(lái)去掉在調用:OSIntExit,OSIntCtxSw過(guò)程中入棧的多余內容
2、將當前任務(wù)棧指針保存到OSTCBCur中(OSTCBCur->OSTCBStkPtr = __SP__)
3、如果需要則調用OSTaskSwHook
4、OSTCBCur = OSTCBHighRdy
5、OSPrio = OSPrioHighRdy
6、從OSTCBCur中恢復棧指針(__SP__ = OSTCBCur->OSTCBStkPtr)
7、恢復保存了的CPU寄存器
8、執行中斷返回指令

新的寫(xiě)法只需將原寫(xiě)法中的1,2去掉即可,因為1,2步只是保存舊任務(wù)的棧指針,而新的寫(xiě)
法中,這些步被移到了“中斷服務(wù)程序”中的2.2。

5.注意ARM Image for uCOSII for lpc213x 模板中的TargetInit()


對于很多使用ZLG ARM Image for uCOSII for lpc213x 模板的初學(xué)者,常常會(huì )置疑使用該模板
后自動(dòng)生成的target.c文件,和在程序中調用的TargetInit()函數,我和 Zgpswh都是如此,這
個(gè)問(wèn)題當初困擾了很久:當用戶(hù)程序中不調用TargetInit()時(shí),發(fā)現內核能運行,但是等待機制
失靈,調用 TargetInit(),很多硬件中斷打不開(kāi),后來(lái),在很多熱心人的指點(diǎn)下解決了,現重新
總結如下:

請仔細察看ZLG模板里的target.c文件,這里的TargetInit()如下:

void TargetInit(void)
{
    OS_ENTER_CRITICAL();
    srand((uint32) TargetInit);
    VICInit();
    Timer0Init();
    OS_EXIT_CRITICAL();
}

其中的Timer0Init();用于硬件定時(shí)器0的初始化,事實(shí)上,ZLG的移植代碼的μC/OS-Ⅱ的時(shí)鐘節拍是
通過(guò)定時(shí)器0提供的,不在主程序里調用這個(gè)函數,μC/OS-Ⅱ的時(shí)鐘源就無(wú)法打開(kāi);但是,沒(méi)有開(kāi)啟
時(shí)鐘源的μC/OS-Ⅱ是同樣能運行的,只是內核提供的延時(shí)和等待時(shí)限機制都不起作用,系統雖能將
就運行,但因沒(méi)調用TargetInit()而使內核功能不健全。

請注意,TargetInit()中的另一個(gè)函數VICInit ()是用來(lái)中斷的初始化,它其中含有對UART0中斷的
分配,在用戶(hù)程序里需要根據使用的硬件中斷修改這部分代碼,否則,這些硬件中斷無(wú)法開(kāi)啟;
再者,在不調用TargetInit()的時(shí)候,硬件的中斷初始化是在硬件初始化函數中完成,
這也就是Zgpswh提到的現象:不調用TargetInit()內核運行異常,調用了卻開(kāi)不了UART0的中斷。

解決的方法如下:
這在《ARM嵌入式系統基礎教程》的430頁(yè)7.4.3節中論述的很清楚:

……關(guān)鍵在于把程序與芯片相關(guān)中斷源掛接,使芯片在產(chǎn)生相應的中斷后會(huì )調用相應的處理程序。
這需要做兩方面事情:
1. 增加匯編接口的支持?!?br>2. 初始化向量中斷控制器?!?/p>

按照一下方法完成中斷源的的掛接:
1、增加匯編接口的支持。方法是修改IRQ.s文件,在末尾添加本句代碼:

UART0_Handler HANDLER UART0_Exception

追加定義了通用串口0 中斷句柄。
2、初始化向量中斷控制器。將target.c文件中的VICInit()修改如下:

void VICInit(void)
{ extern void IRQ_Handler(void);
   extern void Timer0_Handler(void);
   extern void UART0_Handler(void);
   VICIntEnClr = 0xffffffff;
   VICDefVectAddr = (uint32)IRQ_Handler;
   VICVectAddr0 = (uint32)Timer0_Handler;
   VICVectCntl0 = (0x20 | 0x04);
   VICIntEnable = 1 << 4;
   VICVectAddr14 = (uint32)UART0_Handler;
   VICVectCntl14 = (0x20 | 0x06);
   VICIntEnable = 1 << 6;
}

此為初始化向量中斷控制器。包括定時(shí)器0和串口0,特別要注意的是,一定不可以省略對定
時(shí)器0的初始化
中斷里,不可以調用延時(shí)

請注意,中斷里面是不支持等待機制的。請用自己編的一個(gè)軟件延時(shí),問(wèn)題就可以解決了。
中斷源掛接正確是沒(méi)問(wèn)題的。

6.問(wèn)
void TargetInit(void)
{
    OS_ENTER_CRITICAL();
    srand((uint32) TargetInit);
    VICInit();
    Timer0Init();
    OS_EXIT_CRITICAL();
}
在此單獨用srand()函數有什么作用(用了有什么好處,不用又會(huì )怎樣),一般srand()用于
給rand()設定種子(即srand給定rand運算式子的第一個(gè)值)。查了FAQ(P22)僅僅說(shuō)明了
seed的譯文。

答 2
你說(shuō)的沒(méi)有錯,他就是用來(lái)設置隨機數的種子。
每次編譯一次,void TargetInit(void)函數在Ram或者Flash中的地址都不一樣
(即種子也不一樣)。如果你在程序中不用隨機函數rand(),那么srand()
在這里對你來(lái)說(shuō)是沒(méi)有意義的,如果你要用rand(),那么每次編譯程序后你的rand()
產(chǎn)生的隨機數就不一樣。當然,你也可以自己種種子咯。

7.
在A(yíng)RM上移植操作系統有一點(diǎn)需要注意:建立任務(wù)的任務(wù),最好不要做復雜的工作。
頻繁的訪(fǎng)問(wèn)其他硬件或者做時(shí)序要求比較嚴的工作容易造成系統死機,希望大家多
多注意。我的做法是:將建立任務(wù)的任務(wù),閑置起來(lái),但是不能進(jìn)入死循環(huán)。方法
是:利用一個(gè)空郵箱,讓任務(wù)無(wú)限期的等待,這樣可以實(shí)現與其他任務(wù)的切換。


8.//定義與編譯器無(wú)關(guān)的數據類(lèi)型

typedef unsigned char BOOLEAN; //布爾變量

typedef unsigned char INT8U; // 無(wú)符號8位整型變量

typedef signed char INT8S; //有符號8位整型變量

typedef unsigned short INT16U; //無(wú)符號16位整型變量

typedef signed short INT16S; //有符號16位整型變量

typedef unsigned int INT32U; //無(wú)符號32位整型變量

typedef signed int INT32S; //有符號32位整型變量

typedef float FP32; //單精度浮點(diǎn)數(32位長(cháng)度)

typedef double FP64; //雙精度浮點(diǎn)數(64位長(cháng)度)

typedef INT32U OS_STK; //堆棧是32位寬度

注:這里為什么用typedef,因為如果用#define,那么代碼中的每一個(gè)相應的類(lèi)型都會(huì )被替代,
很有可能會(huì )出現問(wèn)題,畢竟他只是一個(gè)替代的關(guān)系,且編譯時(shí)間會(huì )增加,而用typedef則不會(huì ),
它就相當于我們C++里面的引用,一樣的思維,在這里面就是說(shuō)多了一個(gè)名稱(chēng)。還有要注意的是
我們怎么知道unsigned char 就是無(wú)符號8位整型變量,可以ARM公司里面下載ADS_CompilerGuide_D.PDF
文件,或者在你所裝的ADS1.2目錄里面有一個(gè)文件夾叫PDF,打開(kāi)它就可以找到,具體頁(yè)在259頁(yè)。

9>OS_CPU_a.s:

;定義系統模式堆棧的大小

SVC_STACK_LEGTH EQU 32


NoInt EQU 0x80


USR32Mode EQU 0x10

SVC32Mode EQU 0x13

SYS32Mode EQU 0x1f

IRQ32Mode EQU 0x12

FIQ32Mode EQU 0x11


;T_bit用于檢測進(jìn)入異常前cpu是否處于THUMB狀態(tài)

T_bit EQU 0x20


CODE32


AREA |subr|, CODE, READONLY


IMPORT OSTCBCur ;指向當前任務(wù)TCB的指針

IMPORT OSTCBHighRdy ;指向將要運行的任務(wù)TCB的指針

IMPORT OSPrioCur ;當前任務(wù)的優(yōu)先級

IMPORT OSPrioHighRdy ;將要運行的任務(wù)的優(yōu)先級

IMPORT OSTaskSwHook ;任務(wù)切換的鉤子函數

IMPORT OSRunning ;uC/OS-II運行標志


IMPORT OsEnterSum ;關(guān)中斷計數器(關(guān)中斷信號量)

IMPORT SWI_Exception ;軟中斷異常處理程序

EXPORT __OSStartHighRdy

EXPORT OSIntCtxSw ;中斷退出時(shí)的入口,參見(jiàn)startup.s中的IRQ_Handler

EXPORT SoftwareInterrupt ;軟中斷入口


;軟件中斷

//當CPU發(fā)現有軟中斷信號出現時(shí),CPU的PC馬上指到軟中斷服務(wù)地址處【見(jiàn)Startup.s】,然后通過(guò)跳轉到下面這段軟中斷處理程序,進(jìn)入后,首先要設置好管理模式下的堆棧,保存好用戶(hù)任務(wù)的幾個(gè)寄存器,其它寄存器系統會(huì )自動(dòng)保存,然后取出SWI號。

SoftwareInterrupt

LDR SP, StackSvc ; 重新設置堆棧指針

STMFD SP!, {R0-R3, R12, LR} //為什么只保存這幾個(gè)寄存器,見(jiàn)上面的解釋

MOV R1, SP ; R1指向參數存儲位置


MRS R3, SPSR //保存管理模式的狀態(tài)寄存器

TST R3, #T_bit ; 中斷前是否是Thumb狀態(tài)

LDRNEH R0, [LR,#-2] ; 是: 取得Thumb狀態(tài)SWI號

BICNE R0, R0, #0xff00

LDREQ R0, [LR,#-4] ; 否: 取得arm狀態(tài)SWI號

BICEQ R0, R0, #0xFF000000

; r0 = SWI號,R1指向參數存儲位置

CMP R0, #1

LDRLO PC, =OSIntCtxSw

LDREQ PC, =__OSStartHighRdy ; SWI 0x01為第一次任務(wù)切換


BL SWI_Exception

LDMFD SP!, {R0-R3, R12, PC}^

StackSvc DCD (SvcStackSpace + SVC_STACK_LEGTH * 4 - 4)


OSIntCtxSw

;下面為保存任務(wù)環(huán)境

LDR R2, [SP, #20] ;獲取PC//其實(shí)他就是管理模式下的LR寄存器的值,也就是用戶(hù)任務(wù)的PC值,為什么是SP+20,因為該棧是滿(mǎn)棧遞減,保存了R0-R3, R12, LR,所以L(fǎng)R的值為[SP+#20]。

LDR R12, [SP, #16] ;獲取R12

MRS R0, CPSR //用通用寄存器R0保存該管理模式下的CPSR


MSR CPSR_c, #(NoInt | SYS32Mode)//切換到系統模式

MOV R1, LR //把用戶(hù)的LR保存在通用寄存器R1中

STMFD SP!, {R1-R2} ;保存LR,PC//把系統模式的LR,PC壓入用戶(hù)任務(wù)的棧中

STMFD SP!, {R4-R12} ;保存R4-R12//把系統模式的R4-R12壓入用戶(hù)棧中


MSR CPSR_c, R0 //重新回到管理模式

LDMFD SP!, {R4-R7} ;獲取R0-R3//實(shí)際上把用戶(hù)的R0~R3放到管理模式下的R4-R7

ADD SP, SP, #8 ;出棧R12,PC//這兩個(gè)已經(jīng)保存了,所以SP要往上8個(gè)字節

MSR CPSR_c, #(NoInt | SYS32Mode//系統模式

STMFD SP!, {R4-R7} ;保存R0-R3//因為管理模式的R4-R11和系統模式的R4-R11是一樣的,保它保存在用戶(hù)任務(wù)的棧中

//接下來(lái)的我就不分析拉,因為你如果按照我上面的分析,應該不成問(wèn)題的,如果還未明白,請多看幾遍,如果有問(wèn)題,請留言我們一起來(lái)探討,謝謝合作!上面的分析除了紅色部分是周立功公司的注釋外,其余都是我的理解,如果有錯的,真心希望您能指出!謝謝!

LDR R1, =OsEnterSum ;獲取OsEnterSum

LDR R2, [R1]

STMFD SP!, {R2, R3} ;保存CPSR,OsEnterSum


;保存當前任務(wù)堆棧指針到當前任務(wù)的TCB

LDR R1, =OSTCBCur

LDR R1, [R1]

STR SP, [R1]


BL OSTaskSwHook ;調用鉤子函數

;OSPrioCur <= OSPrioHighRdy

LDR R4, =OSPrioCur

LDR R5, =OSPrioHighRdy

LDRB R6, [R5]

STRB R6, [R4]

;OSTCBCur <= OSTCBHighRdy

LDR R6, =OSTCBHighRdy

LDR R6, [R6]

LDR R4, =OSTCBCur

STR R6, [R4]

OSIntCtxSw_1

;獲取新任務(wù)堆棧指針

LDR R4, [R6]

ADD SP, R4, #68 ;17寄存器CPSR,OsEnterSum,R0-R12,LR,SP

LDR LR, [SP, #-8]

MSR CPSR_c, #(NoInt | SVC32Mode) ;進(jìn)入管理模式

MOV SP, R4 ;設置堆棧指針


LDMFD SP!, {R4, R5} ;CPSR,OsEnterSum

;恢復新任務(wù)的OsEnterSum

LDR R3, =OsEnterSum

STR R4, [R3]

MSR SPSR_cxsf, R5 ;恢復CPSR

LDMFD SP!, {R0-R12, LR, PC }^ ;運行新任務(wù)

__OSStartHighRdy

MSR CPSR_c, #(NoInt | SYS32Mode)

;告訴uC/OS-II自身已經(jīng)運行

LDR R4, =OSRunning

MOV R5, #1

STRB R5, [R4]


BL OSTaskSwHook ;調用鉤子函數


LDR R6, =OSTCBHighRdy

LDR R6, [R6]

B OSIntCtxSw_1


AREA SWIStacks, DATA, NOINIT,ALIGN=2

SvcStackSpace SPACE SVC_STACK_LEGTH * 4 ;管理模式堆??臻g


END
 

類(lèi)別:uc/os-ii | 添加到搜藏 | 瀏覽(180) | 評論 (0)  上一篇:模電學(xué)習筆記匯總    下一篇:uCos-II學(xué)習匯總(一) 相關(guān)文章:? 09年部分省市高考理科狀元學(xué)習經(jīng)...          ? English詞匯學(xué)習專(zhuān)貼分類(lèi)詞匯匯...
學(xué)習Fluent的經(jīng)驗匯總(轉摘的,個(gè)...          ? .net學(xué)習網(wǎng)站匯總
2010年?yáng)|南大學(xué)-301學(xué)習科學(xué)研究...          ? 精彩英語(yǔ)聽(tīng)力口語(yǔ)學(xué)習網(wǎng)站-網(wǎng)址...
樹(shù)狀數組學(xué)習系列2 之 OJ題目大...          ? 學(xué)習娛樂(lè )兩不誤 OPPO S39評測大...
DIV CSS網(wǎng)頁(yè)布局學(xué)習中容易出現...          ? 數據挖掘學(xué)習和研究的一些指導性...
更多>>
 最近讀者: 登錄后,您就出現在這里。 

嵌入式實(shí)時(shí)操作系統ucos ii的分析2009年03月18日 星期三 下午 05:23摘要:近年來(lái),在單片機系統中嵌入操作系統已經(jīng)成為人們越來(lái)越關(guān)心的一個(gè)話(huà)題。本文通過(guò)對一種源碼公開(kāi)的嵌入式實(shí)時(shí)操作系統ucos ii的分析,以51系列單片機為例,闡述了在單片機中使用該嵌入式操作系統的優(yōu)缺點(diǎn),以及在應用中應當注意的一些問(wèn)題。
關(guān)鍵詞:實(shí)時(shí)操作系統;ucos ii;單片機


引言
  早在20世紀60年代,就已經(jīng)有人開(kāi)始研究和開(kāi)發(fā)嵌入式操作系統。但直到最近,它才在國內被越來(lái)越多的提及,在通信、電子、自動(dòng)化等需要實(shí)時(shí)處理的領(lǐng)域所曰益顯現的重要性吸引了人們越來(lái)越多的注意力。但是,人們所談?wù)摰耐且恍┲?zhù)名的商業(yè)內核,諸如VxWorks、PSOS等。這些商業(yè)內核性能優(yōu)越,但價(jià)格昂貴,主要用于16位和32位處理器中,針對國內大部分用戶(hù)使用的51系列8位單片機,可以選擇免費的ucos ii。


ucos ii的特點(diǎn)
  1.ucos ii是由Labrosse先生編寫(xiě)的一個(gè)開(kāi)放式內核,最主要的特點(diǎn)就是源碼公開(kāi)。這一點(diǎn)對于用戶(hù)來(lái)說(shuō)可謂利弊各半,好處在于,一方面它是免費的,另一方面用戶(hù)可以根據自己的需要對它進(jìn)行修改。缺點(diǎn)在于它缺乏必要的支持,沒(méi)有功能強大的軟件包,用戶(hù)通常需要自己編寫(xiě)驅動(dòng)程序,特別是如果用戶(hù)使用的是不太常用的單片機,還必須自己編寫(xiě)移植程序。

  2.ucos ii是一個(gè)占先式的內核,即已經(jīng)準備就緒的高優(yōu)先級任務(wù)可以剝奪正在運行的低優(yōu)先級任務(wù)的CPU使用權。這個(gè)特點(diǎn)使得它的實(shí)時(shí)性比非占先式的內核要好。通常我們都是在中斷服務(wù)程序中使高優(yōu)先級任務(wù)進(jìn)入就緒態(tài)(例如發(fā)信號),這樣退出中斷服務(wù)程序后,將進(jìn)行任務(wù)切換,高優(yōu)先級任務(wù)將被執行。拿51單片機為例,比較一下就可以發(fā)現這樣做的好處。假如需要用中斷方式采集一批數據并進(jìn)行處理,在傳統的編程方法中不能在中斷服務(wù)程序中進(jìn)行復雜的數據處理,因為這會(huì )使得關(guān)中斷時(shí)間過(guò)長(cháng)。所以經(jīng)常采用的方法是置一標志位,然后退出中斷。由于主程序是循環(huán)執行的,所以它總有機會(huì )檢測到這一標志并轉到數據處理程序中去。但是因為無(wú)法確定發(fā)生中斷時(shí)程序到底執行到了什么地方,也就無(wú)法判斷要經(jīng)過(guò)多長(cháng)時(shí)間數據處理程序才會(huì )執行,中斷響應時(shí)間無(wú)法確定,系統的實(shí)時(shí)性不強。如果使用μC/OS-II的話(huà),只要把數據處理程序的優(yōu)先級設定得高一些,并在中斷服務(wù)程序中使它進(jìn)入就緒態(tài),中斷結束后數據處理程序就會(huì )被立即執行。這樣可以把中斷響應時(shí)間限制在一定的范圍內。對于一些對中斷響應時(shí)間有嚴格要求的系統,這是必不可少的。但應該指出的是如果數據處理程序簡(jiǎn)單,這樣做就未必合適。因為ucos ii要求在中斷服務(wù)程序末尾使用OSINTEXIT函數以判斷是否進(jìn)行任務(wù)切換,這需要花費一定的時(shí)間。

  3.ucos ii和大家所熟知的Linux等分時(shí)操作系統不同,它不支持時(shí)間片輪轉法。ucos ii是一個(gè)基于優(yōu)先級的實(shí)時(shí)操作系統,每個(gè)任務(wù)的優(yōu)先級必須不同,分析它的源碼會(huì )發(fā)現,ucos ii把任務(wù)的優(yōu)先級當做任務(wù)的標識來(lái)使用,如果優(yōu)先級相同,任務(wù)將無(wú)法區分。進(jìn)入就緒態(tài)的優(yōu)先級最高的任務(wù)首先得到CPU的使用權,只有等它交出CPU的使用權后,其他任務(wù)才可以被執行。所以它只能說(shuō)是多任務(wù),不能說(shuō)是多進(jìn)程,至少不是我們所熟悉的那種多進(jìn)程。顯而易見(jiàn),如果只考慮實(shí)時(shí)性,它當然比分時(shí)系統好,它可以保證重要任務(wù)總是優(yōu)先占有CPU。但是在系統中,重要任務(wù)畢竟是有限的,這就使得劃分其他任務(wù)的優(yōu)先權變成了一個(gè)讓人費神的問(wèn)題。另外,有些任務(wù)交替執行反而對用戶(hù)更有利。例如,用單片機控制兩小塊顯示屏時(shí),無(wú)論是編程者還是使用者肯定希望它們同時(shí)工作,而不是顯示完一塊顯示屏的信息以后再顯示另一塊顯示屏的信息。這時(shí)候,要是ucos ii即支持優(yōu)先級法又支持時(shí)間片輪轉法就更合適了。

  4.ucos ii對共享資源提供了保護機制。正如上文所提到的,ucos ii是一個(gè)支持多任務(wù)的操作系統。一個(gè)完整的程序可以劃分成幾個(gè)任務(wù),不同的任務(wù)執行不同的功能。這樣,一個(gè)任務(wù)就相當于模塊化設計中的一個(gè)子模塊。在任務(wù)中添加代碼時(shí),只要不是共享資源就不必擔心互相之間有影響。而對于共享資源(比如串口),ucos ii也提供了很好的解決辦法。一般情況下使用的是信號量的方法。簡(jiǎn)單地說(shuō),先創(chuàng )建一個(gè)信號量并對它進(jìn)行初始化。當一個(gè)任務(wù)需要使用一個(gè)共享資源時(shí),它必須先申請得到這個(gè)信號量,而一旦得到了此信號量,那就只有等使用完了該資源,信號量才會(huì )被釋放。在這個(gè)過(guò)程中即使有優(yōu)先權更高的任務(wù)進(jìn)入了就緒態(tài),因為無(wú)法得到此信號量,也不能使用該資源。這個(gè)特點(diǎn)的好處顯而易見(jiàn),例如當顯示屏正在顯示信息的時(shí)候,外部產(chǎn)生了一個(gè)中斷,而在中斷服務(wù)程序中需要顯示屏顯示其他信息。這樣,退出中斷服務(wù)程序后,原有的信息就可能被破壞了。而在μC/OS-II中采用信號量的方法時(shí),只有顯示屏把原有信息顯示完畢后才可以顯示新信息,從而可以避免這個(gè)現象。不過(guò),采用這種方法是以犧牲系統的實(shí)時(shí)性為代價(jià)的。如果顯示原有信息需要耗費大量時(shí)間,系統只好等待。從結果上看,等于延長(cháng)了中斷響應時(shí)間,這對于未顯示信息是報警信息的情況,無(wú)疑是致命的。發(fā)生這種情況,在μC/OS-II中稱(chēng)為優(yōu)先級反轉,就是高優(yōu)先級任務(wù)必須等待低優(yōu)先級任務(wù)的完成。在上述情況下,在兩個(gè)任務(wù)之間發(fā)生優(yōu)先級反轉是無(wú)法避免的。所以在使用ucos ii時(shí),必須對所開(kāi)發(fā)的系統了解清楚,才能決定對于某種共享資源是否使用信號量。


ucos ii在單片機使用中的一些特點(diǎn)
  1.在單片機系統中嵌入ucos ii將增強系統的可靠性,并使得調試程序變得簡(jiǎn)單。以往傳統的單片機開(kāi)發(fā)工作中經(jīng)常遇到程序跑飛或是陷入死循環(huán)??梢杂每撮T(mén)狗解決程序跑飛問(wèn)題,而對于后一種情況,尤其是其中牽扯到復雜數學(xué)計算的話(huà),只有設置斷點(diǎn),耗費大量時(shí)間來(lái)慢慢分析。如果在系統中嵌入 ucos ii的話(huà),事情就簡(jiǎn)單多了??梢园颜麄€(gè)程序分成許多任務(wù),每個(gè)任務(wù)相對獨立,然后在每個(gè)任務(wù)中設置超時(shí)函數,時(shí)間用完以后,任務(wù)必須交出 CPU的使用權。即使一個(gè)任務(wù)發(fā)生問(wèn)題,也不會(huì )影響其他任務(wù)的運行。這樣既提高了系統的可靠性,同時(shí)也使得調試程序變得容易。

  2.在單片機系統中嵌入ucos ii將增加系統的開(kāi)銷(xiāo)?,F在所使用的51單片機,一般是指87C51或者89C51,其片內都帶有一定的RAM和 ROM。對于一些簡(jiǎn)單的程序,如果采用傳統的編程方法,已經(jīng)不需要外擴存儲器了。如果在其中嵌入ucos ii的話(huà),在只需要使用任務(wù)調度、任務(wù)切換、信號量處理、延時(shí)或超時(shí)服務(wù)的情況下,也不需要外擴ROM了,但是外擴RAM是必須的。由于ucos ii是可裁減的操作系統,其所需要的RAM大小就取決于操作系統功能的多少。舉例來(lái)說(shuō),μC/OS-II允許用戶(hù)定義最大任務(wù)數。由于每建立一個(gè)任務(wù),都要產(chǎn)生一個(gè)與之相對應的數據結構TCB,該數據結構要占用很大一部分內存空間。所以在定義最大任務(wù)數時(shí),一定要考慮實(shí)際情況的需要。如果定得過(guò)大,勢必會(huì )造成不必要的浪費。嵌入ucos ii以后,總的RAM需求可以由如下表達式得出:

  RAM總需求=應用程序的RAM需求+內核數據區的RAM需求+(任務(wù)棧需求+最大中斷嵌套棧需求)·任務(wù)數
所幸的是,μC/OS-II可以對每個(gè)任務(wù)分別定義堆??臻g的大小,開(kāi)發(fā)人員可根據任務(wù)的實(shí)際需求來(lái)進(jìn)行??臻g的分配。但在RAM容量有限的情況下,還是應該注意一下對大型數組、數據結構和函數的使用,別忘了,函數的形參也是要推入堆棧的。

  3.ucos ii的移植也是一件需要值得注意的工作。如果沒(méi)有現成的移植實(shí)例的話(huà),就必須自己來(lái)編寫(xiě)移植代碼。雖然只需要改動(dòng)兩個(gè)文件,但仍需要對相應的微處理器比較熟悉才行,最好參照已有的移植實(shí)例。另外,即使有移植實(shí)例,在編程前最好也要閱讀一下,因為里面牽扯到堆棧操作。在編寫(xiě)中斷服務(wù)程序時(shí),把寄存器推入堆棧的順序必須與移植代碼中的順序相對應。

  4.和其他一些著(zhù)名的嵌入式操作系統不同,ucos ii在單片機系統中的啟動(dòng)過(guò)程比較簡(jiǎn)單,不像有些操作系統那樣,需要把內核編譯成一個(gè)映像文件寫(xiě)入ROM中,上電復位后,再從ROM中把文件加載到RAM中去,然后再運行應用程序。ucos ii的內核是和應用程序放在一起編譯成一個(gè)文件的,使用者只需要把這個(gè)文件轉換成HEX格式,寫(xiě)入ROM中就可以了,上電后,會(huì )像普通的單片機程序一樣運行。

結語(yǔ)
  由以上介紹可以看出,ucos ii具有免費、使用簡(jiǎn)單、可靠性高、實(shí)時(shí)性好等優(yōu)點(diǎn),但也有移植困難、缺乏必要的技術(shù)支持等缺點(diǎn),尤其不像商用嵌入式系統那樣得到廣泛使用和持續的研究更新。但開(kāi)放性又使得開(kāi)發(fā)人員可以自行裁減和添加所需的功能,在許多應用領(lǐng)域發(fā)揮著(zhù)獨特的作用。當然,是否在單片機系統中嵌入ucos ii應視所開(kāi)發(fā)的項目而定,對于一些簡(jiǎn)單的、低成本的項目來(lái)說(shuō),就沒(méi)必要使用嵌入式操作系統了。
 

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
uCOS II的移植步驟
uCOS II內核調度分析
μCOSII在Cortex-M3核ARM處理器上的移植
ucos II任務(wù)管理之一:掛起任務(wù)
ucos-II延時(shí)函數
一步一步教你使用uCOS
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久