欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標(biāo)題: uc/os-ii操作系統(tǒng)的內(nèi)存管理實現(xiàn)實例--很受用! [打印本頁]

作者: liuyy    時間: 2015-1-12 15:24
標(biāo)題: uc/os-ii操作系統(tǒng)的內(nèi)存管理實現(xiàn)實例--很受用!
     每次 溫故uc/os-ii操作系統(tǒng)的源碼都有收獲,經(jīng)典的東西就是經(jīng)典;uc/os-ii曾經(jīng)把我搞得好累,但是經(jīng)過一段時間摸索之后發(fā)現(xiàn)只要有正確的學(xué)習(xí)方法,學(xué)好uc/os-ii并不難,同時基于uc/os-ii操作系統(tǒng)的應(yīng)用程序開發(fā)也不難。關(guān)于嵌入式系統(tǒng)內(nèi)存管理的方法應(yīng)該不少,原子的內(nèi)存管理教程就有兩個例程,一個是“特大號數(shù)組”型,一個是動態(tài)分配型,兩者都使用了malloc()函數(shù)。而uc/os-ii操作系統(tǒng)的內(nèi)存管理實現(xiàn)原理很精妙沒有使用malloc()函數(shù),主要是考慮該函數(shù)申請內(nèi)存的時間不確定性。可以說,通過該例程就能理解uc/os-ii操作系統(tǒng)的內(nèi)存管理實現(xiàn)原理。筆者認(rèn)為通過實例學(xué)習(xí),理解uc/os-ii操作系統(tǒng)的原理是個不錯的選擇。
    本實驗基于PC機在DOS環(huán)境下模擬。



/*設(shè)計一個有3個任務(wù)的應(yīng)用程序,這3個任務(wù)分別是Mytask Youtask Hertask。在應(yīng)用程序中創(chuàng)建一個動態(tài)內(nèi)存分區(qū),該分區(qū)有8個內(nèi)存塊,每個內(nèi)存塊的長度是6字節(jié)。應(yīng)用程序的任務(wù)Youtask Hertask都在任務(wù)運行后請求一個內(nèi)存塊.隨后就釋放它;任務(wù)MYTASK也在任務(wù)運行后請求一個內(nèi)存塊,但是要在任務(wù)MYTASK運行6次后,才釋放它所申請的內(nèi)存塊。為了了解內(nèi)存分區(qū)變化的情況,編寫代碼來觀察分區(qū)頭指針和已被使用內(nèi)存塊的個數(shù)*/


#include "INCLUDES.h"

#define  TASK_STK_SIZE        512       /* 任務(wù)堆棧長度*/            

OS_STK        StartTaskStk[TASK_STK_SIZE];    /*定義任務(wù)堆棧區(qū) */
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;      /*定義內(nèi)存控制塊指針,創(chuàng)建一個內(nèi)存分區(qū)時,返回值就是它 */
INT8U         IntPart[8][6];  /*劃分一個具有8個內(nèi)存塊,每個內(nèi)存塊長度是6的內(nèi)存分區(qū) */
INT8U         *IntBlkPtr;      /*定義內(nèi)存塊指針,確定內(nèi)存分區(qū)中首個內(nèi)存塊的指針  */
OS_MEM_DATA MemInfo;   /*存放內(nèi)存分區(qū)的狀態(tài)信息 */

void  StartTask(void *data);               /* 聲明起始任務(wù)  */
void  MyTask(void *data);                  /* 聲明任務(wù)      */
void  YouTask(void *data);                 /* 聲明任務(wù)      */
void  HerTask(void *data);                 /* 聲明任務(wù)      */

/*
********************************************************************
*              MAIN主函數(shù)
**********************************************************************
*/

void  main (void)
{
    OSInit();               /* 初始化uC/OS-II                      */
    PC_DOSSaveReturn();       /* 保存DOS環(huán)境     */
    PC_VectSet(uCOS, OSCtxSw);     /* 安裝uC/OS-II的中斷 */
    IntBuffer=OSMemCreate(IntPart,8,6,&err);    /*創(chuàng)建動態(tài)內(nèi)存區(qū)  */
    OSTaskCreate(StartTask, (void *)0, &StartTaskStk[TASK_STK_SIZE - 1], 0);
    OSStart();             /* 啟動多任務(wù)管理   */
}


