ucos內(nèi)存的動(dòng)態(tài)分配_第1頁
ucos內(nèi)存的動(dòng)態(tài)分配_第2頁
ucos內(nèi)存的動(dòng)態(tài)分配_第3頁
ucos內(nèi)存的動(dòng)態(tài)分配_第4頁
ucos內(nèi)存的動(dòng)態(tài)分配_第5頁
已閱讀5頁,還剩10頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、13 Sept. 2008Confidential內(nèi)存的動(dòng)態(tài)分配內(nèi)存的動(dòng)態(tài)分配內(nèi)存的動(dòng)態(tài)分配內(nèi)存的動(dòng)態(tài)分配目標(biāo):本章旨在介紹內(nèi)存的數(shù)據(jù)結(jié)構(gòu)及操作,通過本章的學(xué)習(xí),應(yīng)該掌握如下知識: uC/OS-II對內(nèi)存的分區(qū)及分塊 描述內(nèi)存塊的數(shù)據(jù)結(jié)構(gòu)-內(nèi)存控制塊 內(nèi)存控制塊與內(nèi)存分區(qū)之間的關(guān)系 對內(nèi)存的操作1 1 內(nèi)存控制塊內(nèi)存控制塊p uC/OS-II對內(nèi)存進(jìn)行兩級管理:把連續(xù)內(nèi)存分成若干個(gè)分區(qū),每個(gè)分區(qū)又分成若干個(gè)大小相等的內(nèi)存塊來進(jìn)行管理。p 操作系統(tǒng)以分區(qū)為單位來管理動(dòng)態(tài)內(nèi)存,而任務(wù)以內(nèi)存塊為單位來獲得和釋放動(dòng)態(tài)內(nèi)存。p 內(nèi)存分區(qū)及內(nèi)存塊的使用情況由內(nèi)存控制塊來記錄。p 應(yīng)用程序在運(yùn)行中為了某種特

2、殊需要,經(jīng)常需要臨時(shí)獲得一些內(nèi)存空間。因此作為比較完善的操作系統(tǒng),必須具有動(dòng)態(tài)分配內(nèi)存的能力。p 能否合理、有效的對內(nèi)存進(jìn)行分配和管理,是衡量一個(gè)操作系統(tǒng)品質(zhì)的指標(biāo)之一。特別對于實(shí)時(shí)操作系統(tǒng),應(yīng)該保證系統(tǒng)在動(dòng)態(tài)分配內(nèi)存時(shí),它的執(zhí)行時(shí)間必須是可確定的。uC/OS-II改進(jìn)了ANSI C用來動(dòng)態(tài)分配和釋放內(nèi)存的函數(shù)malloc()和free(),使他們可以對大小固定的內(nèi)存進(jìn)行操作,從而使函數(shù)malloc()和free()執(zhí)行時(shí)間成為可確定的,滿足了實(shí)時(shí)操作系統(tǒng)的要求。在ANSI C中可以用malloc()和free()兩個(gè)函數(shù)動(dòng)態(tài)地分配內(nèi)存和釋放內(nèi)存。但是,在嵌入式實(shí)時(shí)操作系統(tǒng)中,多次這樣做會把原

3、來很大的一塊連續(xù)內(nèi)存區(qū)域,逐漸地分割成許多非常小而且彼此又不相鄰的內(nèi)存區(qū)域,也就是內(nèi)存碎片。由于這些碎片的大量存在,使得程序到后來連非常小的內(nèi)存也分配不到1.1 可動(dòng)態(tài)分配內(nèi)存的劃分 在內(nèi)存中劃分一個(gè)內(nèi)存分區(qū)與內(nèi)存塊的方法:INT16U IntMemBuf510;M 注意:上面這個(gè)定義只是在內(nèi)存中劃分出了分區(qū)及內(nèi)存塊的區(qū)域,還不是一個(gè)真正的可以動(dòng)態(tài)分配的內(nèi)存區(qū)! 只有當(dāng)把內(nèi)存控制塊與分區(qū)關(guān)聯(lián)起來之后,系統(tǒng)才能對其進(jìn)行相應(yīng)的管理和控制。它才是一個(gè)真正的動(dòng)態(tài)內(nèi)存區(qū)。內(nèi)存塊1內(nèi)存塊2內(nèi)存塊3 內(nèi)存塊5一個(gè)內(nèi)存分區(qū)圖1 內(nèi)存控制塊與內(nèi)存分區(qū)和內(nèi)存塊的關(guān)系1-沒有控制塊時(shí)的分區(qū)內(nèi)存uC/OS-II要求同

