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

📄 lib_mem.c

📁 飞思卡尔HCS12的OS移植(ucosII),实现了三个任务,IDE:CODEWARRIOR
💻 C
📖 第 1 页 / 共 4 页
字号:

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

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

    pmem_blk_end = (void *)((CPU_INT08U *)pmem_pool->PoolAddrEnd - pmem_pool->BlkSize + 1);

#if 0 /* !!!! */
    if ((pmem_addr < pmem_pool->PoolAddrStart) ||
        (pmem_addr > pmem_blk_end)) {
        CPU_CRITICAL_EXIT();
       *perr = LIB_MEM_ERR_INVALID_ADDR;
        return;
    }
#endif

#if (LIB_MEM_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
    if (Mem_PoolBlkCalcValidAddr(pmem_pool, pmem_addr) == DEF_FALSE) {
        CPU_CRITICAL_EXIT();
       *perr = LIB_MEM_ERR_INVALID_ADDR;
        return;
    }

    for (i = 0; i < pmem_pool->BlkIx; i++) {
        if (pmem_pool->PoolPtrs[i] == pmem_addr) {
            CPU_CRITICAL_EXIT();
           *perr = LIB_MEM_ERR_INVALID_ADDR;
            return;
        }
    }
#endif

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

   *perr = LIB_ERR_NONE;
}
#endif


/*$PAGE*/
/*
*********************************************************************************************************
*********************************************************************************************************
*                                           LOCAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                        Mem_PoolSegGetBlkSize()
*
* Description : (1) Calculates total memory segment size for number of blocks with specific size and alignment :
*
*
*                       -----                     ======================  ---
*                         ^       Mem Addr  --->  |  /  /  /  /  /  /  |   ^
*                         |    (see Note #1a)     | /  /  /  /  /  /  /|   |    Mem Align Offset
*                         |                       |/  /  /  /  /  /  / |   |  (see Notes #1e & #2a)
*                         |                       |  /  /  /  /  /  /  |   v
*                         |                       ======================  ---
*                         |                       |                    |   ^
*                         |                       |                    |   |
*                         |                       |     Mem Blk #1     |   |        Blk Size
*                         |                       |                    |   |     (see Note #1c)
*                         |                       |                    |   v
*                         |                       ----------------------  ---
*                         |                       |  /  /  /  /  /  /  |   ^
*                         |                       | /  /  /  /  /  /  /|   |    Blk Align Offset
*                         |                       |/  /  /  /  /  /  / |   |  (see Notes #1f & #2b)
*                         |                       |  /  /  /  /  /  /  |   v
*                                                 ======================  ---
*                     Total Size                  |         .          |
*                   (see Note #2c)                |         .          |
*                                                 |         .          |
*                         |                       ======================  ---
*                         |                       |                    |   ^
*                         |                       |                    |   |
*                         |                       |   Mem Blk #N - 1   |   |        Blk Size
*                         |                       |                    |   |     (see Note #1c)
*                         |                       |                    |   v
*                         |                       ----------------------  ---
*                         |                       |  /  /  /  /  /  /  |   ^
*                         |                       | /  /  /  /  /  /  /|   |    Blk Align Offset
*                         |                       |/  /  /  /  /  /  / |   |  (see Notes #1f & #2b)
*                         |                       |  /  /  /  /  /  /  |   v
*                         |                       ======================  ---
*                         |                       |                    |   ^
*                         |                       |                    |   |
*                         |                       |     Mem Blk #N     |   |        Blk Size
*                         |                       |                    |   |     (see Note #1c)
*                         v                       |                    |   v
*                       -----                     ======================  ---
*
*               where
*
*                   (a) Mem Addr            Memory address of the beginning of the memory block ('pmem_addr')
*
*                   (b) N                   Number of memory blocks to allocate ('blk_nbr')
*
*                   (c) Blk Size            Size   of memory block  to allocate ('blk_size')
*
*                   (d) Align               Required block memory alignment ('blk_align')
*
*                   (e) Mem Align Offset    Offset required to align first memory block
*
*                   (f) Blk Align Offset    Offset required to align every memory block
*
*
*               (2) The total size is computed based on the following expressions :
*
*                                          { (1) Align - (Mem Addr % Align) , if memory address is not aligned
*                   (a) Mem Align Offset = {
*                                          { (2) 0                          , if memory address is     aligned
*
*
*                                          { (1) Align - (Size     % Align) , if memory block   is not aligned
*                   (b) Blk Align Offset = {
*                                          { (2) 0                          , if memory block   is     aligned
*
*
*                   (c) Total Size = Mem Align Offset + ((Size + Blk Align Offset) * (N - 1)) + Size
*
*$PAGE*
* Argument(s) : pmem_addr   Memory address of the beginning of the memory block.
*
*               blk_nbr     Number of memory blocks to allocate.
*
*               blk_size    Size   of memory block  to allocate.
*
*               blk_align   Required block memory alignment (in octets).
*               ---------   Argument validated in Mem_PoolCreate().
*
* Return(s)   : Total size of memory segment used to allocate the number of blocks.
*
* Caller(s)   : Mem_PoolCreate().
*
* Note(s)     : none.
*********************************************************************************************************
*/

