新聞中心

ucos系統(tǒng)的精華提煉

作者: 時(shí)間:2016-11-26 來(lái)源:網(wǎng)絡(luò) 收藏
前言:線程不是什么神秘的東西,當(dāng)你理解后你會(huì)有一種茅塞頓開(kāi)的感覺(jué),其實(shí)它本身就很簡(jiǎn)單。

  第一節(jié):程序代碼運(yùn)行條件
  回想一下:
  1.一個(gè)鏈接過(guò)的程序由以下組成:代碼段,只讀數(shù)據(jù)段,可讀寫數(shù)據(jù)段。
  2.單片機(jī)上常使用的兩個(gè)資源:Flash(只讀),RAM(可讀寫)
  3.對(duì)于單片機(jī),我們習(xí)慣于一種模式,代碼段和只讀數(shù)據(jù)放在FLASH上,可讀寫數(shù)據(jù)放在RAM的起始地址,棧從RAM中最高地址向下開(kāi)始運(yùn)行。
  4.處理器從代碼段提取代碼,有三種方式,順序,跳轉(zhuǎn),調(diào)用。所有代碼段必須放在正確的位置上。
  5.處理器上數(shù)據(jù)段是通過(guò)地址來(lái)處理數(shù)據(jù),所以數(shù)據(jù)也必須放在正確的位置上。
  6.處理上臨時(shí)變量通過(guò)棧指針的向下偏移來(lái)提取變量,所以臨時(shí)變量的地址是不固定的。
  7.至于堆,那是C語(yǔ)言的技巧,不列入條件范圍內(nèi)。
  總結(jié):1.程序運(yùn)行需要代碼段,數(shù)據(jù)段和棧區(qū),而代碼段和數(shù)據(jù)段都必須放在編輯時(shí)對(duì)應(yīng)的地址上,只有棧區(qū)是可以設(shè)置的。那么在不使用臨時(shí)變量地址作為計(jì)算因數(shù)的情況下,就算改變棧頂?shù)奈恢茫绦虻倪\(yùn)行結(jié)果相同。