4、一個(gè)分區(qū)中內(nèi)存塊的字節(jié)數(shù)必須相等,而且每個(gè)分區(qū)與該分區(qū)內(nèi)存塊的數(shù)據(jù)類型必須相同。1.2 內(nèi)存控制塊OS_MEM的結(jié)構(gòu)4 內(nèi)存控制塊的結(jié)構(gòu):typedef structvoid *OSMemAddr;/ 內(nèi)存分區(qū)的指針(指向分區(qū)的起始地址)void *OSMemFreeList;/ 內(nèi)存控制塊鏈表的指針I(yè)NT32U OSMemBlkSize;/ 內(nèi)存塊的長度INT32U OSMemNBlks;/ 分區(qū)內(nèi)內(nèi)存塊的數(shù)目INT32U OSMemNFree;/ 分區(qū)內(nèi)當(dāng)前可分配的內(nèi)存塊數(shù)目OS_MEM;下一個(gè)內(nèi)存塊的指針內(nèi)存塊1下一個(gè)內(nèi)存塊的指針內(nèi)存塊2下一個(gè)內(nèi)存塊的指針內(nèi)存塊n內(nèi)存內(nèi)存分區(qū)OSMemA

5、ddrOSMemFreeListOSMemBlkSizeOSMemNBlksOSMemNFree內(nèi)存控制塊OS_MEM0圖2 內(nèi)存控制塊與內(nèi)存分區(qū)和內(nèi)存塊的關(guān)系2-有控制塊時(shí)的分區(qū)從圖中可知,內(nèi)存控制塊的內(nèi)存分區(qū)指針OSMemAddr指向了內(nèi)存分區(qū),內(nèi)存分區(qū)中的各個(gè)內(nèi)存塊又組成了一個(gè)單向鏈表,內(nèi)存控制塊的鏈表指針OSMemFreeList就指向了這個(gè)單向鏈表的頭。1.3 空內(nèi)存控制塊鏈表OSMemAddrOSMemFreeListOSMemBlkSizeOSMemNBlksOSMemNFreeOSMemAddrOSMemFreeListOSMemBlkSizeOSMemNBlksOSMemNF

6、reeOSMemAddrOSMemFreeListOSMemBlkSizeOSMemNBlksOSMemNFree0共OS_MAX_MEM_PART個(gè)內(nèi)存分區(qū)OSMemFreeList圖3 空內(nèi)存控制塊鏈表q uC/OS-II初始化時(shí),會調(diào)用內(nèi)存初始化函數(shù)OS_MemInit()定義并初始化一個(gè)空內(nèi)存控制塊鏈表。q 每當(dāng)應(yīng)用程序需要?jiǎng)?chuàng)建一個(gè)內(nèi)存分區(qū)時(shí),系統(tǒng)就會從空內(nèi)存控制塊鏈表中摘取一個(gè)控制塊,而把鏈表的頭指針OSMemFreeList指向下一個(gè)空內(nèi)存控制塊;而每當(dāng)應(yīng)用程序釋放一個(gè)內(nèi)存分區(qū)時(shí),則會把該分區(qū)對應(yīng)的內(nèi)存控制塊歸還給空內(nèi)存控制塊鏈表。在OS-CFG.H中定義的常數(shù)2 2 動(dòng)態(tài)內(nèi)存的管