#if (LIB_MEM_CFG_POOL_EN == DEF_ENABLED)
static  CPU_SIZE_T  Mem_PoolSegCalcTotSize (void        *pmem_addr,
                                            CPU_SIZE_T   blk_nbr,
                                            CPU_SIZE_T   blk_size,
                                            CPU_SIZE_T   blk_align)
{
    CPU_SIZE_T  align_offset;
    CPU_SIZE_T  mem_align_offset;
    CPU_SIZE_T  blk_align_offset;
    CPU_SIZE_T  tot_size;

                                                                /* Calc mem align (see Note #2a).                       */
    align_offset = (CPU_ADDR)pmem_addr % blk_align;
    if (align_offset != 0) {
        mem_align_offset = blk_align - align_offset;
    } else {
        mem_align_offset = 0;
    }
                                                                /* Calc blk align (see Note #2b).                       */
    align_offset = blk_size % blk_align;
    if (align_offset != 0) {
        blk_align_offset = blk_align - align_offset;
    } else {
        blk_align_offset = 0;
    }
                                                                /* Calc tot size  (see Note #2c).                       */
    tot_size = mem_align_offset + ((blk_size + blk_align_offset) * (blk_nbr - 1)) + blk_size;

    return (tot_size);
}
#endif


/*$PAGE*/
/*
*********************************************************************************************************
*                                     Mem_PoolBlkCalcValidAddr()
*
* Description : Calculates if a given memory block address is valid for the memory pool.
*
* Argument(s) : pmem_pool   Pointer to memory pool structure to validate memory block address.
*               ---------   Argument validated in Mem_PoolBlkFree()
*
*               pmem_addr   Pointer to memory block address to validate.
*               ---------   Argument validated in Mem_PoolBlkFree()
*
* Return(s)   : DEF_TRUE, if NO errors.
*
*               DEF_FALSE, otherwise.
*
* Caller(s)   : Mem_PoolBlkFree().
*
* Note(s)     : only available if LIB_MEM_CFG_ARG_CHK_EXT_EN is enabled.
*********************************************************************************************************
*/

