Created
on:
2012-10-8
Author: zhang bin
学习笔记
for ucos-ii PC
redesigned by zhang bin
2012-10-8
versions:V-0.1
All Rights Reserved
#include "INCLUDES.h"
#define TASK_STK_SIZE 512
OS_STK StartTaskStk[TASK_STK_SIZE];
OS_STK MyTaskStk[TASK_STK_SIZE];
OS_MEM *IntBuffer; //定义内存控制块指针,也即是指向内存分区的指针,创建一个
//内存分区时,返回值就是它 OS_MEM 内存控制块类型的指针
INT8U IntPart[50][64]; //划分一个具有50个内存块,每个内存块长度是64个字节的内存分区
INT8U *IntBlkPtr; //定义内存块指针 无符号char型的
char *s1= "Mytask is running";
//char *s2= "Youtask is running";
//char *s3= "Hertask is running";
INT8U err; //存放错误信息
INT8U y=0; //字符显示位置
void StartTask(void *data);
void MyTask(void *data);
void main (void)
{
OSInit();
PC_DOSSaveReturn();
PC_VectSet(uCOS, OSCtxSw);
IntBuffer=OSMemCreate(IntPart,50,64,&err); //创建动态内存区 函数参数为:IntPart为内存分区的起始地址
//前面已经定义了INT8U IntPart[50][64];表示内存分区,用数组名表示起始地址
//第二个参数50表示分区中内存块的数目,第三个参数64表示每个内存块的字节数,最后&err为错误信息
//上面也定义了INT8U err; //存放错误信息
//函数的返回值为创建的内存分区的指针,为OS_MEM 内存控制块类型的指针,上面定义了
//OS_MEM *IntBuffer; //定义内存控制块指针
OSTaskCreate(StartTask, (void *)0, &StartTaskStk[TASK_STK_SIZE - 1], 0); //创建起始任务
OSStart();
}
void StartTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
INT16S key;
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);
}
}
void MyTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_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"
#define TASK_STK_SIZE 512
OS_STK StartTaskStk[TASK_STK_SIZE];
OS_STK MyTaskStk[TASK_STK_SIZE];
OS_STK YouTaskStk[TASK_STK_SIZE];
OS_STK HerTaskStk[TASK_STK_SIZE];
char *s;
char *s1= "Mytask ";
char *s2= "Youtask ";
char *s3= "Hertask ";
INT8U err; //错误信息
INT8U y=0; //字符显示位置
INT8U Times=0;
OS_MEM *IntBuffer; //定义内存控制块指针,创建一个内存分区时,返回值就是它
INT8U IntPart[8][6]; //划分一个具有8个内存块,每个内存块长度是6个字节的内存分区
INT8U *IntBlkPtr; //定义内存块指针 INT8U型的
OS_MEM_DATA MemInfo; //存放内存分区的状态信息 该数据结构存放查询动态内存分区状态函数OSMemQuery()
//查询到的动态内存分区状态的信息 是一个SO_MEM_DATA型的数据结构 OSMemQuery()函数查询到的内存分区
//的有关信息就放在这个数据结构中
void StartTask(void *data);
void MyTask(void *data);
void YouTask(void *data);
void HerTask(void *data);
void main (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();
}
void StartTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
INT16S key;
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);
}
}
void MyTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_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
}
}
void YouTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_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
}
}
void HerTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_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次后才释放所申请的内存块