本文引用地址:http://butianyuan.cn/article/201611/321597.htm

  第二節(jié):多程序運(yùn)行原理
  多線程的原理其實(shí)很簡(jiǎn)單,系統(tǒng)為每個(gè)線程提供一片內(nèi)存作為棧區(qū)。然后選取FLASH中一點(diǎn)作為線程代碼的起始地址,最后調(diào)轉(zhuǎn)到線程代碼的起始地址開(kāi)始執(zhí)行。線程代碼可以隨意操作被分配的棧中的臨時(shí)變量而不會(huì)干擾到任何其他線程。除非你的臨時(shí)變量過(guò)大超過(guò)了分配的棧區(qū),這個(gè)就要你使用線程的經(jīng)驗(yàn)和感覺(jué)有關(guān)了,一般人都不會(huì)去仔細(xì)的計(jì)算使用多大臨時(shí)變量空間。線程也有個(gè)缺點(diǎn),就是線程在訪問(wèn)棧區(qū)以外的地址時(shí),包括數(shù)據(jù)區(qū),都會(huì)存在這樣一種可能,多個(gè)線程同時(shí)讀取和修改一個(gè)數(shù)據(jù)區(qū)中的數(shù)據(jù)時(shí),就會(huì)發(fā)生邊界現(xiàn)象,即多線程共管的數(shù)據(jù)。當(dāng)然同時(shí)是相對(duì)的,相對(duì)我們的感覺(jué),現(xiàn)在舉例說(shuō)明:A線程在從Addr地址處讀取出數(shù)據(jù)data后,恰巧被另外一線程B交接,而B線程也讀取了Addr地址處的data數(shù)據(jù)并修改了data的一位,然后...,當(dāng)再次運(yùn)行到A線程時(shí),A線程也修改了data并寫回到Addr地址處,這樣就存在了一個(gè)bug,B線程修改的位就被A線程的寫回覆蓋了。這點(diǎn)其實(shí)我們不擔(dān)心,因?yàn)橄到y(tǒng)一般都會(huì)提供很多避免這種現(xiàn)象的機(jī)制。
  如果你對(duì)多線程還是不了解的話,我估計(jì)你應(yīng)該就是對(duì)棧的認(rèn)識(shí)不夠準(zhǔn)確,可參考相關(guān)資料。


  第三節(jié):ucos系統(tǒng)介紹
  關(guān)于ucos的廣告部分我已經(jīng)屏蔽,我直接進(jìn)入正題,ucos是一個(gè)搶占式系統(tǒng),搶占式是指任務(wù)以搶占式的方式來(lái)運(yùn)行。把Ucos中的任務(wù)當(dāng)成進(jìn)程來(lái)理解是不恰當(dāng)?shù)?,這會(huì)影響我們對(duì)Windows進(jìn)程和Linux進(jìn)程的理解。Ucos中的任務(wù)只能相當(dāng)于線程的角色。Ucos內(nèi)容包括兩大部分,一個(gè)是系統(tǒng)部分:包括任務(wù)操作,時(shí)間操作,事件操作,內(nèi)存操作,這些不隨處理器的不同而不同。另外一個(gè)是接口部分:由匯編和C語(yǔ)言組成。提供任務(wù)切換函數(shù),定時(shí)器接口,CPU寄存器保存和讀取,及中斷處理等硬件相關(guān)操作函數(shù)。

  第四節(jié):創(chuàng)建ucos任務(wù)
  使用下面函數(shù)創(chuàng)建一個(gè)任務(wù):
  INT8UOSTaskCreate(void(*task)(void*p_arg),void*p_arg,OS_STK*ptos,INT8Uprio);

  創(chuàng)建函數(shù)設(shè)置任務(wù)函數(shù)(任務(wù)代碼首地址)和任務(wù)參數(shù),分配棧頂(ptos),和優(yōu)先級(jí)。Ptos的傳入做法在可讀寫數(shù)據(jù)區(qū)分配一個(gè)數(shù)據(jù)OS_STKStk【size】.然后把stk最高地址傳送給ptos。而stk數(shù)組就是默認(rèn)的分配給任務(wù)的棧區(qū),任務(wù)task運(yùn)行后使用stk存儲(chǔ)臨時(shí)變量。
  另外,stk還有個(gè)縮水就是系統(tǒng)需要從stk最高位減去一部分空間用來(lái)存儲(chǔ)寄存器信息,對(duì)于ARM是16個(gè)unsignedlong長(zhǎng)度,用來(lái)存儲(chǔ)該任務(wù)的r0-r15,CPSR.
  系統(tǒng)也會(huì)為每一個(gè)創(chuàng)建的任務(wù)分配一個(gè)任務(wù)控制塊(TCB)。TCB管理者任務(wù)的狀態(tài)和信息。另外還有一個(gè)TCB指針指向當(dāng)前正在運(yùn)行的任務(wù)。TCB控制著當(dāng)前進(jìn)程是否在運(yùn)行,如果不是在運(yùn)行是否是因?yàn)槭录枞?,?dāng)任務(wù)運(yùn)行時(shí),從什么地方找到上次運(yùn)行時(shí)保存的信息等等。
  對(duì)于每個(gè)創(chuàng)建后或運(yùn)行的任務(wù),都有兩個(gè)重要的部分,一個(gè)是TCB,一個(gè)是棧頭(棧區(qū)頂上保留的空間)。任務(wù)開(kāi)始調(diào)度的第一步就是找到該任務(wù)的TCB,然后從TCB中找到棧頭地址,然后使用棧頭保存的數(shù)據(jù)復(fù)制到CPU寄存器上和CPSR上,最后跳轉(zhuǎn)到棧頭上上次運(yùn)行保存的地址處開(kāi)始執(zhí)行。當(dāng)運(yùn)行的任務(wù)被調(diào)度時(shí),一樣是首先找到TCB所指向的棧頭,然后把CPU所有寄存器內(nèi)容和CPSR及當(dāng)前地址全部復(fù)制過(guò)去,再去找到另外一個(gè)被任務(wù)是應(yīng)該運(yùn)行的進(jìn)程,然后調(diào)度那個(gè)進(jìn)程。
  多任務(wù)的背景來(lái)自一點(diǎn),其實(shí)我們寫的大部分程序其實(shí)都有太多的延遲,對(duì)于沒(méi)有系統(tǒng)的程序,真正執(zhí)行效率(即不做無(wú)效循環(huán))的時(shí)間可能只占到處理器運(yùn)行的5%都不到。插入一句,如果你善于處理器編程的話,你看代碼不應(yīng)該只看到代碼的長(zhǎng)度,而是這段代碼運(yùn)行占用了多長(zhǎng)時(shí)間,和占用哪些資源和多大空間。系統(tǒng)的引入會(huì)讓我們重新認(rèn)識(shí)任務(wù)運(yùn)行時(shí)間,我們不希望程序長(zhǎng)時(shí)間做無(wú)效循環(huán),我們要利用這段時(shí)間去做其他的事,從而提高處理器的效率。所以不讓認(rèn)為系統(tǒng)會(huì)占用你的資源,系統(tǒng)會(huì)幫助你努力收回那95%以上效率。實(shí)際上收回全部資源是不可能的。這就看你如何使用架構(gòu),和你的任務(wù)級(jí)別了。每個(gè)項(xiàng)目可能都會(huì)不同。


  第四節(jié):搶占式調(diào)度(ucos的經(jīng)典)
  調(diào)度的意思就是從所有的任務(wù)隊(duì)列中找到最應(yīng)該運(yùn)行的任務(wù),然后運(yùn)行該任務(wù)。而調(diào)度的方式?jīng)Q定了系統(tǒng)的性能。Ucos的經(jīng)典就來(lái)自于它只用了一個(gè)數(shù)組采取了最單純的行為來(lái)進(jìn)行任務(wù)調(diào)度,同時(shí)也占用了最小的資源。所以,即使是8位處理器,很多人也會(huì)使用ucos系統(tǒng)。
  上面說(shuō)過(guò),ucos是搶占式調(diào)度。搶占式調(diào)度的概念就是,只有一個(gè)CPU,所有線程以搶占的方式占有CPU,然后運(yùn)行任務(wù),除非他主動(dòng)讓出,或他被其他任務(wù)搶占,否則,他會(huì)一直占用CPU.UCOS的搶占方式是比較優(yōu)先級(jí),每個(gè)任務(wù)都需要分配一個(gè)且唯一的優(yōu)先級(jí)。每次調(diào)度就是比較所有任務(wù)的優(yōu)先級(jí),找到優(yōu)先級(jí)最高的任務(wù)(這點(diǎn)其實(shí)不復(fù)雜,下段介紹),然后調(diào)度該任務(wù)并運(yùn)行,最高優(yōu)先級(jí)的任務(wù)需要自己主動(dòng)退出,否則,永遠(yuǎn)是這一個(gè)在運(yùn)行。當(dāng)這個(gè)任務(wù)運(yùn)行到延遲或等待事件時(shí),系統(tǒng)函數(shù)就會(huì)把這個(gè)任務(wù)從運(yùn)行隊(duì)列屏蔽掉,然后重新調(diào)度,再次搜索最高優(yōu)先級(jí)的任務(wù),這樣就找到了另外一個(gè)優(yōu)先級(jí)的任務(wù),然后運(yùn)行該任務(wù),到這個(gè)任務(wù)睡眠或等待事件時(shí),也會(huì)睡眠,然后再次調(diào)度,這時(shí),如果前面睡眠的最高優(yōu)先級(jí)的任務(wù)被喚醒,那么他將也會(huì)被放到優(yōu)先級(jí)隊(duì)列中。否則,再進(jìn)入下一個(gè)優(yōu)先級(jí)。
  關(guān)于任務(wù)的隊(duì)列,睡眠,運(yùn)行等概念都是一種理解概念,實(shí)際上ucos在這點(diǎn)是很簡(jiǎn)單的,也是很經(jīng)典的?,F(xiàn)在說(shuō)明下ucos的調(diào)度隊(duì)列。首先,我們需要知道下面?zhèn)€數(shù)組是干什么用的。
  INT8UconstOSUnMapTbl[256]={
  0,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
  5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
  6,0,1,0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
  };

  隨意給一個(gè)8位數(shù)data,這個(gè)數(shù)組的作用就是以查表的方式最快的速度找到data數(shù)據(jù)中從低位到高位中為第一個(gè)為1的數(shù)的位置(bit0為0)。即代替下面的函數(shù)的作用。使用方法:prto= OSUnMapTbl[data]
  for (i=0; i<8; i++)
  {
  If ( data & (1<  Break;
  }
  理解了那個(gè)數(shù)組后我們?cè)僖雰蓚€(gè)變量,
  OS_EXTINT8U OSRdyGrp;
  OS_EXTINT8U OSRdyTbl[OS_RDY_TBL_SIZE];
  每個(gè)任務(wù)的優(yōu)先級(jí)對(duì)應(yīng)于OSRdyTbl數(shù)組中的一個(gè)位。對(duì)應(yīng)關(guān)系是OSRdyTbl[prio/8]中的的第(prio%8)位,(prio/8)和(prio%8)使用任務(wù)控制塊TCB中的->OSTCBX和->OSTCBY表示。將OSRdyTbl數(shù)組中任務(wù)對(duì)應(yīng)的位置置一表示該任務(wù)準(zhǔn)備妥當(dāng),可參加搶占運(yùn)行, OSRdyTbl數(shù)組中任務(wù)對(duì)應(yīng)的位置為0表示該任務(wù)不存在,或該任務(wù)當(dāng)前被阻塞無(wú)法運(yùn)行。OSRdyGrp變量的作用是使用8個(gè)位依次對(duì)應(yīng)OSRdyTbl數(shù)組的前8個(gè)字節(jié),對(duì)第n位為0,代表 OSRdyTbl[n]全部為0,如果第n位為1,代表對(duì)應(yīng)的OSRdyTbl[n]至少有一個(gè)為1;
  然后調(diào)度工具就開(kāi)始使用下面機(jī)制來(lái)得到最高優(yōu)先級(jí)的任務(wù),即優(yōu)先級(jí)號(hào)最低的那個(gè)任務(wù)
  y = OSUnMapTbl[OSRdyGrp];
  OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);
  第一行代碼,通過(guò)查表找到OSRdyTbl數(shù)組中不為0的最低的一個(gè)數(shù)組。然后通過(guò)第二條代碼的OSUnMapTbl[OSRdyTbl[y]]);找到對(duì)應(yīng)的OSRdyTbl[y]中的最低的一個(gè)是1的位置。然后與(y << 3)相加,就得到了OSRdyTbl數(shù)組中從低到高的最低的為1的1位的位置。即最高優(yōu)先級(jí)任務(wù)的優(yōu)先級(jí),然后根據(jù)優(yōu)先級(jí)找到對(duì)應(yīng)的TCB進(jìn)行調(diào)度。
  每次調(diào)度時(shí)都是關(guān)閉了前一個(gè)進(jìn)程,因此ucos需要隊(duì)列中至少有一個(gè)可運(yùn)行的程序,為此UCOS制作了一個(gè)IDLE任務(wù),這個(gè)任務(wù)優(yōu)先級(jí)最低,在最高位,目的是所有任務(wù)進(jìn)程都睡眠時(shí),讓系統(tǒng)仍然有任務(wù)可調(diào),不至于崩潰。另外一個(gè)用作是統(tǒng)計(jì)CPU使用率。如果IDLE任務(wù)從沒(méi)調(diào)用過(guò),那就說(shuō)明的任務(wù)搶占度過(guò)高,優(yōu)先級(jí)高的任務(wù)有需要釋放一些空間讓優(yōu)先級(jí)低的任務(wù)運(yùn)行。

  第五節(jié):UCOS的實(shí)時(shí)性能
  按我理解,UCOS的實(shí)時(shí)性能是一種設(shè)想,讓所有的任務(wù)等處于等待信號(hào)階段,當(dāng)有中斷觸發(fā)時(shí),執(zhí)行中斷處理函數(shù),通過(guò)信號(hào)喚醒進(jìn)程,來(lái)完成任務(wù),完成后可以繼續(xù)睡眠。即使有多個(gè)中斷響應(yīng),只要中斷函數(shù)能及時(shí)響應(yīng),那么任務(wù)就排著隊(duì)來(lái)完成后續(xù)工作。這就是我的UCOS設(shè)想。
  所以,我們需要在兩個(gè)地方調(diào)度,一個(gè)是中斷,每次進(jìn)入中斷后關(guān)閉調(diào)度,但是允許信號(hào)喚醒任務(wù),然后在最后一個(gè)中斷嵌套完成后退出時(shí)進(jìn)行調(diào)度,檢測(cè)有沒(méi)有被喚醒的可執(zhí)行任務(wù)。另外一個(gè)就是定時(shí)中斷。每次tick完成后都進(jìn)行一次重調(diào)度。目的是當(dāng)?shù)蛢?yōu)先級(jí)執(zhí)行時(shí)沒(méi)有釋放資源,而高優(yōu)先級(jí)的任務(wù)已被喚醒。特別是IDLE任務(wù),除非你問(wèn)它要,否則他不會(huì)給你釋放資源的。

  第六節(jié):事件處理
  UCOS的事件主要包括SEMAPHORE,Mutex,和Mbox,Q,使用起來(lái)都很簡(jiǎn)單,一般都只適用三個(gè)函數(shù)創(chuàng)建,掛起等待,釋放。
  SEMAPHORE作用是當(dāng)某個(gè)任務(wù)運(yùn)行到必須得到某種資源時(shí)進(jìn)行掛起等待資源滿足,其他的任務(wù)或中斷發(fā)送SEMAPHORE表示資源已經(jīng)建立,你可以運(yùn)行了,如果是任務(wù)在發(fā)送SEMAPHORE時(shí)發(fā)現(xiàn)有任務(wù)因此被掛起,會(huì)喚醒并調(diào)度到該任務(wù)上執(zhí)行。
   Mutex有一種鎖的概念,當(dāng)?shù)玫揭粋€(gè)東西后,就立馬對(duì)其上鎖,其他的任務(wù)就只能等待該任務(wù)完成后打開(kāi)鎖才能運(yùn)行。這里有一個(gè)問(wèn)題就是一旦低優(yōu)先級(jí)的任務(wù)占用鎖后而高優(yōu)先級(jí)的就必須等待,而恰巧低優(yōu)先級(jí)的又被中優(yōu)先級(jí)的任務(wù)搶去執(zhí)行就會(huì)發(fā)生,高優(yōu)先級(jí)等低優(yōu)先級(jí),低優(yōu)先級(jí)等中優(yōu)先級(jí)的現(xiàn)象稱為優(yōu)先級(jí)翻轉(zhuǎn),所有Mutex有一個(gè)機(jī)制就是高優(yōu)先級(jí)想得到鎖的話就臨時(shí)提高低優(yōu)先級(jí)的優(yōu)先級(jí),使低優(yōu)先級(jí)盡快完成完成釋放鎖。
  郵箱MBox基本和SEMPAPHORE相同,只是SEMPAPHORE被當(dāng)做一個(gè)信號(hào)標(biāo)志來(lái)傳送,Mbox也可以被當(dāng)做SEMPAPHORE使用,但是會(huì)返回一個(gè)地址指針。
  Q消息隊(duì)列沒(méi)有用過(guò),看樣子是首先初始化一個(gè)數(shù)組,然后對(duì)數(shù)組使用FIFO的方式發(fā)送和接受信件。
  我一般還會(huì)再加上一些原子讀寫函數(shù)atom_read/wirte,主要針對(duì)邊界變量。其實(shí)很簡(jiǎn)單就是讀取前關(guān)中斷,讀取后開(kāi)中斷而已。

  第七節(jié):tick
   Tick是系統(tǒng)時(shí)間,他和定時(shí)的概念是不同的,如OSTimeDly (OS_TICKS_PER_SEC/100),實(shí)際上不是嚴(yán)格的延遲了OS_TICKS_PER_SEC/100秒,存在0-1/OS_TICKS_PER_SEC之間的誤差。Tick相當(dāng)于鐘表在不停的跑,秒表變化的瞬間被稱為tick,而我們是不可能從tick那一瞬間開(kāi)始計(jì)時(shí)的。所以這是一個(gè)概念是要分清的。
  
  第八節(jié):ucos的缺陷
  UCOS畢竟是一個(gè)小系統(tǒng),甚至可以在8位處理器上運(yùn)行,所以對(duì)于我們完成更復(fù)雜的任務(wù)和對(duì)系統(tǒng)效率更高的要求的話,它是存在一定的局限性的。如:
  1. 系統(tǒng)和應(yīng)用,中斷等關(guān)系密切,開(kāi)發(fā)人員需要熟悉系統(tǒng)特性,如。任務(wù)被創(chuàng)建后是不能直接退出的,必須使用API函數(shù)銷毀它。
  2. 調(diào)度方式過(guò)于單一,任務(wù)較少時(shí)可以達(dá)到平衡,任務(wù)較多時(shí),高優(yōu)先級(jí)的和低優(yōu)先級(jí)的運(yùn)行時(shí)間就會(huì)存在嚴(yán)重不平衡,并且會(huì)增加考慮調(diào)度問(wèn)題。
  3. 缺少異步讀取機(jī)制,如我想向串口發(fā)送數(shù)據(jù),而此時(shí)串口緩存已滿,我們就需要放棄資源調(diào)度其他任務(wù)。串口可以通過(guò)多開(kāi)緩存來(lái)彌補(bǔ),但是對(duì)于TCP,退出就需要至少等待下一個(gè)Tick,時(shí)間就顯得有些長(zhǎng)久了,這個(gè)機(jī)制其實(shí)我一直在考慮?!?/p>

  第九節(jié):寫后
  不喜歡LPC21xx和周立功的UCOS系統(tǒng)還有個(gè)原因就是LPC21xx的中斷機(jī)制看起來(lái)不錯(cuò),但實(shí)際上已經(jīng)能夠影響了我們代碼的發(fā)揮。也可能我自己懶惰的原因,沒(méi)有來(lái)及在LPC上改造ucos。周立功的中斷函數(shù)使用__irq聲明,這一點(diǎn)已經(jīng)和上面第五節(jié)所說(shuō)內(nèi)容想違背。
  兩外,周立功的關(guān)中斷函數(shù)和開(kāi)中斷函數(shù)使用swi中斷,我覺(jué)得是不如原版的較好。原版的函數(shù)是保存寄存器關(guān)中斷函數(shù)和恢復(fù)寄存器內(nèi)容。我本來(lái)考慮著周立功可能是考慮軟中斷可直接進(jìn)入中斷來(lái)避免中斷干擾,而原版的在關(guān)中斷函數(shù)中間仍有可能被中斷,如下
  MRSR0, CPSR;//復(fù)制CPSR,執(zhí)行后可能被中斷
  ORR R1, R0, #0xC0;//計(jì)算,也有可能被中斷
  MSRCPSR_c, R1;//這個(gè)代碼完成才真正關(guān)閉中斷
  但后來(lái)相通之后,覺(jué)得周立功是多此一舉,即使關(guān)中斷前被中斷也沒(méi)有什么的,因?yàn)橹袛嗪笏鼤?huì)原模原樣的返回給你。還是不喜歡周立功的UCOS和LPC
  后來(lái)在三星的s3c2440上也架構(gòu)了一個(gè)ucos,并且搭配了TFTP傳輸和TCP對(duì)話,感覺(jué)用起來(lái)要比LPC的好用很多。
  當(dāng)然,這只是個(gè)人用法和感覺(jué),每個(gè)芯片只要寫好了軟件應(yīng)該也是不錯(cuò)的。下面稍微提下個(gè)人用法,我一般如下定義main函數(shù)
  int main(void)
  {
   OSInit();
   OSTaskCreate(MainTask,(void *)1,&MainTaskStk[MainTaskStkLengh-1], MainTaskPrio);
   OSStart();
   return 0;
  }
  直接創(chuàng)建一個(gè)MainTask任務(wù),然后在MainTask中進(jìn)行初始化硬件和創(chuàng)建任務(wù),事件
  void MainTask(void *pdata)
  {
  u8 err,iLed=0;
  TargetInit();
  env_init();
  PrintMutux=OSMutexCreate(MutexPrintPrior,&err);
  OSTaskCreate (Consoler,(void *)0, &ConsolerStk[ConsolerStkLengh - 1], ConsolerPrio);
  OSTaskCreate(NetConsole,(void *)0,
  &NetConsoleStk[NetConsoleStkLengh - 1],
  NetConsolePrio);
  while(1){
  iLed++;
  Led_Display(iLed);
  OSTimeDly (400);
  rtcDisplayTime();
  }

  }



關(guān)鍵詞: ucos系統(tǒng)線

評(píng)論


技術(shù)專區(qū)

關(guān)閉