#if (LIB_MEM_CFG_POOL_EN        == DEF_ENABLED) && \
    (LIB_MEM_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
static  CPU_SIZE_T  Mem_PoolBlkCalcValidAddr (MEM_POOL  *pmem_pool,
                                              void      *pmem_addr)
{
    CPU_INT08U  *pmem_start;
    CPU_INT08U  *pmem_pool_addr;
    CPU_SIZE_T   align_offset;
    CPU_SIZE_T   mem_diff;
    CPU_SIZE_T   mem_align;
    CPU_SIZE_T   mem_align_offset;
    CPU_SIZE_T   blk_align;
    CPU_SIZE_T   blk_align_offset;
    CPU_SIZE_T   blk_size;


    if (pmem_pool->PoolAddrStart > pmem_addr) {
        return (DEF_FALSE);
    }

    blk_align      = (CPU_SIZE_T  )pmem_pool->BlkAlign;
    pmem_pool_addr = (CPU_INT08U *)pmem_pool->PoolAddrStart;
    align_offset   = (CPU_ADDR    )pmem_pool_addr % blk_align;
    if (align_offset != 0) {
        mem_align_offset = blk_align - align_offset;
    } else {
        mem_align_offset = 0;
    }

    blk_size     = pmem_pool->BlkSize;
    align_offset = blk_size % blk_align;
    if (align_offset != 0) {
        blk_align_offset = blk_align - align_offset;
    } else {
        blk_align_offset = 0;
    }

    pmem_start =  pmem_pool_addr + mem_align_offset;
    mem_align  =  blk_size + blk_align_offset;
    mem_diff   = (CPU_INT08U *)pmem_addr - pmem_start;

    if ((mem_diff % mem_align) == 0) {
        return (DEF_TRUE);
    } else {
        return (DEF_FALSE);
    }
}
#endif


/*$PAGE*/
/*
*********************************************************************************************************
*                                        Mem_PoolSegAlloc()
*
* Description : Allocates memory from specific segment.
*
* Argument(s) : pmem_pool   Pointer to memory pool structure containing segment information.
*               ---------   Argument validated in Mem_PoolCreate()
*
*               size        Size of memory to allocate.
*               ----        Argument validated in Mem_PoolCreate()
*
*               align       Required starting memory alignment (in octets).
*               -----       Argument validated in Mem_PoolCreate()
*
* Return(s)   : Pointer to allocated memory, if NO errors.
*
*               Pointer to NULL, otherwise.
*
* Caller(s)   : Mem_PoolCreate().
*
* Note(s)     : (1) Allocated memory from the specific segment is NEVER freed after allocation.
*********************************************************************************************************
*/

#if (LIB_MEM_CFG_POOL_EN == DEF_ENABLED)
static  void  *Mem_PoolSegAlloc  (MEM_POOL    *pmem_pool,
                                  CPU_SIZE_T   size,
                                  CPU_SIZE_T   align)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
    CPU_SR       cpu_sr;
#endif
    CPU_INT08U  *pmem_addr;
    CPU_SIZE_T   mem_align;
    CPU_SIZE_T   align_offset;
    CPU_SIZE_T   tot_size;
    CPU_SIZE_T   size_rem;


    CPU_CRITICAL_ENTER();
    pmem_addr = (CPU_INT08U *)pmem_pool->SegAddrNextAvail;      /* Get next avail addr in mem seg.                      */

    mem_align = ((CPU_ADDR)pmem_addr) % align;                  /* Calc mem align.                                      */

    if (mem_align != 0) {
        align_offset = align - mem_align;
    } else {
        align_offset = 0;
    }

    tot_size = align_offset + size;
    size_rem = pmem_pool->SegSizeRem;

    if (tot_size > size_rem) {                                  /* Do not alloc if size extends beyond mem seg.         */
        CPU_CRITICAL_EXIT();
        return ((void *)0);
    }

    pmem_addr += align_offset;                                  /* Adj mem addr align.                                  */

    pmem_pool->SegAddrNextAvail  = pmem_addr + size;            /* Advance next avail addr depending on alloc size.     */
    pmem_pool->SegSizeRem       -= tot_size;                    /* Adj rem mem seg size.                                */

    CPU_CRITICAL_EXIT();

    return ((void *)pmem_addr);
}
#endif

⌨️ 快捷键说明

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