新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > ucos-ii學習筆記——動態(tài)內存分配原理及使用

ucos-ii學習筆記——動態(tài)內存分配原理及使用

作者: 時間:2016-11-28 來源:網絡 收藏
Createdon:2012-10-8

Author:zhangbin

本文引用地址:http://www.2s4d.com/article/201611/322853.htm

學習筆記

forucos-iiPC

redesignedbyzhangbin

2012-10-8

versions:V-0.1

AllRightsReserved

#include"INCLUDES.h"

#defineTASK_STK_SIZE512

OS_STKStartTaskStk[TASK_STK_SIZE];

OS_STKMyTaskStk[TASK_STK_SIZE];

OS_MEM*IntBuffer;//定義內存控制塊指針,也即是指向內存分區(qū)的指針,創(chuàng)建一個

//內存分區(qū)時,返回值就是它OS_MEM內存控制塊類型的指針

INT8UIntPart[50][64];//劃分一個具有50個內存塊,每個內存塊長度是64個字節(jié)的內存分區(qū)

INT8U*IntBlkPtr;//定義內存塊指針無符號char型的

char*s1="Mytaskisrunning";

//char*s2="Youtaskisrunning";

//char*s3="Hertaskisrunning";

INT8Uerr;//存放錯誤信息

INT8Uy=0;//字符顯示位置

voidStartTask(void*data);

voidMyTask(void*data);

voidmain(void)

{

OSInit();

PC_DOSSaveReturn();

PC_VectSet(uCOS,OSCtxSw);

IntBuffer=OSMemCreate(IntPart,50,64,&err);//創(chuàng)建動態(tài)內存區(qū)函數參數為:IntPart為內存分區(qū)的起始地址

//前面已經定義了INT8UIntPart[50][64];表示內存分區(qū),用數組名表示起始地址

//第二個參數50表示分區(qū)中內存塊的數目,第三個參數64表示每個內存塊的字節(jié)數,最后&err為錯誤信息

//上面也定義了INT8Uerr;//存放錯誤信息

//函數的返回值為創(chuàng)建的內存分區(qū)的指針,為OS_MEM內存控制塊類型的指針,上面定義了

//OS_MEM*IntBuffer;//定義內存控制塊指針

OSTaskCreate(StartTask,(void*)0,&StartTaskStk[TASK_STK_SIZE-1],0);//創(chuàng)建起始任務

OSStart();

}

voidStartTask(void*pdata)

{

#ifOS_CRITICAL_METHOD==3

OS_CPU_SRcpu_sr;

#endif

INT16Skey;

pdata=pdata;

OS_ENTER_CRITICAL();

PC_VectSet(0x08,OSTickISR);

PC_SetTickRate(OS_TICKS_PER_SEC);

OS_EXIT_CRITICAL();

OSStatInit();

OSTaskCreate(MyTask,(void*)0,&MyTaskStk[TASK_STK_SIZE-1],3);//創(chuàng)建任務MyTask

for(;;)

{

//如果恩下ESC鍵,則退出UC/OS-II

if(PC_GetKey(&key)==TRUE)

{

if(key==0x1B)

{

PC_DOSReturn();

}

}

OSTimeDlyHMSM(0,0,3,0);

}

}

voidMyTask(void*pdata)