/*
***********************************************************
*                STARTUP TASK:主要功能就是創(chuàng)建3個任務(wù)
***********************************************************
*/
void  StartTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3      /* Allocate storage for CPU status register,實際應(yīng)用中該部分可省略 */
    OS_CPU_SR  cpu_sr;
#endif
    INT16S        key;          /*用于退出的建*/
    pdata = pdata;          /* Prevent compiler warning                 */
    OS_ENTER_CRITICAL();
    PC_VectSet(0x08, OSTickISR);      /* 安裝時鐘中斷向量 , */
    PC_SetTickRate(OS_TICKS_PER_SEC);   /* 設(shè)置時鐘頻率 */
    OS_EXIT_CRITICAL();

    OSStatInit();        /* 初始化統(tǒng)計任務(wù)   */
    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) {   /* See if key has been pressed     */
            if (key == 0x1B) {       /* Yes, see if it's the ESCAPE key    */
                PC_DOSReturn();    /* Return to DOS       */
            }
        }
        OSTimeDlyHMSM(0, 0, 3, 0);   /* Wait 3s,在這里創(chuàng)建完StartTask任務(wù)為什么不掛起自己?      */
    }
}

/*--------------------MyTask任務(wù)-------------------------*/
void MyTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3       /* Allocate storage for CPU status register */
    OS_CPU_SR  cpu_sr;
#endif
pdata=pdata;
for( ; ; )
{
PC_DispStr(10,++y,s1,DISP_BGND_BLACK+DISP_FGND_WHITE);  /*"++y"執(zhí)行一次就換一次行  */
IntBlkPtr=OSMemGet(   /*請求內(nèi)存分區(qū)的內(nèi)存塊的指針 */
                 IntBuffer, /*這個參數(shù)就指明了要獲取的內(nèi)存塊屬于哪個內(nèi)存分區(qū) */  
                 &err);      
   OSMemQuery(        /*查詢內(nèi)存控制塊信息 */
            IntBuffer,     /*帶查詢內(nèi)存控制塊指針 */
&MemInfo);
sprintf(s,"%0x",MemInfo.OSFreeList);  /*顯示頭指針 */
PC_DispStr(30,y,s,DISP_BGND_BLACK+DISP_FGND_WHITE);
sprintf(s,"%d",MemInfo.OSNUsed);  /*顯示已用的內(nèi)存塊數(shù)目 */
PC_DispStr(40,y,s,DISP_BGND_BLACK+DISP_FGND_WHITE);
if(Times>4)  /*0-1-2-3-4-5;Times==6時該條件語句為真 */
{
OSMemPut(IntBuffer,IntBlkPtr);   /* 進入第6次就釋放已經(jīng)使用過的內(nèi)存塊  */
}
Times++;
OSTimeDlyHMSM(0,0,1,0);  //等待2s
}
}

/*-------------------------------Youtask-------------------------------------*/
void YouTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
    OS_CPU_SR  cpu_sr;
#endif
pdata=pdata;
for( ; ; )
{
PC_DispStr(10,++y,s2,DISP_BGND_BLACK+DISP_FGND_WHITE);
IntBlkPtr=OSMemGet(            //請求內(nèi)存塊
                 IntBuffer,   //內(nèi)存分區(qū)的指針
                 &err);       //錯誤信息
   OSMemQuery(        //查詢內(nèi)存控制塊信息
            IntBuffer,     //帶查詢內(nèi)存控制塊指針
&MemInfo);
sprintf(s,"%0x",MemInfo.OSFreeList);  //顯示頭指針
PC_DispStr(30,y,s,DISP_BGND_BLACK+DISP_FGND_WHITE);
sprintf(s,"%d",MemInfo.OSNUsed);  //顯示已用的內(nèi)存塊數(shù)目
PC_DispStr(40,y,s,DISP_BGND_BLACK+DISP_FGND_WHITE);
OSMemPut( IntBuffer, IntBlkPtr );
OSTimeDlyHMSM(0,0,2,0);  //等待2s
}
}
/*-------------------------------Hertask-------------------------------------*/
void HerTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3      /* Allocate storage for CPU status register */
    OS_CPU_SR  cpu_sr;
