新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > μC/OS-II的內存管理

        μC/OS-II的內存管理

        作者: 時間:2016-10-08 來源:網絡 收藏

        for(i=0;i(nblks-1);i++){

        *plink=(void*)pblk;

        plink=(void**)pblk;

        pblk=pblk+blksize;

        }

        *plink=(void*)0;

        OS_ENTER_CRITICAL();

        pmem->OSMemAddr=addr;(6)

        pmem->OSMemFreeList=addr;

        pmem->OSMemNFree=nblks;

        pmem->OSMemNBlks=nblks;

        pmem->OSMemBlkSize=blksize;

        OS_EXIT_CRITICAL();

        *err=OS_NO_ERR;

        return(pmem);(7)

        }

        圖F7.4是OSMemCreate()函數完成后,內存控制塊及對應的內存分區和分區內的內存塊之間的關系。在程序運行期間,經過多次的內存分配和釋放后,同一分區內的各內存塊之間的鏈接順序會發生很大的變化。

        分配一個內存塊,OSMemGet()應用程序可以調用OSMemGet()函數從已經建立的內存分區中申請一個內存塊。該函數的唯一參數是指向特定內存分區的指針,該指針在建立內存分區時,由OSMemCreate()函數返回。顯然,應用程序必須知道內存塊的大小,并且在使用時不能超過該容量。例如,如果一個內存分區內的內存塊為32字節,那么,應用程序最多只能使用該內存塊中的32字節。當應用程序不再使用這個內存塊后,必須及時把它釋放,重新放入相應的內存分區中[見7.03節,釋放一個內存塊,OSMemPut()]。

        圖F7.4OSMemCreate()——Figure7.4

        程序清單L7.4是OSMemGet()函數的源代碼。參數中的指針pmem指向用戶希望從其中分配內存塊的內存分區[L7.4(1)]。OSMemGet()首先檢查內存分區中是否有空閑的內存塊[L7.4(2)]。

        如果有,從空閑內存塊鏈表中刪除第一個內存塊[L7.4(3)],并對空閑內存塊鏈表作相應的修改[L7.4(4)]。這包括將鏈表頭指針后移一個元素和空閑內存塊數減1[L7.4(5)]。最后,返回指向被分配內存塊的指針[L7.4(6)]。

        程序清單L7.4OSMemGet()

        void*OSMemGet(OS_MEM*pmem,INT8U*err)(1)

        {

        void*pblk;

        OS_ENTER_CRITICAL();

        if(pmem->OSMemNFree>0){(2)

        pblk=pmem->OSMemFreeList;(3)

        pmem->OSMemFreeList=*(void**)pblk;(4)

        pmem->OSMemNFree--;(5)

        OS_EXIT_CRITICAL();

        *err=OS_NO_ERR;

        return(pblk);(6)

        }else{

        OS_EXIT_CRITICAL();

        *err=OS_MEM_NO_FREE_BLKS;

        return((void*)0);

        }

        }

        值得注意的是,用戶可以在中斷服務子程序中調用OSMemGet(),因為在暫時沒有內存塊可用的情況下,OSMemGet()不會等待,而是馬上返回NULL指針。

        釋放一個內存塊,OSMemPut()

        當用戶應用程序不再使用一個內存塊時,必須及時地把它釋放并放回到相應的內存分區中。這個操作由OSMemPut()函數完成。必須注意的是,OSMemPut()并不知道一個內存塊是屬于哪個內存分區的。例如,用戶任務從一個包含32字節內存塊的分區中分配了一個內存塊,用完后,把它返還給了一個包含120字節內存塊的內存分區。當用戶應用程序下一次申請120字節分區中的一個內存塊時,它會只得到32字節的可用空間,其它88字節屬于其它的任務,這就有可能使系統崩潰。

        程序清單L7.5是OSMemPut()函數的源代碼。它的第一個參數pmem是指向內存控制塊的指針,也即內存塊屬于的內存分區[L7.5(1)]。OSMemPut()首先檢查內存分區是否已滿[L7.5(2)]。如果已滿,說明系統在分配和釋放內存時出現了錯誤。如果未滿,要釋放的內存塊被插入到該分區的空閑內存塊鏈表中[L7.5(3)]。最后,將分區中空閑內存塊總數加1[L7.5(4)]。

        程序清單L7.5OSMemPut()

        INT8UOSMemPut(OS_MEM*pmem,void*pblk)(1)

        {

        OS_ENTER_CRITICAL();

        if(pmem->OSMemNFree>=pmem->OSMemNBlks){(2)

        OS_EXIT_CRITICAL();

        return(OS_MEM_FULL);

        }

        *(void**)pblk=pmem->OSMemFreeList;(3)

        pmem->OSMemFreeList=pblk;

        pmem->OSMemNFree++;(4)

        OS_EXIT_CRITICAL();

        return(OS_NO_ERR);

        }

        查詢一個內存分區的狀態,OSMemQuery()

        在μC/OS-II中,可以使用OSMemQuery()函數來查詢一個特定內存分區的有關消息。通過該函數可以知道特定內存分區中內存塊的大小、可用內存塊數和正在使用的內存塊數等信息。所有這些信息都放在一個叫OS_MEM_DATA的數據結構中,如程序清單L7.6。

        程序清單L7.6OS_MEM_DATA數據結構

        typedefstruct{

        void*OSAddr;/*指向內存分區首地址的指針*/

        void*OSFreeList;/*指向空閑內存塊鏈表首地址的指針*/

        INT32UOSBlkSize;/*每個內存塊所含的字節數*/

        INT32UOSNBlks;/*內存分區總的內存塊數*/

        INT32UOSNFree;/*空閑內存塊總數*/

        INT32UOSNUsed;/*正在使用的內存塊總數*/

        }OS_MEM_DATA;

        程序清單L7.7是OSMemQuery()函數的源代碼,它將指定內存分區的信息復制到OS_MEM_DATA定義的變量的對應域中。在此之前,代碼首先禁止了外部中斷,防止復制過程中某些變量值被修改[L7.7(1)]。由于正在使用的內存塊數是由 OS_MEM_DATA中的局部變量計算得到的,所以,可以放在(criticalsection中斷屏蔽)的外面。

        程序清單L7.7OSMemQuery()

        INT8UOSMemQuery(OS_MEM*pmem,OS_MEM_DATA*pdata)

        {

        OS_ENTER_CRITICAL();

        pdata->OSAddr=pmem->OSMemAddr;(1)

        pdata->OSFreeList=pmem->OSMemFreeList;

        pdata->OSBlkSize=pmem->OSMemBlkSize;

        pdata->OSNBlks=pmem->OSMemNBlks;

        pdata->OSNFree=pmem->OSMemNFree;

        OS_EXIT_CRITICAL();

        pdata->OSNUsed=pdata->OSNBlks-pdata->OSNFree;(2)

        return(OS_NO_ERR);

        }

        UsingMemoryPartitions



        關鍵詞:

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 长子县| 自贡市| 荔浦县| 西乌珠穆沁旗| 西吉县| 武强县| 吕梁市| 石门县| 弥勒县| 鄂尔多斯市| 大理市| 内丘县| 肥西县| 凭祥市| 邵武市| 柞水县| 湾仔区| 宣化县| 尚义县| 化德县| 靖边县| 曲周县| 哈巴河县| 铜梁县| 丁青县| 西华县| 揭西县| 西乌珠穆沁旗| 成武县| 闽清县| 叶城县| 东乡县| 财经| 泌阳县| 弥渡县| 长兴县| 犍为县| 永济市| 黑山县| 嘉祥县| 安远县|