UCOSII 内存管理

在下这厢有礼了

内存管理:实际上就是为节省和最大利用内存,而对内存做的管理。

内存管理原理:就是将一块内存分割成很多的小块,让user去使用,被使用的内存成为使用了的内存,用完重新回到内存管理中,没有使用的内存被作为有效(free)内存。

为什么系统需要内存管理?这个问题可以思考一下。

我在学习ucosII的memory management,感觉肯定很牛逼的操作,让它实现了一个内存管理。可是它却给我上了一课,最简单的操作,才是最牛逼的操作。实际上它就是通过将一块内存通过数组将它分成相同的N块,通过链表将每一个数字连接起来,形成一个数组链表,使用一块,就从链表头中,去掉一个,用完就放到链表的尾端。

第一段 创建内存

OS_MEM  *OSMemCreate(void   *addr,

                     INT32U  nblks,

                     INT32U  blksize,

                     INT8U  *perr)

{

    OS_MEM    *pmem;

    INT8U     *pblk;

    void     **plink;

    INT32U     loops;

    INT32U     i;

 

    OS_ENTER_CRITICAL();

    pmem =OSMemFreeList;                            /* Get next free memory partition                */

    if (OSMemFreeList !=(OS_MEM *)0) {               /* See ifpool of free partitions was empty      */

        OSMemFreeList = (OS_MEM*)OSMemFreeList->OSMemFreeList;

    }

    OS_EXIT_CRITICAL();

    if (pmem == (OS_MEM*)0) {                        /* See ifwe have a memory partition             */

        *perr =OS_ERR_MEM_INVALID_PART;

        return ((OS_MEM*)0);

    }

    plink = (void**)addr;                            /*Create linked list of free memory blocks     */

    pblk  = (INT8U *)addr;

    loops  = nblks - 1u;

    for (i = 0u; i <loops; i++) {

        pblk +=  blksize;                             /* Point to the FOLLOWING block                  */

       *plink = (void *)pblk;                        /*Save pointer to NEXT block in CURRENT block  */

        plink = (void **)pblk;                       /* Position to  NEXT      block                  */

    }

    *plink              = (void *)0;                  /* Last memory block pointsto NULL              */

   pmem->OSMemAddr     =addr;                       /* Storestart address of memory partition      */

    pmem->OSMemFreeList= addr;                       /*Initialize pointer to pool of free blocks    */

   pmem->OSMemNFree    =nblks;                      /* Storenumber of free blocks in MCB           */

   pmem->OSMemNBlks    = nblks;

    pmem->OSMemBlkSize  = blksize;                    /* Store block size of eachmemory blocks        */

    *perr               = OS_ERR_NONE;

    return (pmem);

}

蓝色的确保是一个空的链表块

红色的是将下一块的指针地址保存在当前块指针地址中

第二段 获得内存

void *OSMemGet (OS_MEM  *pmem,

                 INT8U   *perr)

{

   void      *pblk;

   OS_ENTER_CRITICAL();

   if (pmem->OSMemNFree > 0u) {                      /* See if there are anyfree memory blocks       */

       pblk                = pmem->OSMemFreeList;    /* Yes, point to next free memory block          */

       pmem->OSMemFreeList = *(void **)pblk;         /*     Adjust pointer to new free list         */

       pmem->OSMemNFree--;                           /*      One less memory block in thispartition  */

       OS_EXIT_CRITICAL();

       *perr = OS_ERR_NONE;                          /*      No error                                 */

       return (pblk);                                /*      Return memory block to caller            */

    }

   OS_EXIT_CRITICAL();

   *perr = OS_ERR_MEM_NO_FREE_BLKS;                  /* No,  Notify caller of empty memory partition  */

   return ((void *)0);                               /*      Return NULL pointer to caller            */

}

红色的调整新的内存链表,

第一条指令是:拿出一块有效内存那(首地址的内存块);

第二条指令是:将首地址内存块存储的第二块内存地址 传给  可用(free)首地址。

第三条指令是:从总的内存块数量中减去一块


第三段 释放内存

INT8U OSMemPut (OS_MEM  *pmem,

                 void    *pblk)

{

   OS_ENTER_CRITICAL();

   if (pmem->OSMemNFree >= pmem->OSMemNBlks) {  /* Make sure all blocks not alreadyreturned          */

       OS_EXIT_CRITICAL();

       return (OS_ERR_MEM_FULL);

    }

    *(void **)pblk      = pmem->OSMemFreeList;   /* Insert released block into free blocklist         */

    pmem->OSMemFreeList= pblk;

    pmem->OSMemNFree++;                          /* One more memoryblock in this partition            */

   OS_EXIT_CRITICAL();

   return (OS_ERR_NONE);                        /* Notify caller thatmemory block was released       */

}

第一条指令:插入释放的内存块在可用内存块链表(就是说将空闲的链表的首地址放到pblk的地址中保存)

第二条指令:将释放的内存的首地址交给 可用内存块的链表

第三条指令:是将可用内存块的数量加一


如果你觉得指针理解还够的话,推荐你看《理解*(void**)》,可能会对你有帮助。




  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值