⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lib_mem.c

📁 UCOS-III
💻 C
📖 第 1 页 / 共 5 页
字号:
            pmem_pool_next = pmem_pool_next->SegNextPtr;
        }

        if (pmem_pool_blk == (MEM_POOL *)0) {                       /* If mem seg NOT found, add    new  mem seg.       */
            pmem_pool_blk               = pmem_pool;
            pmem_pool->SegAddr          = pmem_base_addr;
            pmem_pool->SegAddrNextAvail = pmem_base_addr;
            pmem_pool->SegSizeTot       = mem_size;
            pmem_pool->SegSizeRem       = mem_size;
        }

/*$PAGE*/
                                                                    /* --------------- VALIDATE MEM SEG --------------- */
                                                                    /* Calc tot mem size for mem pool ptrs.             */
        pmem_addr_ptrs = (CPU_INT08U *)pmem_pool_heap->SegAddrNextAvail;
        size_tot_ptrs  =  Mem_PoolSegCalcTotSize((void     *)pmem_addr_ptrs,
                                                 (CPU_SIZE_T)blk_nbr,
                                                 (CPU_SIZE_T)sizeof(void *),
                                                 (CPU_SIZE_T)sizeof(void *));
#if (LIB_MEM_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
        if (size_tot_ptrs < 1) {                                    /* If heap ovf, ...                                 */
            CPU_CRITICAL_EXIT();
           *perr = LIB_MEM_ERR_HEAP_OVF;                            /* ... rtn err but add'l heap size NOT avail.       */
            return;
        }
#endif

        size_rem = pmem_pool_heap->SegSizeRem;
        if (size_tot_ptrs > size_rem) {                             /* If ptr size > rem  size, ...                     */
            CPU_CRITICAL_EXIT();
           *poctets_reqd = size_tot_ptrs - size_rem;                /* ... rtn add'l heap size needed.                  */
           *perr         = LIB_MEM_ERR_HEAP_EMPTY;
            return;
        }

                                                                    /* Calc tot mem size for mem blks.                  */
        pmem_addr_pool = (CPU_INT08U *)pmem_pool_blk->SegAddrNextAvail;
        size_tot_pool  =  Mem_PoolSegCalcTotSize((void     *)pmem_addr_pool,
                                                 (CPU_SIZE_T)blk_nbr,
                                                 (CPU_SIZE_T)blk_size,
                                                 (CPU_SIZE_T)blk_align);
#if (LIB_MEM_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
        if (size_tot_pool < 1) {                                    /* If seg  ovf, ...                                 */
            CPU_CRITICAL_EXIT();
           *perr = LIB_MEM_ERR_SEG_OVF;                             /* ... rtn err but add'l seg  size NOT avail.       */
            return;
        }
#endif

        size_rem = pmem_pool_blk->SegSizeRem;
        if (size_tot_pool > size_rem) {                             /* If tot size > rem  size, ...                     */
            CPU_CRITICAL_EXIT();
           *poctets_reqd = size_tot_pool - size_rem;                /* ... rtn add'l seg  size needed.                  */
           *perr         = LIB_MEM_ERR_SEG_EMPTY;
            return;
        }
    }


