新聞中心

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

        ucos-ii學習筆記——動態內存分配原理及使用

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

        Author:zhangbin

        本文引用地址:http://www.104case.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;//定義內存控制塊指針,也即是指向內存分區的指針,創建一個

        //內存分區時,返回值就是它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次后才釋放所申請的內存塊



        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 绵竹市| 兴文县| 军事| 舟山市| 鄄城县| 建昌县| 巧家县| 洛川县| 繁昌县| 湘阴县| 当涂县| 资源县| 金塔县| 邢台县| 凌源市| 稻城县| 自治县| 贺兰县| 新竹县| 渭南市| 泸州市| 靖州| 手游| 定州市| 革吉县| 双桥区| 北票市| 山阳县| 界首市| 崇礼县| 新田县| 河曲县| 邛崃市| 二手房| 安康市| 澎湖县| 沧州市| 建瓯市| 奇台县| 阿拉尔市| 安图县|