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

📄 lib_mem.c

📁 飞思卡尔HCS12的OS移植(ucosII),实现了三个任务,IDE:CODEWARRIOR
💻 C
📖 第 1 页 / 共 4 页
字号:
    if (Mem_PoolTbl == (MEM_POOL *)0) {
       *perr = LIB_MEM_ERR_HEAP_NOT_FOUND;
        return;
    }

    if (pmem_base_addr != (void *)0) {
        if (mem_size < 1) {
           *perr = LIB_MEM_ERR_INVALID_SEG_SIZE;
            return;
        }
    }


    pmem_pool_heap = (MEM_POOL *)&Mem_PoolHeap;

    CPU_CRITICAL_ENTER();

                                                                /* ------------------ MEM POOL CREATE ----------------- */
    if (pmem_base_addr == (void *)0) {                          /* If no base addr, cfg mem pool from heap.             */
        pmem_pool_prev = pmem_pool_heap;
        pmem_pool_next = pmem_pool_heap;
        pmem_pool_blk  = pmem_pool_heap;

                                                                /* Get next avail addr in mem seg.                      */
        pmem_addr_ptrs = (CPU_INT08U *)pmem_pool_heap->SegAddrNextAvail;
                                                                /* Calc tot mem   size for mem pool ptrs.               */
        tot_size_ptrs  =  Mem_PoolSegCalcTotSize((void     *)pmem_addr_ptrs,
                                                 (CPU_SIZE_T)blk_nbr,
                                                 (CPU_SIZE_T)sizeof(void *),
                                                 (CPU_SIZE_T)sizeof(void *));
        pmem_addr_pool =  pmem_addr_ptrs + tot_size_ptrs;       /* Adj next avail addr for mem pool blks.               */
                                                                /* Calc tot mem  usage for mem blks.                    */
        tot_size_pool  =  Mem_PoolSegCalcTotSize((void     *)pmem_addr_ptrs,
                                                 (CPU_SIZE_T)blk_nbr,
                                                 (CPU_SIZE_T)blk_size,
                                                 (CPU_SIZE_T)blk_align);

        tot_size = tot_size_ptrs + tot_size_pool;
        size_rem = pmem_pool_heap->SegSizeRem;

        if (tot_size > size_rem) {
            CPU_CRITICAL_EXIT();
           *perr = LIB_MEM_ERR_HEAP_FULL;

            if (poctets_reqd != (CPU_SIZE_T *)0) {
               *poctets_reqd  =  tot_size - size_rem;
            }
            return;
        }


    } else {
                                                                /* Srch mem seg tbl prim list to find insertion pnt.    */
        pmem_pool_blk  = (MEM_POOL *)0;
        pmem_pool_prev = (MEM_POOL *)0;
        pmem_pool_next =  Mem_PoolTbl;

        while (pmem_pool_next != (MEM_POOL *)0) {
                                                                /* Seg found.                                           */
            if ((pmem_base_addr == pmem_pool_next->SegAddr) &&
                (mem_size       == pmem_pool_next->SegSizeTot)) {

                pmem_pool_prev = pmem_pool_next;
                pmem_pool_blk  = pmem_pool_next;                /* Store pool ptr with seg info.                        */
                break;

            } else {
                pmem_base_addr_start = (CPU_INT08U *)pmem_base_addr;
                pmem_base_addr_end   = (CPU_INT08U *)pmem_base_addr + mem_size - 1;
                pmem_seg_addr_start  = (CPU_INT08U *)pmem_pool_next->SegAddr;
                pmem_seg_addr_end    = (CPU_INT08U *)pmem_pool_next->SegAddr + pmem_pool_next->SegSizeTot - 1;

                                                                /* Seg not found.                                       */
                if (pmem_base_addr_end < pmem_seg_addr_start) {
                    break;

                                                                /* New seg extends over prev def seg.                   */
                } else if ((pmem_base_addr_start <= pmem_seg_addr_start) &&
                           (pmem_base_addr_end   >= pmem_seg_addr_start)) {
                    CPU_CRITICAL_EXIT();
                   *perr = LIB_MEM_ERR_SEG_OVERLAP;
                    return;

                                                                /* New seg overlaps end of prev def seg.                */
                } else if ((pmem_base_addr_start >= pmem_seg_addr_start) &&
                           (pmem_base_addr_start <= pmem_seg_addr_end)) {
                    CPU_CRITICAL_EXIT();
                   *perr = LIB_MEM_ERR_SEG_OVERLAP;
                    return;
                }
            }

            pmem_pool_prev = pmem_pool_next;
            pmem_pool_next = pmem_pool_next->SegPrimListNextPtr;
        }

        if (pmem_pool_blk == (MEM_POOL *)0) {                   /* If seg not found, write seg info into new pool.      */
            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;
        }

                                                                /* Get next avail addr in heap.                         */
        pmem_addr_ptrs = (CPU_INT08U *)pmem_pool_heap->SegAddrNextAvail;
                                                                /* Calc tot mem size for mem pool ptrs.                 */
        tot_size_ptrs  =  Mem_PoolSegCalcTotSize((void     *)pmem_addr_ptrs,
                                                 (CPU_SIZE_T)blk_nbr,
                                                 (CPU_SIZE_T)sizeof(void *),
                                                 (CPU_SIZE_T)sizeof(void *));
        size_rem       =  pmem_pool_heap->SegSizeRem;

        if (tot_size_ptrs > size_rem) {
            CPU_CRITICAL_EXIT();
           *perr = LIB_MEM_ERR_HEAP_FULL;

            if (poctets_reqd != (CPU_SIZE_T *)0) {
               *poctets_reqd  =  tot_size_ptrs - size_rem;
            }
            return;
        }

                                                                /* Get next avail addr in mem seg.                      */
        pmem_addr_pool = (CPU_INT08U *)pmem_pool_blk->SegAddrNextAvail;
                                                                /* Calc tot mem size for mem blks.                      */
        tot_size_pool  =  Mem_PoolSegCalcTotSize((void     *)pmem_addr_pool,
                                                 (CPU_SIZE_T)blk_nbr,
                                                 (CPU_SIZE_T)blk_size,
                                                 (CPU_SIZE_T)blk_align);
        size_rem       =  pmem_pool_blk->SegSizeRem;

        if (tot_size_pool > size_rem) {
            CPU_CRITICAL_EXIT();
           *perr = LIB_MEM_ERR_SEG_FULL;

            if (poctets_reqd != (CPU_SIZE_T *)0) {
               *poctets_reqd  =  tot_size_pool - size_rem;
            }
            return;
        }
    }

                                                                /* ------------------- MEM BLK ALLOC ------------------ */
    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 *));

                                                                /* Alloc mem blks from blk seg ptr.                     */
    for (i = 0; i < blk_nbr; i++) {
        pmem_blk = (void *)Mem_PoolSegAlloc(pmem_pool_blk, blk_size, blk_align);

        if (pmem_blk == (void *)0) {
            CPU_CRITICAL_EXIT();
           *perr = LIB_MEM_ERR_SEG_FULL;
            return;
        }

        ppool_ptr[i] = pmem_blk;
    }

                                                                /* ------------------- MEM POOL TBL ------------------- */
    if (pmem_pool_prev == pmem_pool_next) {                     /* Add new mem pool to sec  list.                       */

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

    } else {                                                    /* Add new mem pool to prim list.                       */

        pmem_pool->SegPrimListPrevPtr = pmem_pool_prev;
        pmem_pool->SegPrimListNextPtr = pmem_pool_next;

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

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

                                                                /* ------------------- MEM POOL INFO ------------------ */
    pmem_pool->Type          = (LIB_MEM_TYPE)LIB_MEM_TYPE_POOL;
    pmem_pool->PoolAddrStart = (void       *) pmem_addr_pool;
    pmem_pool->PoolAddrEnd   = (void       *)(pmem_addr_pool + tot_size_pool - 1);
    pmem_pool->PoolPtrs      = (void      **) ppool_ptr;
    pmem_pool->PoolSize      = (CPU_SIZE_T  ) tot_size_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_ERR_NONE;
}
#endif


/*$PAGE*/
/*
*********************************************************************************************************
*                                          Mem_PoolBlkGet()
*
* Description : Retrieve a memory block from memory pool.
*
* Argument(s) : pmem_pool       Pointer to memory pool to get memory block from.
*
*               mem_size        Size of requested memory (in octets).
*
*               perr            Pointer to variable that will receive the return error code from this function :
*
*                                   LIB_ERR_NONE                    Memory block retrieved successfully.
*
* Return(s)   : Pointer to memory block, if NO errors.
*
*               Pointer to NULL,         otherwise.
*
* Caller(s)   : various.
*
* Note(s)     : none.
*********************************************************************************************************
*/

#if (LIB_MEM_CFG_POOL_EN == DEF_ENABLED)
void  *Mem_PoolBlkGet (MEM_POOL    *pmem_pool,
                       CPU_SIZE_T   size,
                       LIB_ERR     *perr)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
    CPU_SR   cpu_sr;
#endif
    void    *pmem_blk;


    if (pmem_pool == (MEM_POOL *)0) {
       *perr = LIB_MEM_ERR_NULL_PTR;
        return ((void *)0);
    }

    CPU_CRITICAL_ENTER();
    if (pmem_pool->Type != LIB_MEM_TYPE_POOL) {
        CPU_CRITICAL_EXIT();
       *perr = LIB_MEM_ERR_INVALID_POOL;
        return ((void *)0);
    }

    if (size > pmem_pool->BlkSize) {
        CPU_CRITICAL_EXIT();
       *perr = LIB_MEM_ERR_INVALID_BLK_SIZE;
        return ((void *)0);
    }

    if (pmem_pool->BlkIx == 0) {
        CPU_CRITICAL_EXIT();
       *perr = LIB_MEM_ERR_NONE_AVAIL;
        return ((void *)0);
    }

    if (pmem_pool->BlkIx > pmem_pool->BlkNbr) {
        CPU_CRITICAL_EXIT();
       *perr = LIB_MEM_ERR_INVALID_IX;
        return ((void *)0);
    }

    pmem_pool->BlkIx--;
    pmem_blk = pmem_pool->PoolPtrs[pmem_pool->BlkIx];
    CPU_CRITICAL_EXIT();

   *perr = LIB_ERR_NONE;
    return (pmem_blk);
}
#endif


/*$PAGE*/
/*
*********************************************************************************************************
*                                          Mem_PoolBlkFree()
*
* Description : Return a memory block to memory pool.
*
* Argument(s) : pmem_pool       Pointer to memory pool.
*
*               pmem_addr       Pointer to memory block address to free.
*
*               perr            Pointer to variable that will receive the return error code from this function :
*
*                                   LIB_ERR_NONE                    Memory block successfully freed.
*
* Return(s)   : Pointer to memory block, if NO errors.
*
*               Pointer to NULL,         otherwise.
*
* Caller(s)   : various.
*
* Note(s)     : none.
*********************************************************************************************************
*/

#if (LIB_MEM_CFG_POOL_EN == DEF_ENABLED)
void  Mem_PoolBlkFree (MEM_POOL  *pmem_pool,
                       void      *pmem_addr,
                       LIB_ERR   *perr)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
    CPU_SR        cpu_sr;
#endif
#if (LIB_MEM_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
    MEM_POOL_IX   i;
#endif
    void         *pmem_blk_end;


    if (pmem_pool == (MEM_POOL *)0) {
       *perr = LIB_MEM_ERR_NULL_PTR;
        return;
    }

    if (pmem_addr == (void *)0) {
       *perr = LIB_MEM_ERR_NULL_PTR;
        return;
    }

⌨️ 快捷键说明

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