久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 16640|回復: 0
打印 上一主題 下一主題
收起左側

uc/os-ii操作系統的內存管理實現實例--很受用!

[復制鏈接]
跳轉到指定樓層
樓主
ID:72008 發表于 2015-1-12 15:24 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
     每次 溫故uc/os-ii操作系統的源碼都有收獲,經典的東西就是經典;uc/os-ii曾經把我搞得好累,但是經過一段時間摸索之后發現只要有正確的學習方法,學好uc/os-ii并不難,同時基于uc/os-ii操作系統的應用程序開發也不難。關于嵌入式系統內存管理的方法應該不少,原子的內存管理教程就有兩個例程,一個是“特大號數組”型,一個是動態分配型,兩者都使用了malloc()函數。而uc/os-ii操作系統的內存管理實現原理很精妙沒有使用malloc()函數,主要是考慮該函數申請內存的時間不確定性。可以說,通過該例程就能理解uc/os-ii操作系統的內存管理實現原理。筆者認為通過實例學習,理解uc/os-ii操作系統的原理是個不錯的選擇。
    本實驗基于PC機在DOS環境下模擬。



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


#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;      /*定義內存塊指針,確定內存分區中首個內存塊的指針  */
OS_MEM_DATA MemInfo;   /*存放內存分區的狀態信息 */

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

/*
********************************************************************
*              MAIN主函數
**********************************************************************
*/

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


/*
***********************************************************
*                STARTUP TASK:主要功能就是創建3個任務
***********************************************************
*/
void  StartTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3      /* Allocate storage for CPU status register,實際應用中該部分可省略 */
    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);   /* 設置時鐘頻率 */
    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) {   /* 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,在這里創建完StartTask任務為什么不掛起自己?      */
    }
}

/*--------------------MyTask任務-------------------------*/
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"執行一次就換一次行  */
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);
if(Times>4)  /*0-1-2-3-4-5;Times==6時該條件語句為真 */
{
OSMemPut(IntBuffer,IntBlkPtr);   /* 進入第6次就釋放已經使用過的內存塊  */
}
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(            //請求內存塊
                 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
}
}
/*-------------------------------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(            //請求內存塊
                 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);  //等待2s
}
}
/*
通過本例的實驗現象能深刻理解內存管理函數的本質;現象分析如下:
y(行)    顯示內容:       顯示頭指針OSFreeList:     顯示已用的內存塊數目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”的數據很有規律,即都是以6為單位遞增,這是因為在創建內存控制塊時就定義了每個內存塊的長度是6個字節,所以就是以6為單位遞增,(0x504+0x6)==0x50A;
(0x50A+0x6)==0x510,(0x510+0x6)==0x516,等等; 2,第2行中,因為YouTask任務請求一個內存塊之后就立即釋放了,所以在第3個任務(HerTask任務)中,HerTask任務申請到的還是50A指針指向的內存塊,同樣在本任務中及時釋放了內存塊,實際上此時系統只占用504內存塊,所以到第4個任務MyTask 任務執行時,還是顯示已用2個內存塊,不過這時MyTask 任務已經占用了兩個內存塊,因為此時MyTask 任務還沒有釋放內存塊;3,當if(Times>4) 時 (0-1-2-3-4-5;Times==6時該條件語句為真)MyTask 任務得到一個內存塊就立即釋放了該內存塊,所以就一直會顯示已用6個內存塊,指針值停留在0x522處,不會再遞增了;4,由此現象得知:a),本例中申請到的8個內存塊是連續的地址空間;b),系統在初始化時,就初始化了一個空的任務控制塊鏈表,每個任務控制塊的有效數據為空,但是結點指針都有所指;當系統申請一個內存分區時,空閑任務控制塊就會減1,釋放了就加1;c),整個空閑鏈表是不是一個大的連續內存空間,還不知道,我覺得應該看OSInit()源碼。

*/                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 可以看黄的视频 | 新超碰97| 精品成人在线观看 | 精品国产黄色片 | 久久国产亚洲精品 | 国产亚洲欧美日韩精品一区二区三区 | 四虎av电影| 国产精品91久久久久久 | 日韩欧美在线不卡 | 欧美日韩在线一区二区三区 | 日本一区二区高清视频 | 一级黄色片一级黄色片 | 欧美精品久久久久久久久久 | 中文字幕 在线观看 | 国产精品一区二区三区四区五区 | 成人综合视频在线观看 | 精品久久电影 | 国内精品视频一区二区三区 | 国产久视频 | 亚洲国产精品久久 | 亚洲视频中文字幕 | 美国黄色一级片 | 成人三级影院 | 国产精品精品久久久 | 美女爽到呻吟久久久久 | 国产精品视屏 | 亚洲一区二区中文字幕 | 亚洲成人精 | 国产免费一级片 | 亚洲国产成人精品女人久久久 | 影音先锋中文字幕在线观看 | 国产亚洲精品久久久久久牛牛 | 日韩免费一级 | 91在线精品秘密一区二区 | 综合久久综合久久 | 欧美国产日韩在线观看成人 | 精品国产一区二区三区性色 | 欧美6一10sex性hd | 毛片网站在线观看视频 | 亚洲精品成人av久久 | 在线观看亚洲精品 |