7、理動(dòng)態(tài)內(nèi)存的管理 創(chuàng)建動(dòng)態(tài)內(nèi)存分區(qū)OS_MEM *OSMemCreate(void *addr,/ 內(nèi)存分區(qū)的起始地址INT32U nblks,/ 分區(qū)中內(nèi)存塊的數(shù)目INT32U blksize,/ 每個(gè)內(nèi)存塊的字節(jié)數(shù)INT8U *err/ 錯(cuò)誤信息 );進(jìn)入 Addr != NULL?yesno*err=OS_MEM_INVALID_ADDR 返回空指針NULL nblks 1?yesno*err=OS_MEM_INVALID_BLKS 返回空指針NULL blksize = sizeof(void*)?yesno*err=OS_MEM_INVALID_SIZE 返回空指針NULL OSMe

8、mFreeList!= NULL?yesno*err=OS_MEM_INVALID_PART 返回空指針NULL 自空內(nèi)存控制塊鏈表 取一個(gè)空內(nèi)存控制塊 將分區(qū)中的所有內(nèi)存 塊鏈接為單向鏈表 在內(nèi)存控制塊中 填寫剛建立分區(qū)的信息 返回內(nèi)存控制塊指針pmem返回圖4 函數(shù)OSMemCreate()流程圖分區(qū)的內(nèi)存塊至少有2塊每個(gè)內(nèi)存塊的空間得至少能存放一個(gè)指針例1建立一個(gè)含有50個(gè)內(nèi)存塊并且每塊的長度為64字節(jié)的內(nèi)存分區(qū)。試寫出主要代碼。OS_MEM*CommTxBuffer;/ 定義內(nèi)存分區(qū)指針I(yè)NT8UCommTxPart5064;/ 定義分區(qū)和內(nèi)存塊INT8Uerr;void main(v

9、oid)INT8Uerr;OsInit();CommTxBuffer = OSMemCreate(CommTxPart,/ 內(nèi)存分區(qū)的首地址50,/ 分區(qū)內(nèi)內(nèi)存塊的數(shù)目64,/ 每個(gè)內(nèi)存塊的長度*err );OSStart(); 請求獲得一個(gè)內(nèi)存塊void * OSMemGet(OS_MEM *pmem,/ 內(nèi)存分區(qū)的指針I(yè)NT8U *err/ 錯(cuò)誤信息 );2 動(dòng)態(tài)內(nèi)存的管理(續(xù))進(jìn)入 pmem != NULL?yesno*err=OS_MEM_INVALID_PMEM 返回空指針NULL pmem-OSNMemFree0?yesno*err=OS_MEM_NO_FREE_BLKS 返回空指

10、針NULLPblk=pmem-OSMemFreeList 調(diào)整區(qū)內(nèi)的內(nèi)存塊鏈表 pmem-OSMemNFree- *err=OS_NO_ERR 返回分配給應(yīng)用程序 的內(nèi)存塊指針pblk圖5 函數(shù)OSSemGet()流程圖內(nèi)存分區(qū)尚存在未被分配的內(nèi)存塊將內(nèi)存塊鏈表的第一個(gè)塊的指針OSMemFrereList賦給了指針pblk使指針OSMemFrereList指向新的鏈表頭例2在例1的基礎(chǔ)上寫出任務(wù)MyTask請求一個(gè)內(nèi)存塊的代碼。OS_MEM*CommTxBuffer;/ 定義內(nèi)存分區(qū)指針I(yè)NT8UCommTxPart5064;/ 定義分區(qū)和內(nèi)存塊INT8Uerr;INT8U*BlkPtr;/