{

#ifOS_CRITICAL_METHOD==3

OS_CPU_SRcpu_sr;

#endif

pdata=pdata;

for(;;)

{

IntBlkPtr=OSMemGet(IntBuffer,&err);//請求內存塊從已經建立的內存分區(qū)中申請一個內存塊

//函數的參數為指向內存分區(qū)的指針,上面已經創(chuàng)建了內存分區(qū)IntBuffer

//函數的返回值為內存塊指針,上面定義了INT8U*IntBlkPtr;//定義內存塊指針無符號char型的

*IntBlkPtr=1;//在申請到的內存塊中存入1

//注意,應用程序在使用內存塊時,必須知道內存塊的大小,并且在使用時不能超過該容量

PC_DispStr(*IntBlkPtr*10,++y,s1,DISP_BGND_BLACK+DISP_FGND_WHITE);//顯示信息

*++IntBlkPtr=2;//???

PC_DispStr(*IntBlkPtr*10,++y,s1,DISP_BGND_BLACK+DISP_FGND_WHITE);

IntBlkPtr--;//???

OSMemPut(IntBuffer,IntBlkPtr);//釋放內存塊當應用程序不再使用這個內存塊后,必須及時把它釋放,

//重新放入相應的內存分區(qū)中

//函數中的第一個參數IntBuffer為內存塊所屬的內存分區(qū)的指針,IntBlkPtr為待釋放內存塊指針

//在使用函數OSMemPut()釋放內存塊時,一定要確保把該內存塊釋放到它原來所屬的內存分區(qū)中

//否則會引起災難性的后果

OSTimeDlyHMSM(0,0,1,0);//等待1s

}

}

//上面程序中*++IntBlkPtr=2;//???和IntBlkPtr--;//???的意思和作用還沒有搞清楚

#include"INCLUDES.h"

#defineTASK_STK_SIZE512

OS_STKStartTaskStk[TASK_STK_SIZE];

OS_STKMyTaskStk[TASK_STK_SIZE];

OS_STKYouTaskStk[TASK_STK_SIZE];

OS_STKHerTaskStk[TASK_STK_SIZE];

char*s;

char*s1="Mytask";

char*s2="Youtask";

char*s3="Hertask";

INT8Uerr;//錯誤信息

INT8Uy=0;//字符顯示位置

INT8UTimes=0;

OS_MEM*IntBuffer;//定義內存控制塊指針,創(chuàng)建一個內存分區(qū)時,返回值就是它

INT8UIntPart[8][6];//劃分一個具有8個內存塊,每個內存塊長度是6個字節(jié)的內存分區(qū)

INT8U*IntBlkPtr;//定義內存塊指針INT8U型的

OS_MEM_DATAMemInfo;//存放內存分區(qū)的狀態(tài)信息該數據結構存放查詢動態(tài)內存分區(qū)狀態(tài)函數OSMemQuery()

//查詢到的動態(tài)內存分區(qū)狀態(tài)的信息是一個SO_MEM_DATA型的數據結構OSMemQuery()函數查詢到的內存分區(qū)

//的有關信息就放在這個數據結構中

voidStartTask(void*data);

voidMyTask(void*data);

voidYouTask(void*data);

voidHerTask(void*data);

voidmain(void)

{

OSInit();

PC_DOSSaveReturn();

PC_VectSet(uCOS,OSCtxSw);

IntBuffer=OSMemCreate(IntPart,8,6,&err);//創(chuàng)建動態(tài)內存區(qū)

OSTaskCreate(StartTask,(void*)0,&StartTaskStk[TASK_STK_SIZE-1],0);//創(chuàng)建起始函數

OSStart();

}

voidStartTask(void*pdata)

{

#ifOS_CRITICAL_METHOD==3

OS_CPU_SRcpu_sr;

#endif

INT16Skey;

pdata=pdata;

OS_ENTER_CRITICAL();

PC_VectSet(0x08,OSTickISR);

PC_SetTickRate(OS_TICKS_PER_SEC);

OS_EXIT_CRITICAL();

OSStatInit();

OSTaskCreate(MyTask,(void*)0,&MyTaskStk[TASK_STK_SIZE-1],3);//創(chuàng)建任務

OSTaskCreate(YouTask,(void*)0,&YouTaskStk[TASK_STK_SIZE-1],4);

OSTaskCreate(HerTask,(void*)0,&HerTaskStk[TASK_STK_SIZE-1],5);

for(;;)

{

//如果恩下ESC鍵,則退出UC/OS-II

if(PC_GetKey(&key)==TRUE)

{

if(key==0x1B)

{

PC_DOSReturn();

}

}

OSTimeDlyHMSM(0,0,3,0);

}

}

voidMyTask(void*pdata)

{

#ifOS_CRITICAL_METHOD==3

OS_CPU_SRcpu_sr;

#endif

pdata=pdata;

for(;;)

{

PC_DispStr(10,++y,s1,DISP_BGND_BLACK+DISP_FGND_WHITE);//顯示信息

IntBlkPtr=OSMemGet(//請求內存塊

IntBuffer,//內存分區(qū)的指針

&err);//錯誤信息

OSMemQuery(//查詢內存控制塊信息

IntBuffer,//帶查詢內存控制塊指針

&MemInfo);

sprintf(s,"%0x",MemInfo.OSFreeList);//顯示頭指針把得到的空閑內存塊鏈表首地址的指針放到指針s所指的空間中

PC_DispStr(30,y,s,DISP_BGND_BLACK+DISP_FGND_WHITE);//把空閑內存塊鏈表首地址的指針顯示出來

sprintf(s,"%d",MemInfo.OSNUsed);//顯示已用的內存塊數目

PC_DispStr(40,y,s,DISP_BGND_BLACK+DISP_FGND_WHITE);

if(Times>=5)//運行六次后

{

OSMemPut(//釋放內存塊函數

IntBuffer,//內存塊所屬內存分區(qū)的指針

IntBlkPtr//待釋放內存塊指針

//此次釋放,只能釋放最后一次申請到的內存塊,前面因為IntBlkPtr被后面的給覆蓋掉了,所以釋放

//不了。

);

}

Times++;//運行次數加1

OSTimeDlyHMSM(0,0,1,0);//等待1s

}

}

voidYouTask(void*pdata)

{

#ifOS_CRITICAL_METHOD==3

OS_CPU_SRcpu_sr;

#endif

pdata=pdata;

for(;;)

{

PC_DispStr(10,++y,s2,DISP_BGND_BLACK+DISP_FGND_WHITE);

IntBlkPtr=OSMemGet(//請求內存塊

IntBuffer,//內存分區(qū)的指針

&err);//錯誤信息

OSMemQuery(//查詢內存控制塊信息

IntBuffer,//待查詢內存控制塊指針

&MemInfo);

sprintf(s,"%0x",MemInfo.OSFreeList);//顯示頭指針

PC_DispStr(30,y,s,DISP_BGND_BLACK+DISP_FGND_WHITE);

sprintf(s,"%d",MemInfo.OSNUsed);//顯示已用的內存塊數目

PC_DispStr(40,y,s,DISP_BGND_BLACK+DISP_FGND_WHITE);

OSMemPut(//釋放內存塊

IntBuffer,//內存塊所屬內存分區(qū)的指針

IntBlkPtr//待釋放內存塊指針

);

OSTimeDlyHMSM(0,0,2,0);//等待2s

}

}

voidHerTask(void*pdata)

{

#ifOS_CRITICAL_METHOD==3

OS_CPU_SRcpu_sr;

#endif

pdata=pdata;

for(;;)

{

PC_DispStr(10,++y,s3,DISP_BGND_BLACK+DISP_FGND_WHITE);

IntBlkPtr=OSMemGet(//請求內存塊

IntBuffer,//內存分區(qū)的指針

&err);//錯誤信息

OSMemQuery(//查詢內存控制塊信息

IntBuffer,//待查詢內存控制塊指針

&MemInfo);

sprintf(s,"%0x",MemInfo.OSFreeList);//顯示頭指針

PC_DispStr(30,y,s,DISP_BGND_BLACK+DISP_FGND_WHITE);

sprintf(s,"%d",MemInfo.OSNUsed);//顯示已用的內存塊數目

PC_DispStr(40,y,s,DISP_BGND_BLACK+DISP_FGND_WHITE);

OSMemPut(

IntBuffer,//內存塊所屬內存分區(qū)的指針

IntBlkPtr//待釋放內存塊指針

);

OSTimeDlyHMSM(0,0,1,0);//等待1s

}

}

//根據上面的分析可以很容易分析運行的現象了,從現象中可以看出,任務YouTask和HerTask申請了內存塊使用完了

//后就釋放了,而任務MyTask要一直到運行了6次后才釋放所申請的內存塊



評論


相關推薦

技術專區(qū)

關閉