新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > ucos-ii学习笔记——动态内存分配原理及使用

ucos-ii学习笔记——动态内存分配原理及使用

作者:时间:2016-11-28来源:网络收藏
Createdon:2012-10-8

Author:zhangbin

本文引用地址:http://www.eepw.com.cn/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;//定义内存控制块指针,也即是指向内存分区的指针,创建一个

//内存分区时,返回值就是它OS_MEM内存控制块类型的指针

INT8UIntPart[50][64];//划分一个具有50个内存块,每个内存块长度是64个字节的内存分区

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);//创建动态内存函数参数为:IntPart为内存分区的起始地址

//前面已经定义了INT8UIntPart[50][64];表示内存分区,用数组名表示起始地址

//第二个参数50表示分区中内存块的数目,第三个参数64表示每个内存块的字节数,最后&err为错误信息

//上面也定义了INT8Uerr;//存放错误信息

//函数的返回值为创建的内存分区的指针,为OS_MEM内存控制块类型的指针,上面定义了

//OS_MEM*IntBuffer;//定义内存控制块指针

OSTaskCreate(StartTask,(void*)0,&StartTaskStk[TASK_STK_SIZE-1],0);//创建起始任务

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);//创建任务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);//请求内存块从已经建立的内存分区中申请一个内存块

//函数的参数为指向内存分区的指针,上面已经创建了内存分区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);//释放内存块当应用程序不再使用这个内存块后,必须及时把它释放,

//重新放入相应的内存分区中

//函数中的第一个参数IntBuffer为内存块所属的内存分区的指针,IntBlkPtr为待释放内存块指针

//在使用函数OSMemPut()释放内存块时,一定要确保把该内存块释放到它原来所属的内存分区中

//否则会引起灾难性的后果

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;//定义内存控制块指针,创建一个内存分区时,返回值就是它

INT8UIntPart[8][6];//划分一个具有8个内存块,每个内存块长度是6个字节的内存分区

INT8U*IntBlkPtr;//定义内存块指针INT8U型的

OS_MEM_DATAMemInfo;//存放内存分区的状态信息该数据结构存放查询动态内存分区状态函数OSMemQuery()

//查询到的动态内存分区状态的信息是一个SO_MEM_DATA型的数据结构OSMemQuery()函数查询到的内存分区

//的有关信息就放在这个数据结构中

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);//创建动态内存区

OSTaskCreate(StartTask,(void*)0,&StartTaskStk[TASK_STK_SIZE-1],0);//创建起始函数

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);//创建任务

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,//内存分区的指针

&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,//内存块所属内存分区的指针

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,//内存分区的指针

&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,//内存块所属内存分区的指针

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,//内存分区的指针

&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,//内存块所属内存分区的指针

IntBlkPtr//待释放内存块指针

);

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

}

}

//根据上面的分析可以很容易分析运行的现象了,从现象中可以看出,任务YouTask和HerTask申请了内存块使用完了

//后就释放了,而任务MyTask要一直到运行了6次后才释放所申请的内存块



评论


相关推荐

技术专区

关闭