/*$PAGE*/
                                                                    /* ---------------- ALLOC MEM BLKs ---------------- */
    size_pool_ptrs =  blk_nbr * sizeof(void *);
                                                                    /* Alloc stk of ptrs for mem blks from heap.        */
    ppool_ptr      = (void **)Mem_PoolSegAlloc((MEM_POOL *)pmem_pool_heap,
                                               (CPU_SIZE_T)size_pool_ptrs,
                                               (CPU_SIZE_T)sizeof(void *));
    if (ppool_ptr == (void **)0) {                                  /* If mem pool ptrs alloc failed, ...               */
        size_rem = pmem_pool_heap->SegSizeRem;
        CPU_CRITICAL_EXIT();
                                                                    /* ... rtn add'l heap size needed.                  */
        if (pmem_base_addr == (void *)0) {
            if (size_tot > size_rem) {
               *poctets_reqd = size_tot       - size_rem;
            } else {
               *poctets_reqd = size_tot;
            }
        } else {
            if (size_pool_ptrs > size_rem) {
               *poctets_reqd = size_pool_ptrs - size_rem;
            } else {
               *poctets_reqd = size_pool_ptrs;
            }
        }
       *perr = LIB_MEM_ERR_HEAP_EMPTY;
        return;
    }

    for (i = 0u; i < blk_nbr; i++) {                                /* Alloc mem blks from blk seg ptr.                 */
        pmem_blk = (void *)Mem_PoolSegAlloc(pmem_pool_blk, blk_size, blk_align);
        if (pmem_blk == (void *)0) {                                /* If    mem blks alloc failed, ...                 */
            pmem_addr_pool = (CPU_INT08U *)pmem_pool_blk->SegAddrNextAvail;
            size_rem       = (CPU_SIZE_T  )pmem_pool_blk->SegSizeRem;
            CPU_CRITICAL_EXIT();
            blk_rem        =  blk_nbr - i;
            size_tot       =  Mem_PoolSegCalcTotSize((void     *)pmem_addr_pool,
                                                     (CPU_SIZE_T)blk_rem,
                                                     (CPU_SIZE_T)blk_size,
                                                     (CPU_SIZE_T)blk_align);
                                                                    /* ... rtn add'l seg  size needed.                  */
            if (size_tot > size_rem) {
               *poctets_reqd = size_tot - size_rem;
            } else {
               *poctets_reqd = size_tot;
            }
           *perr = LIB_MEM_ERR_SEG_EMPTY;
            return;
        }
        ppool_ptr[i] = pmem_blk;
    }


/*$PAGE*/
                                                                    /* ------------- UPDATE MEM POOL TBL -------------- */
    if (pmem_pool_prev == pmem_pool_next) {                         /* Add new mem seg  to list.                        */

        pmem_pool_next             = pmem_pool_blk->PoolNextPtr;
        pmem_pool->PoolPrevPtr     = pmem_pool_blk;
        pmem_pool->PoolNextPtr     = pmem_pool_next;
        pmem_pool_blk->PoolNextPtr = pmem_pool;
        if (pmem_pool_next != (MEM_POOL *)0) {
            pmem_pool_next->PoolPrevPtr = pmem_pool;
        }

    } else {                                                        /* Add new mem pool to mem seg.                     */

        pmem_pool->SegPrevPtr = pmem_pool_prev;
        pmem_pool->SegNextPtr = pmem_pool_next;

        if (pmem_pool_prev != (MEM_POOL *)0) {                      /* Update prev mem pool link.                       */
            pmem_pool_prev->SegNextPtr = pmem_pool;
        } else {
            Mem_PoolTbl                = pmem_pool;                 /* Update      mem pool head.                       */
        }

        if (pmem_pool_next != (MEM_POOL *)0) {                      /* Update next mem pool link.                       */
            pmem_pool_next->SegPrevPtr = pmem_pool;
        }
    }


                                                                    /* ----------------- CFG MEM POOL ----------------- */
    pmem_pool->Type          = (LIB_MEM_TYPE) LIB_MEM_TYPE_POOL;
    pmem_pool->PoolAddrStart = (void       *) pmem_addr_pool;
    pmem_pool->PoolAddrEnd   = (void       *)(pmem_addr_pool + size_tot_pool - 1);
    pmem_pool->PoolPtrs      = (void      **) ppool_ptr;
    pmem_pool->PoolSize      = (CPU_SIZE_T  ) size_tot_pool;
    pmem_pool->BlkAlign      = (CPU_SIZE_T  ) blk_align;
    pmem_pool->BlkSize       = (CPU_SIZE_T  ) blk_size;
    pmem_pool->BlkNbr        = (CPU_SIZE_T  ) blk_nbr;
    pmem_pool->BlkIx         = (MEM_POOL_IX ) blk_nbr;


    CPU_CRITICAL_EXIT();

   *perr = LIB_MEM_ERR_NONE;
}
#endif