#endif
pdata=pdata;
for( ; ; )
{
PC_DispStr(10,++y,s3,DISP_BGND_BLACK+DISP_FGND_WHITE);
IntBlkPtr=OSMemGet(            //請求內(nèi)存塊
                 IntBuffer,   //內(nèi)存分區(qū)的指針
                 &err);       //錯誤信息
   OSMemQuery(        //查詢內(nèi)存控制塊信息
            IntBuffer,     //帶查詢內(nèi)存控制塊指針
&MemInfo);
sprintf(s,"%0x",MemInfo.OSFreeList);  //顯示頭指針
PC_DispStr(30,y,s,DISP_BGND_BLACK+DISP_FGND_WHITE);
sprintf(s,"%d",MemInfo.OSNUsed);  //顯示已用的內(nèi)存塊數(shù)目
PC_DispStr(40,y,s,DISP_BGND_BLACK+DISP_FGND_WHITE);
OSMemPut(
IntBuffer,
IntBlkPtr
);
OSTimeDlyHMSM(0,0,1,0);  //等待2s
}
}
/*
通過本例的實驗現(xiàn)象能深刻理解內(nèi)存管理函數(shù)的本質(zhì);現(xiàn)象分析如下:
y(行)    顯示內(nèi)容:       顯示頭指針OSFreeList:     顯示已用的內(nèi)存塊數(shù)目OSNUsed:
1,        MyTask              504                         1
2,        YouTask             50A                         2
3,        HerTask             50A                         2
4,        MyTask              50A                         2
5,        HerTask             510                         3
6,        MyTask              510                         3
7,        YouTask             516                         4
8,        HerTask             516                         4
9,        MyTask              516                         4
10,       HerTask             51C                         5
11,       MyTask              51C                         5
12,       YouTask             522                         6
13,       HerTask             522                         6
14,       MyTask              522                         6
15,       MyTask              522                         6

通過上表可以看出:1,“顯示頭指針OSFreeList”的數(shù)據(jù)很有規(guī)律,即都是以6為單位遞增,這是因為在創(chuàng)建內(nèi)存控制塊時就定義了每個內(nèi)存塊的長度是6個字節(jié),所以就是以6為單位遞增,(0x504+0x6)==0x50A;
(0x50A+0x6)==0x510,(0x510+0x6)==0x516,等等; 2,第2行中,因為YouTask任務(wù)請求一個內(nèi)存塊之后就立即釋放了,所以在第3個任務(wù)(HerTask任務(wù))中,HerTask任務(wù)申請到的還是50A指針指向的內(nèi)存塊,同樣在本任務(wù)中及時釋放了內(nèi)存塊,實際上此時系統(tǒng)只占用504內(nèi)存塊,所以到第4個任務(wù)MyTask 任務(wù)執(zhí)行時,還是顯示已用2個內(nèi)存塊,不過這時MyTask 任務(wù)已經(jīng)占用了兩個內(nèi)存塊,因為此時MyTask 任務(wù)還沒有釋放內(nèi)存塊;3,當(dāng)if(Times>4) 時 (0-1-2-3-4-5;Times==6時該條件語句為真)MyTask 任務(wù)得到一個內(nèi)存塊就立即釋放了該內(nèi)存塊,所以就一直會顯示已用6個內(nèi)存塊,指針值停留在0x522處,不會再遞增了;4,由此現(xiàn)象得知:a),本例中申請到的8個內(nèi)存塊是連續(xù)的地址空間;b),系統(tǒng)在初始化時,就初始化了一個空的任務(wù)控制塊鏈表,每個任務(wù)控制塊的有效數(shù)據(jù)為空,但是結(jié)點指針都有所指;當(dāng)系統(tǒng)申請一個內(nèi)存分區(qū)時,空閑任務(wù)控制塊就會減1,釋放了就加1;c),整個空閑鏈表是不是一個大的連續(xù)內(nèi)存空間,還不知道,我覺得應(yīng)該看OSInit()源碼。

*/                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   






歡迎光臨 (http://www.raoushi.com/bbs/) Powered by Discuz! X3.1