11、定義內(nèi)存塊指針void main(void)INT8Uerr;OsInit();CommTxBuffer = OSMemCreate(CommTxPart,50,64,*err);OSStart();void MyTask( (void *)pdata )for(;)BlkPtr = OSMemGet(CommTxBuffer,&err); 需要注意的是:應(yīng)用程序在調(diào)用函數(shù)OSMemGet()時(shí),應(yīng)該事先知道該分區(qū)中內(nèi)存塊的大小,并且在使用該內(nèi)存塊時(shí)不能超其長度,否則會引起災(zāi)難性的后果。當(dāng)應(yīng)用程序不再需要該內(nèi)存塊時(shí),必須及時(shí)將其釋放。 釋放一個(gè)內(nèi)存塊INT8U OSMemPut(OS_MEM

12、*pmem,/ 內(nèi)存所屬內(nèi)存分區(qū)的指針void *pblk/ 待釋放內(nèi)存塊的指針 );2 動(dòng)態(tài)內(nèi)存的管理(續(xù))進(jìn)入 pmem != NULL?yesno返回OS_MEM_INVALID_PMEM pblk != NULL?yesno返回OS_MEM_INVALID_PBLK鏈表頭指針OSMemFreeList 指向釋放的內(nèi)存塊Pmem-OSMemNFree+ 返回OS_NO_ERR圖6 函數(shù)OSSemPut()流程圖需要注意的是,在調(diào)用函數(shù)OSMemPut()時(shí),一定要確保把該內(nèi)存塊釋放到它原來所屬的內(nèi)存分區(qū)中,否則會引起災(zāi)難性后果。對例2中任務(wù)MyTask使用的內(nèi)存塊進(jìn)行釋放 查詢一個(gè)內(nèi)存分

13、區(qū)的狀態(tài)INT8U OSMemQuery( OS_MEM *pmem,/ 待查詢的內(nèi)存控制塊的指針 OS_MEM_DATA *pdata/ 存放分區(qū)狀態(tài)信息的結(jié)構(gòu)的指針 );2 動(dòng)態(tài)內(nèi)存的管理(續(xù))typedef struct void *OSAddr; / 內(nèi)存分區(qū)的指針 void *OSFreeList; / 分區(qū)內(nèi)內(nèi)存塊鏈表的頭指針 INT32U OSBlkSize; / 內(nèi)存塊的長度 INT32U OSNBlks; / 分區(qū)內(nèi)內(nèi)存塊的數(shù)目 INT32U OSNFree; / 分區(qū)內(nèi)空閑內(nèi)存塊的數(shù)目 INT32U OSNUsed; / 已被分配的內(nèi)存塊的數(shù)目 OS_MEM_DATA;OS_MEM_DATA結(jié)構(gòu)如下:例3 設(shè)計(jì)一個(gè)含有3個(gè)任務(wù)的應(yīng)用程序,這3個(gè)任務(wù)分別是MyTask、YouTask和HerTask。在應(yīng)用程序中創(chuàng)建一個(gè)動(dòng)態(tài)內(nèi)存分區(qū),該分區(qū)有8個(gè)內(nèi)存塊,每個(gè)內(nèi)存塊的長度為6個(gè)字節(jié)。應(yīng)用程序的任務(wù)YouTask和HerTask都在任務(wù)運(yùn)行后請求一個(gè)內(nèi)存塊,隨后就釋放它。任務(wù)MyTask也在任務(wù)運(yùn)行后請求一個(gè)內(nèi)存塊,但是要在任務(wù)MyTask運(yùn)行6次后,才釋放它所申請的內(nèi)存塊。 為了了解內(nèi)存分區(qū)變化的情況,編寫代碼來觀察分區(qū)頭指針和已被使用內(nèi)存塊的個(gè)數(shù)。練習(xí)1 設(shè)計(jì)一個(gè)有兩個(gè)任務(wù)的應(yīng)用程序,其中一個(gè)任務(wù)用來進(jìn)行兩個(gè)隨機(jī)數(shù)的加法運(yùn)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論