/*$PAGE*/
/*
*********************************************************************************************************
*                                          Mem_PoolBlkGet()
*
* Description : Get a memory block from memory pool.
*
* Argument(s) : pmem_pool   Pointer to  memory pool to get memory block from.
*
*               size        Size of requested memory (in octets).
*
*               perr        Pointer to variable that will receive the return error code from this function :
*
*                               LIB_MEM_ERR_NONE                   Memory block successfully returned.
*                               LIB_MEM_ERR_POOL_EMPTY          NO memory blocks available in memory pool.
*
*                               LIB_MEM_ERR_NULL_PTR            Argument 'pmem_pool' passed a NULL pointer.
*                               LIB_MEM_ERR_INVALID_POOL        Invalid memory pool type.
*                               LIB_MEM_ERR_INVALID_BLK_SIZE    Invalid memory pool block size requested.
*                               LIB_MEM_ERR_INVALID_BLK_IX      Invalid memory pool block index.
*
* Return(s)   : Pointer to memory block, if NO error(s).
*
*               Pointer to NULL,         otherwise.
*
* Caller(s)   : Application.
*
* Note(s)     : (1) 'pmem_pool' variables MUST ALWAYS be accessed exclusively in critical sections.
*********************************************************************************************************
*/
/*$PAGE*/
#if (LIB_MEM_CFG_ALLOC_EN == DEF_ENABLED)
void  *Mem_PoolBlkGet (MEM_POOL    *pmem_pool,
                       CPU_SIZE_T   size,
                       LIB_ERR     *perr)
{
    void  *pmem_blk;
    CPU_SR_ALLOC();


#if (LIB_MEM_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)                     /* ------------- VALIDATE RTN ERR PTR ------------- */
    if (perr == (LIB_ERR *)0) {
        CPU_SW_EXCEPTION((void *)0);
    }
#endif

                                                                    /* ------------ VALIDATE MEM POOL GET ------------- */
#if (LIB_MEM_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)                     
    if (pmem_pool == (MEM_POOL *)0) {                               /* Validate mem ptr.                                */
       *perr = LIB_MEM_ERR_NULL_PTR;
        return ((void *)0);
    }

    if (size < 1) {                                                 /* Validate req'd size as non-NULL.                 */
       *perr = LIB_MEM_ERR_INVALID_BLK_SIZE;
        return ((void *)0);
    }
#endif

    CPU_CRITICAL_ENTER();

#if (LIB_MEM_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
    if (pmem_pool->Type != LIB_MEM_TYPE_POOL) {                     /* Validate mem pool type.                          */
        CPU_CRITICAL_EXIT();
       *perr = LIB_MEM_ERR_INVALID_POOL;
        return ((void *)0);
    }

    if (size > pmem_pool->BlkSize) {                                /* Validate req'd size <= mem pool blk size.        */
        CPU_CRITICAL_EXIT();
       *perr = LIB_MEM_ERR_INVALID_BLK_SIZE;
        return ((void *)0);
    }
#endif

   (void)&size;                                                     /* Prevent possible 'variable unused' warning.      */

    if (pmem_pool->BlkIx < 1) {                                     /* Validate mem pool as NOT empty.                  */
        CPU_CRITICAL_EXIT();
       *perr = LIB_MEM_ERR_POOL_EMPTY;
        return ((void *)0);
    }

    if (pmem_pool->BlkIx > pmem_pool->BlkNbr) {                     /* Validate mem pool ix NOT corrupt.                */
        CPU_CRITICAL_EXIT();
       *perr = LIB_MEM_ERR_INVALID_BLK_IX;
        return ((void *)0);
    }

                                                                    /* ------------ GET MEM BLK FROM POOL ------------- */
    pmem_pool->BlkIx--;
    pmem_blk = pmem_pool->PoolPtrs[pmem_pool->BlkIx];

    CPU_CRITICAL_EXIT();

   *perr =  LIB_MEM_ERR_NONE;

    return (pmem_blk);
}
#endif


/*$PAGE*/
/*
*********************************************************************************************************
*                                          Mem_PoolBlkFree()
*
* Description : Free a memory block to memory pool.
*
* Argument(s) : pmem_pool   Pointer to memory pool to free memory block.
*
*               pmem_blk    Pointer to memory block address to free.
*
*               perr        Pointer to variable that will receive the return error code from this function :
*
*                               LIB_MEM_ERR_NONE                            Memory block successfully freed.
*                               LIB_MEM_ERR_POOL_FULL                   ALL memory blocks already available in
*                                                                      

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -