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

📄 lib_mem.c

📁 UCOS-III
💻 C
📖 第 1 页 / 共 5 页
字号:
*         |                              |     |        |     |   |    |     |        |  P  |        |     |
*         |                              |     |        |     |   |    |     |        |     |        |     |
*         |                              -------        -------   |    -------        -------        -------
*         |                                | ^                    |      | ^
*         |                                | |            SegPrevPtr     | |
*         |                                v |         (see Note #2b2)   v |
*         |                              -------                       -------
*                                        |     |                       |     |
*    Memory Pools                        |     |                       |     |
*  (see Note #2a2)                       |     |                       |     |
*                                        |     |                       |     |
*         |                              |     |                       |     |
*         |                              -------                       -------
*         |                                | ^
*         |               PoolNextPtr ---> | | <--- PoolPrevPtr
*         |             (see Note #2b3)    v |    (see Note #2b3)
*         |                              -------
*         |                              |     |
*         |                              |     |
*         |                              |     |
*         |                              |     |
*         v                              |     |
*        ---                             -------
*
*$PAGE*
* Argument(s) : pmem_pool           Pointer to a memory pool structure to create (see Note #3).
*
*               pmem_base_addr      Memory pool base address :
*
*                                       (a)     Null address    Memory pool allocated from general-purpose heap.
*                                       (b) Non-null address    Memory pool allocated from dedicated memory
*                                                                   specified by its base address.
*
*               mem_size            Size      of memory pool segment          (in octets).
*
*               blk_nbr             Number    of memory pool blocks to create.
*
*               blk_size            Size      of memory pool blocks to create (in octets).
*
*               blk_align           Alignment of memory pool blocks to specific word boundary (in octets).
*
*               poctets_reqd        Optional pointer to a variable to ... :
*
*                                       (a) Return the number of octets required to successfully
*                                               allocate the memory pool, if any error(s);
*                                       (b) Return 0, otherwise.
*
*               perr        Pointer to variable that will receive the return error code from this function :
*
*                               LIB_MEM_ERR_NONE                    Memory pool successfully created.
*
*                               LIB_MEM_ERR_HEAP_NOT_FOUND          Heap   segment NOT found.
*                               LIB_MEM_ERR_HEAP_EMPTY              Heap   segment empty; NOT enough available 
*                                                                       memory from heap.
*                               LIB_MEM_ERR_HEAP_OVF                Requested memory overflows heap    memory.
*                               LIB_MEM_ERR_SEG_EMPTY               Memory segment empty; NOT enough available 
*                                                                       memory from segment for memory pools.
*                               LIB_MEM_ERR_SEG_OVF                 Requested memory overflows segment memory.
*
*                               LIB_MEM_ERR_INVALID_SEG_SIZE        Invalid memory segment size.
*                               LIB_MEM_ERR_INVALID_SEG_OVERLAP     Memory segment overlaps other memory
*                                                                       segment(s) in memory pool table.
*                               LIB_MEM_ERR_INVALID_BLK_NBR         Invalid memory pool number of blocks.
*                               LIB_MEM_ERR_INVALID_BLK_SIZE        Invalid memory pool block size.
*                               LIB_MEM_ERR_INVALID_BLK_ALIGN       Invalid memory pool block alignment.
*
*                                                                   ------- RETURNED BY Mem_PoolClr() : -------
*                               LIB_MEM_ERR_NULL_PTR                Argument 'pmem_pool' passed a NULL pointer.
*
* Return(s)   : none.
*
* Caller(s)   : Application.
*
* Note(s)     : (3) Assumes 'pmem_pool' points to a valid memory pool (if non-NULL).
*
*               (4) Pointers to variables that return values MUST be initialized PRIOR to all other 
*                   validation or function handling in case of any error(s).
*
*               (5) 'pmem_pool' variables MUST ALWAYS be accessed exclusively in critical sections.
*********************************************************************************************************
*/
/*$PAGE*/
#if (LIB_MEM_CFG_ALLOC_EN == DEF_ENABLED)
void  Mem_PoolCreate (MEM_POOL    *pmem_pool,
                      void        *pmem_base_addr,
                      CPU_SIZE_T   mem_size,
                      CPU_SIZE_T   blk_nbr,
                      CPU_SIZE_T   blk_size,
                      CPU_SIZE_T   blk_align,
                      CPU_SIZE_T  *poctets_reqd,
                      LIB_ERR     *perr)
{
    MEM_POOL     *pmem_pool_heap;
    MEM_POOL     *pmem_pool_prev;
    MEM_POOL     *pmem_pool_next;
    MEM_POOL     *pmem_pool_blk;
    void        **ppool_ptr;
    void         *pmem_blk;
    CPU_INT08U   *pmem_addr_ptrs;
    CPU_INT08U   *pmem_addr_pool;
    CPU_INT08U   *pmem_base_addr_start;
    CPU_INT08U   *pmem_base_addr_end;
    CPU_INT08U   *pmem_seg_addr_start;
    CPU_INT08U   *pmem_seg_addr_end;
    CPU_SIZE_T    octets_reqd_unused;
    CPU_SIZE_T    size_tot;
    CPU_SIZE_T    size_tot_ptrs;
    CPU_SIZE_T    size_tot_pool;
    CPU_SIZE_T    size_rem;
    CPU_SIZE_T    size_pool_ptrs;
    CPU_SIZE_T    blk_rem;
    CPU_SIZE_T    i;
    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(;);
    }
#endif

                                                                    /* ------------ VALIDATE RTN OCTETS PTR ----------- */
    if (poctets_reqd == (CPU_SIZE_T *) 0) {                         /* If NOT avail, ...                                */
        poctets_reqd  = (CPU_SIZE_T *)&octets_reqd_unused;          /* ... re-cfg NULL rtn ptr to unused local var.     */
       (void)&octets_reqd_unused;                                   /* Prevent possible 'variable unused' warning.      */
    }
   *poctets_reqd = 0u;                                              /* Init octets req'd for err (see Note #4).         */



    Mem_PoolClr(pmem_pool, perr);                                   /* Init mem pool     for err (see Note #4).         */
    if (*perr != LIB_MEM_ERR_NONE) {
         return;
    }


                                                                    /* ----------- VALIDATE MEM POOL CREATE ----------- */
#if (LIB_MEM_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
    if (pmem_base_addr != (void *)0) {
        if (mem_size < 1) {
           *perr = LIB_MEM_ERR_INVALID_SEG_SIZE;
            return;
        }
    }

    if (blk_nbr < 1) {
       *perr = LIB_MEM_ERR_INVALID_BLK_NBR;
        return;
    }

    if (blk_size < 1) {
       *perr = LIB_MEM_ERR_INVALID_BLK_SIZE;
        return;
    }

    if (blk_align < 1) {
       *perr = LIB_MEM_ERR_INVALID_BLK_ALIGN;
        return;
    }
#endif


                                                                    /* ------------ VALIDATE MEM POOL TBL ------------- */
    if (Mem_PoolTbl == (MEM_POOL *)0) {
       *perr = LIB_MEM_ERR_HEAP_NOT_FOUND;
        return;
    }



/*$PAGE*/
                                                                    /* ---------------- CREATE MEM POOL --------------- */
    pmem_pool_heap = (MEM_POOL *)&Mem_PoolHeap;
    size_tot       = (CPU_SIZE_T) 0u;

    CPU_CRITICAL_ENTER();

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

                                                                    /* --------------- 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
                                                                    /* Calc tot mem   size for mem blks.                */
        pmem_addr_pool  =  pmem_addr_ptrs + size_tot_ptrs;          /* Adj next avail addr for mem pool blks.           */
        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 heap ovf, ...                                 */
            CPU_CRITICAL_EXIT();
           *perr = LIB_MEM_ERR_HEAP_OVF;                            /* ... rtn err but add'l heap size NOT avail.       */
            return;
        }
#endif

        size_tot = size_tot_ptrs + size_tot_pool;

#if (LIB_MEM_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
        if ((size_tot < size_tot_ptrs) ||                           /* If heap ovf, ...                                 */
            (size_tot < size_tot_pool)) {
            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 > size_rem) {                                  /* If tot size > rem  size, ...                     */
            CPU_CRITICAL_EXIT();
           *poctets_reqd = size_tot - size_rem;                     /* ... rtn add'l heap size needed.                  */
           *perr         = LIB_MEM_ERR_HEAP_EMPTY;
            return;
        }

/*$PAGE*/
    } else {                                                        /* Else cfg mem pool from dedicated mem.            */
                                                                    /* -------- SRCH ALL MEM SEGS FOR MEM POOL -------- */
        pmem_base_addr_start = (CPU_INT08U *)pmem_base_addr;
        pmem_base_addr_end   = (CPU_INT08U *)pmem_base_addr + mem_size - 1;

#if (LIB_MEM_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
        if (pmem_base_addr_end < pmem_base_addr_start) {            /* Chk ovf of end addr.                             */
            CPU_CRITICAL_EXIT();
           *perr = LIB_MEM_ERR_INVALID_BLK_ADDR;
            return;
        }
#endif

        pmem_pool_blk  = (MEM_POOL *)0;
        pmem_pool_prev = (MEM_POOL *)0;
        pmem_pool_next =  Mem_PoolTbl;

        while (pmem_pool_next != (MEM_POOL *)0) {                   /* Srch tbl for mem seg with same base addr/size.   */

            if ((pmem_base_addr == pmem_pool_next->SegAddr) &&      /* If same base addr/size found, ...                */
                (mem_size       == pmem_pool_next->SegSizeTot)) {

                 pmem_pool_blk   = pmem_pool_next;
                 pmem_pool_prev  = pmem_pool_next;
                 break;                                             /* ... prev mem seg    found in tbl.                */

            } else {
                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;

                                                                    
                if (pmem_base_addr_end < pmem_seg_addr_start) {     /* If mem seg addr/size prior to next mem seg, ...  */
                    break;                                          /* ... new mem seg NOT avail in tbl.                */

                                                                    /* If mem seg overlaps prev mem seg(s) in tbl, ...  */
                } else if (((pmem_base_addr_start <= pmem_seg_addr_start)  &&
                            (pmem_base_addr_end   >= pmem_seg_addr_start)) ||
                           ((pmem_base_addr_start >= pmem_seg_addr_start)  &&
                            (pmem_base_addr_end   <= pmem_seg_addr_end  )) ||
                           ((pmem_base_addr_start <= pmem_seg_addr_end  )  &&
                            (pmem_base_addr_end   >= pmem_seg_addr_end  ))) {
                    CPU_CRITICAL_EXIT();
                   *perr = LIB_MEM_ERR_INVALID_SEG_OVERLAP;         /* ... rtn err.                                     */
                    return;
                }
            }
                                                                    /* If mem seg NOT found, adv to next mem seg.       */
            pmem_pool_prev = pmem_pool_next;

⌨️ 快捷键说明

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