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

📄 lib_mem.c

📁 ucosii在stm32上的移植
💻 C
📖 第 1 页 / 共 5 页
字号:
*                       (2) Memory Pools' 'SegPrevPtr'  & 'SegNextPtr'  doubly-link each memory segment to
*                           form the list of memory segments.
*
*                       (3) Memory Pools' 'PoolPrevPtr' & 'PoolNextPtr' doubly-link the  memory pools of
*                           each memory segment.
*
*                   (c) New memory pools, which do not share a memory segment, are inserted in the Memory
*                       Segments Primary List.  The point of insertion is such to keep ascended order by
*                       memory segment base address.
*
*                   (d) Memory pool pointers to memory blocks 'PoolPtrs' must be allocated for each created
*                       memory pool.  These pointers are stored in the memory pool heap segment 'Mem_PoolHeap'.
*
*                       (1) A memory pool can also have its memory blocks allocated from the memory pool heap.
*                           'pmem_base_addr' must be set to NULL & 'mem_size' must be set to (0) to create the
*                           memory pool.
*
*
*                                        |                                                                 |
*                                        |<----------------------- Memory Segments ----------------------->|
*                                        |                         (see Note #2a1)                         |
*
*                                 Lowest Memory Segment                                      Highest Memory Segment
*                                     Base Address                                                Base Address
*                                    (see Note #2c)                                              (see Note #2c)
*
*                                           |             SegNextPtr             Heap Memory Pool       |
*                                           |          (see Note #2b2)            (see Note #2d)        |
*                                           |                     |                                     |
*                                           v                     |                      |              v
*                                                                 |                      v
*        ---          Head of Memory     -------        -------   v    -------        -------        -------
*         ^             Pool Table   --->|     |------->|     |------->|     |------->|     |------->|     |
*         |          (see Note #2b1)     |     |        |     |        |     |        |  H  |        |     |
*         |                              |     |<-------|     |<-------|     |<-------|  E  |<-------|     |
*         |                              |     |        |     |   ^    |     |        |  A  |        |     |
*         |                              |     |        |     |   |    |     |        |  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 initialize.
*
*               blk_size            Size      of memory pool blocks to initialize (in octets).
*
*               blk_align           Alignment of memory pool blocks to initialize (in octets).
*
*               poctets_reqd        Pointer to a variable to ... :
*
*                                       (a) Return the number of octets required to successfully
*                                               allocate the memory pool, if any errors;
*                                       (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_NULL_PTR                Argument 'pmem_pool' passed a NULL
*                                                                       pointer.
*
*                               LIB_MEM_ERR_HEAP_NOT_FOUND          Heap   segment NOT found.
*                               LIB_MEM_ERR_HEAP_EMPTY              Heap   segment empty; NO available memory
*                                                                       from heap.
*                               LIB_MEM_ERR_SEG_EMPTY               Memory segment empty; NO available memory
*                                                                       from segment for memory pools.
*
*                               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.
*
* Return(s)   : none.
*
* Caller(s)   : Application.
*
* Note(s)     : (3) 'pmem_pool' MUST be passed a pointer to the address of a declared 'MEM_POOL' variable.
*
*               (4) Pointers to variables that return values MUST be initialized to return PRIOR to all
*                   other validation or function handling in case of any error(s).
*********************************************************************************************************
*/

#if (LIB_MEM_CFG_POOL_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)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
    CPU_SR        cpu_sr;
#endif
    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    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    i;


/*$PAGE*/
                                                                    /* Init octets req'd for err (see Note #4).         */
    if (poctets_reqd != (CPU_SIZE_T *)0) {
       *poctets_reqd  = (CPU_SIZE_T  )0;
    }


                                                                    /* -------------- VALIDATE MEM POOL --------------- */
    if (pmem_pool != (MEM_POOL *)0) {
                                                                    /* Init mem pool     for err (see Note #4).         */
        pmem_pool->Type             = (LIB_MEM_TYPE)LIB_MEM_TYPE_NONE;
        pmem_pool->SegPrevPtr       = (MEM_POOL   *)0;
        pmem_pool->SegNextPtr       = (MEM_POOL   *)0;
        pmem_pool->PoolPrevPtr      = (MEM_POOL   *)0;
        pmem_pool->PoolNextPtr      = (MEM_POOL   *)0;
        pmem_pool->PoolAddrStart    = (void       *)0;
        pmem_pool->PoolAddrEnd      = (void       *)0;
        pmem_pool->PoolPtrs         = (void      **)0;
        pmem_pool->PoolSize         = (CPU_SIZE_T  )0;
        pmem_pool->BlkAlign         = (CPU_SIZE_T  )0;
        pmem_pool->BlkSize          = (CPU_SIZE_T  )0;
        pmem_pool->BlkNbr           = (CPU_SIZE_T  )0;
        pmem_pool->BlkIx            = (MEM_POOL_IX )0;
        pmem_pool->SegAddr          = (void       *)0;
        pmem_pool->SegAddrNextAvail = (void       *)0;
        pmem_pool->SegSizeTot       = (CPU_SIZE_T  )0;
        pmem_pool->SegSizeRem       = (CPU_SIZE_T  )0;

    } else {
       *perr = LIB_MEM_ERR_NULL_PTR;
        return;
    }


    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) {
        blk_align = 1;
    }

                                                                    /* ------------ 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;

    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;

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

        size_tot = size_tot_ptrs + size_tot_pool;
        size_rem = pmem_pool_heap->SegSizeRem;

        if (size_tot > size_rem) {
            CPU_CRITICAL_EXIT();
           *perr = LIB_MEM_ERR_HEAP_EMPTY;

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


    } else {                                                        /* Else cfg mem pool from dedicated mem.            */

        pmem_base_addr_start = (CPU_INT08U *)pmem_base_addr;
        pmem_base_addr_end   = (CPU_INT08U *)pmem_base_addr + mem_size - 1;

        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) &&
                (mem_size       == pmem_pool_next->SegSizeTot)) {

                 pmem_pool_blk   = pmem_pool_next;
                 pmem_pool_prev  = pmem_pool_next;
                 break;

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

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

                                                                    /* New mem seg overlaps cur mem seg.                */
                } 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;
                    return;
                }
            }
                                                                    /* If mem seg NOT found, adv to next mem seg.       */
            pmem_pool_prev = pmem_pool_next;
            pmem_pool_next = pmem_pool_next->SegNextPtr;
        }

⌨️ 快捷键说明

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