新聞中心

        μC/OS-II的內(nèi)存管理

        作者: 時(shí)間:2016-10-08 來(lái)源:網(wǎng)絡(luò) 收藏

        圖F7.5是一個(gè)演示如何使用μC/OS-II中的動(dòng)態(tài)分配內(nèi)存功能,以及利用它進(jìn)行消息傳遞[見(jiàn)第6章]的例子。程序清單L7.8是這個(gè)例子中兩個(gè)任務(wù)的示意代碼,其中一些重要代碼的標(biāo)號(hào)和圖F7.5中括號(hào)內(nèi)用數(shù)字標(biāo)識(shí)的動(dòng)作是相對(duì)應(yīng)的。

        第一個(gè)任務(wù)讀取并檢查模擬輸入量的值(如氣壓、溫度、電壓等),如果其超過(guò)了一定的閾值,就向第二個(gè)任務(wù)發(fā)送一個(gè)消息。該消息中含有時(shí)間信息、出錯(cuò)的通道號(hào)和錯(cuò)誤代碼等可以想象的任何可能的信息。

        錯(cuò)誤處理程序是該例子的中心。任何任務(wù)、中斷服務(wù)子程序都可以向該任務(wù)發(fā)送出錯(cuò)消息。錯(cuò)誤處理程序則負(fù)責(zé)在顯示設(shè)備上顯示出錯(cuò)信息,在磁盤(pán)上登記出錯(cuò)記錄,或者啟動(dòng)另一個(gè)任務(wù)對(duì)錯(cuò)誤進(jìn)行糾正等。

        圖F7.5使用動(dòng)態(tài)內(nèi)存分配——Figure7.5

        程序清單L7.8內(nèi)存分配的例子——掃描模擬量的輸入和報(bào)告出錯(cuò)

        AnalogInputTask()

        {

        for(;;){

        for(所有的模擬量都有輸入){

        讀入模擬量輸入值;(1)

        if(模擬量超過(guò)閾值){

        得到一個(gè)內(nèi)存塊;(2)

        得到當(dāng)前系統(tǒng)時(shí)間(以時(shí)鐘節(jié)拍為單位);(3)

        將下列各項(xiàng)存入內(nèi)存塊:(4)

        系統(tǒng)時(shí)間(時(shí)間戳);

        超過(guò)閾值的通道號(hào);

        錯(cuò)誤代碼;

        錯(cuò)誤等級(jí);

        等.

        向錯(cuò)誤隊(duì)列發(fā)送錯(cuò)誤消息;(5)

        (一個(gè)指向包含上述各項(xiàng)的內(nèi)存塊的指針)

        }

        }

        延時(shí)任務(wù),直到要再次對(duì)模擬量進(jìn)行采樣時(shí)為止;

        }

        }

        ErrorHandlerTask()

        {

        for(;;){

        等待錯(cuò)誤隊(duì)列的消息;(6)

        (得到指向包含有關(guān)錯(cuò)誤數(shù)據(jù)的內(nèi)存塊的指針)

        讀入消息,并根據(jù)消息的內(nèi)容執(zhí)行相應(yīng)的操作;(7)

        將內(nèi)存塊放回到相應(yīng)的內(nèi)存分區(qū)中;(8)

        }

        }

        等待一個(gè)內(nèi)存塊

        有時(shí)候,在內(nèi)存分區(qū)暫時(shí)沒(méi)有可用的空閑內(nèi)存塊的情況下,讓一個(gè)申請(qǐng)內(nèi)存塊的任務(wù)等待也是有用的。但是,μC/OS-II本身在內(nèi)存管理上并不支持這項(xiàng)功能。如果確實(shí)需要,則可以通過(guò)為特定內(nèi)存分區(qū)增加信號(hào)量的方法,實(shí)現(xiàn)這種功能(見(jiàn)6.05節(jié),信號(hào)量)。應(yīng)用程序?yàn)榱松暾?qǐng)分配內(nèi)存塊,首先要得到一個(gè)相應(yīng)的信號(hào)量,然后才能調(diào)用OSMemGet()函數(shù)。整個(gè)過(guò)程見(jiàn)程序清單L7.9。

        程序代碼首先定義了程序中使用到的各個(gè)變量[L7.9(1)]。該例中,直接使用數(shù)字定義了各個(gè)變量的大小,實(shí)際應(yīng)用中,建議將這些數(shù)字定義成常數(shù)。在系統(tǒng)復(fù)位時(shí),μC/OS-II調(diào)用OSInit()進(jìn)行系統(tǒng)初始化[L7.9(2)],然后用內(nèi)存分區(qū)中總的內(nèi)存塊數(shù)來(lái)初始化一個(gè)信號(hào)量[L7.9(3)],緊接著建立內(nèi)存分區(qū)[L7.9(4)]和相應(yīng)的要訪問(wèn)該分區(qū)的任務(wù)[L7.9(5)]。當(dāng)然,到此為止,我們對(duì)如何增加其它的任務(wù)也已經(jīng)很清楚了。顯然,如果系統(tǒng)中只有一個(gè)任務(wù)使用動(dòng)態(tài)內(nèi)存塊,就沒(méi)有必要使用信號(hào)量了。這種情況不需要保證內(nèi)存資源的互斥。事實(shí)上,除非我們要實(shí)現(xiàn)多任務(wù)共享內(nèi)存,否則連內(nèi)存分區(qū)都不需要。多任務(wù)執(zhí)行從OSStart()開(kāi)始[L7.9(6)]。當(dāng)一個(gè)任務(wù)運(yùn)行時(shí),只有在信號(hào)量有效時(shí)[L7.9(7)],才有可能得到內(nèi)存塊[L7.9(8)]。一旦信號(hào)量有效了,就可以申請(qǐng)內(nèi)存塊并使用它,而沒(méi)有必要對(duì)OSSemPend()返回

        的錯(cuò)誤代碼進(jìn)行檢查。因?yàn)樵谶@里,只有當(dāng)一個(gè)內(nèi)存塊被其它任務(wù)釋放并放回到內(nèi)存分區(qū)后,

        μC/OS-II才會(huì)返回到該任務(wù)去執(zhí)行。同理,對(duì)OSMemGet()返回的錯(cuò)誤代碼也無(wú)需做進(jìn)一步的檢查(一個(gè)任務(wù)能得以繼續(xù)執(zhí)行,則內(nèi)存分區(qū)中至少有一個(gè)內(nèi)存塊是可用的)。當(dāng)一個(gè)任務(wù)不再使用某內(nèi)存塊時(shí),只需簡(jiǎn)單地將它釋放并返還到內(nèi)存分區(qū)[L7.9(9)],并發(fā)送該信號(hào)量[L7.9(10)]。

        程序清單L7.9等待從一個(gè)內(nèi)存分區(qū)中分配內(nèi)存塊

        OS_EVENT*SemaphorePtr;(1)

        OS_MEM*PartitionPtr;

        INT8UPartition[100][32];

        OS_STKTaskStk[1000];

        voidmain(void)

        {

        INT8Uerr;

        OSInit();(2)

        .

        .

        SemaphorePtr=OSSemCreate(100);(3)

        PartitionPtr=OSMemCreate(Partition,100,32,err);(4)

        .

        OSTaskCreate(Task,(void*)0,TaskStk[999],err);(5)

        .

        OSStart();(6)

        }

        voidTask(void*pdata)

        {

        INT8Uerr;

        INT8U*pblock;

        for(;;){

        OSSemPend(SemaphorePtr,0,err);(7)

        pblock=OSMemGet(PartitionPtr,err);(8)

        .

        ./*使用內(nèi)存塊*/

        .

        OSMemPut(PartitionPtr,pblock);(9)

        OSSemPost(SemaphorePtr);(10)

        }

        }


        上一頁(yè) 1 2 3 下一頁(yè)

        關(guān)鍵詞:

        評(píng)論


        相關(guān)推薦

        技術(shù)專(zhuān)區(qū)

        關(guān)閉
        主站蜘蛛池模板: 北海市| 井研县| 克拉玛依市| 和静县| 洪湖市| 巴彦县| 乐陵市| 德格县| 买车| 建宁县| 万载县| 颍上县| 阿鲁科尔沁旗| 桓台县| 都昌县| 亳州市| 顺义区| 疏勒县| 康定县| 石狮市| 沿河| 赤城县| 泸定县| 大庆市| 叶城县| 望江县| 淮南市| 三江| 绥宁县| 吴旗县| 新乐市| 扶沟县| 泾阳县| 扎兰屯市| 双桥区| 民乐县| 北辰区| 扎鲁特旗| 铁岭县| 蒙城县| 盘山县|