<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

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

          作者: 時(shí)間:2016-11-26 來(lái)源:網(wǎng)絡(luò) 收藏
          前言:線程不是什么神秘的東西,當(dāng)你理解后你會(huì)有一種茅塞頓開的感覺(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中最高地址向下開始運(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://www.ex-cimer.com/article/201611/321597.htm

            第二節(jié):多程序運(yùn)行原理
            多線程的原理其實(shí)很簡(jiǎn)單,系統(tǒng)為每個(gè)線程提供一片內(nèi)存作為棧區(qū)。然后選取FLASH中一點(diǎn)作為線程代碼的起始地址,最后調(diào)轉(zhuǎn)到線程代碼的起始地址開始執(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ù)開始調(diào)度的第一步就是找到該任務(wù)的TCB,然后從TCB中找到棧頭地址,然后使用棧頭保存的數(shù)據(jù)復(fù)制到CPU寄存器上和CPSR上,最后跳轉(zhuǎn)到棧頭上上次運(yùn)行保存的地址處開始執(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)度工具就開始使用下面機(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ù)完成后打開鎖才能運(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)中斷,讀取后開中斷而已。

            第七節(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那一瞬間開始計(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)系密切,開發(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ò)多開緩存來(lái)彌補(bǔ),但是對(duì)于TCP,退出就需要至少等待下一個(gè)Tick,時(shí)間就顯得有些長(zhǎng)久了,這個(gè)機(jī)制其實(shí)我一直在考慮。 

            第九節(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ù)和開中斷函數(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)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();