zoukankan      html  css  js  c++  java
  • uC/OS-II 函数之内存管理相关函数

    上文主要介绍了邮箱管理相关的函数,本文介绍内存管理相关的函数:OSMemCreate()内存块创建函数,OSMemGet()函数,OSMemPut()函数,OSMemQuery()函数.以前用过的uC/OS-II笔记分享到这里。

    内存管理介绍

    在ANSI C中可以用malloc()和free()两个函数动态地分配内存和释放内存。但是,在嵌入式实时操作系统中,多次这样做会把原来很大的一块连续内存区域,逐渐地分割成许多非常小而且彼此又不相邻的内存区域,也就是内存碎片。由于这些碎片的大量存在,使得程序到后来连非常小的内存也分配不到。另外,由于内存管理算法的原因,malloc()和free()函数执行时间是不确定的。
    在μC/OS-II中,操作系统把连续的大块内存按分区来管理。每个分区中包含有整数个大小相同的内存块。利用这种机制,μC/OS-II 对malloc()和free()函数进行了改进,使得它们可以分配和释放固定大小的内存块。这样一来,malloc()和free()函数的执行时间也是固定的了。
    在一个系统中可以有多个内存分区。这样,用户的应用程序就可以从不同的内存分区中得到不同大小的内存块。但是,特定的内存块在释放时必须重新放回它以前所属于的内存分区。显然,采用这样的内存管理算法,上面的内存碎片问题就得到了解决。

    为了便于内存的管理,在μC/OS-II中使用内存控制块(memory control blocks)的数据结构来跟踪每一个内存分区,系统中的每个内存分区都有它自己的内存控制块。
    内存控制块的定义如下:
    typedef struct {
    void *OSMemAddr; //指向内存分区起始地址的指针
    void *OSMemFreeList; //是指向下一个空闲内存控制块或者下一个空闲的内存块的指针
    INT32U OSMemBlkSize; //是内存分区中内存块的大小
    INT32U OSMemNBlks; //内存分区中总的内存块数量
    INT32U OSMemNFree; //内存分区中当前可以得空闲内存块数量
    } OS_MEM;
    如果要在μC/OS-II中使用内存管理,需要在OS_CFG.H文件中将开关量OS_MEM_EN设置为1。这样μC/OS-II 在启动时就会对内存管理器进行初始化[由OSInit()调用OSMemInit()实现]。常数OS_MAX_MEM_PART(见文件OS_CFG.H)定义了最大的内存分区数,该常数值最小应为2。

    注意的事项

    使用内存管理模块需要做的工作还有:
    1.打开配置文件OS_CFG.H,将开关量OS_MEM_EN设置为1:
    #define OS_MEM_EN 0
    2.打开配置文件OS_CFG.H,设置系统要建立的任务分区的数量:
    #define OS_MAX_MEM_PART 2

    OSMemCreate()内存块创建函数

    1 主要作用: 该函数建立并初始化一个用于动态内存分配的区域,该内存区域包含指定数目的、大小确定的内存块。应用可以动态申请这些内存块并在用完后将其释放回这个内存区域。该函数的返回值就是指向这个内存区域控制块的指针,并作为OSMemGet(),OSMemPut(),OSMemQuery() 等相关调用的参数。
    2函数原型:OS_MEM *OSMemCreate( void *addr, INT32U nblks, INT32U blksize, INT8U *err );
    3参数说明:addr 建立的内存区域的起始地址。可以使用静态数组或在系统初始化时使用 malloc() 函数来分配这个区域的空间。
    nblks 内存块的数目。每一个内存区域最少需要定义两个内存块。
    blksize 每个内存块的大小,最小应该能够容纳一个指针变量。
    err 是指向包含错误码的变量的指针。Err可能是如下几种情况:
    OS_NO_ERR :成功建立内存区域。
    OS_MEM_INVALID_ADDR :非法地址,即地址为空指针。
    OS_MEM_INVALID_PART :没有空闲的内存区域。
    OS_MEM_INVALID_BLKS :没有为内存区域建立至少两个内存块。
    OS_MEM_INVALID_SIZE :内存块大小不足以容纳一个指针变量。
    5、函数主体在os_men.c中
    4返回值说明:
    OSMemCreate() 函数返回指向所创建的内存区域控制块的指针。如果创建失败,函数返回空指针。

    OSMemGet()函数

    1 主要作用: 该函数用于从内存区域分配一个内存块。用户程序必须知道所建立的内存块的大小,并必须在使用完内存块后释放它。可以多次调用 OSMemGet() 函数。它的返回值就是指向所分配内存块的指针,并作为 OSMemPut() 函数的参数。
    2函数原型:void *OSMemGet(OS_MEM *pmem, INT8U *err);
    3参数说明:pmem 是指向内存区域控制块的指针,可以从 OSMemCreate() 函数的返回值中得到。
    err 是指向包含错误码的变量的指针。Err可能是如下情况:
    OS_NO_ERR :成功得到一个内存块。
    OS_MEM_NO_FREE_BLKS :内存区域中已经没有足够的内存块。
    4返回值说明:
    OSMemGet() 函数返回指向所分配内存块的指针。如果没有可分配的内存块,OSMemGet() 函数返回空指针。
    5、函数主体在os_men.c中

    OSMemPut()

    1 主要作用:该函数用于释放一个内存块,内存块必须释放回它原先所在的内存区域,否则会造成系统错误。
    2函数原型:INT8U OSMemPut (OS_MEM *pmem, void *pblk);
    3参数说明:pmem 是指向内存区域控制块的指针,可以从 OSMemCreate() 函数的返回值中得到。
    pblk 是指向将被释放的内存块的指针。
    4返回值说明:
    OSMemPut() 函数的返回值为下述之一:
    OS_NO_ERR :成功释放内存块
    OS_MEM_FULL :内存区域已满,不能再接受更多释放的内存块。这种情况说明用户程序出现了错误,释放了多于用 OSMemGet() 函数得到的内存块。
    5、函数主体在os_men.c中

    OSMemQuery()

    1 主要作用:该函数用于得到内存区域的信息。
    2函数原型:INT8U OSMemQuery(OS_MEM *pmem, OS_MEM_DATA pdata);
    3参数说明:pmem 是指向内存区域控制块的指针,可以从 OSMemCreate() 函数的返回值中得到。
    pdata 是一个指向 OS_MEM_DATA 数据结构的指针,该数据结构包含了以下的域:
    void OSAddr; /
    指向内存区域起始地址的指针 /
    void OSFreeList; /
    指向空闲内存块列表起始地址的指针 /
    INT32U OSBlkSize; /
    每个内存块的大小 /
    INT32U OSNBlks; /
    该内存区域中的内存块总数 /
    INT32U OSNFree; /
    空闲的内存块数目 /
    INT32U OSNUsed; /
    已使用的内存块数目 */
    4返回值说明:函数返回值总是OS_NO_ERR。
    5、函数主体在os_men.c中

    附os_men.c代码

    /*
    *********************************************************************************************************
    *                                                uC/OS-II
    *                                          The Real-Time Kernel
    *                                            MEMORY MANAGEMENT
    *
    *                              (c) Copyright 1992-2013, Micrium, Weston, FL
    *                                           All Rights Reserved
    *
    * File    : OS_MEM.C
    * By      : Jean J. Labrosse
    * Version : V2.92.08
    *
    * LICENSING TERMS:
    * ---------------
    *   uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
    * If you plan on using  uC/OS-II  in a commercial product you need to contact Micrium to properly license
    * its use in your product. We provide ALL the source code for your convenience and to help you experience
    * uC/OS-II.   The fact that the  source is provided does  NOT  mean that you can use it without  paying a
    * licensing fee.
    *********************************************************************************************************
    */
    
    #define  MICRIUM_SOURCE
    
    #ifndef  OS_MASTER_FILE
    #include <ucos_ii.h>
    #endif
    
    #if (OS_MEM_EN > 0u) && (OS_MAX_MEM_PART > 0u)
    /*
    *********************************************************************************************************
    *                                      CREATE A MEMORY PARTITION
    *
    * Description : Create a fixed-sized memory partition that will be managed by uC/OS-II.
    *
    * Arguments   : addr     is the starting address of the memory partition
    *
    *               nblks    is the number of memory blocks to create from the partition.
    *
    *               blksize  is the size (in bytes) of each block in the memory partition.
    *
    *               perr     is a pointer to a variable containing an error message which will be set by
    *                        this function to either:
    *
    *                        OS_ERR_NONE              if the memory partition has been created correctly.
    *                        OS_ERR_MEM_INVALID_ADDR  if you are specifying an invalid address for the memory
    *                                                 storage of the partition or, the block does not align
    *                                                 on a pointer boundary
    *                        OS_ERR_MEM_INVALID_PART  no free partitions available
    *                        OS_ERR_MEM_INVALID_BLKS  user specified an invalid number of blocks (must be >= 2)
    *                        OS_ERR_MEM_INVALID_SIZE  user specified an invalid block size
    *                                                   - must be greater than the size of a pointer
    *                                                   - must be able to hold an integral number of pointers
    * Returns    : != (OS_MEM *)0  is the partition was created
    *              == (OS_MEM *)0  if the partition was not created because of invalid arguments or, no
    *                              free partition is available.
    *********************************************************************************************************
    */
    
    OS_MEM  *OSMemCreate (void   *addr,
                          INT32U  nblks,
                          INT32U  blksize,
                          INT8U  *perr)
    {
        OS_MEM    *pmem;
        INT8U     *pblk;
        void     **plink;
        INT32U     loops;
        INT32U     i;
    #if OS_CRITICAL_METHOD == 3u                          /* Allocate storage for CPU status register      */
        OS_CPU_SR  cpu_sr = 0u;
    #endif
    
    
    
    #ifdef OS_SAFETY_CRITICAL
        if (perr == (INT8U *)0) {
            OS_SAFETY_CRITICAL_EXCEPTION();
            return ((OS_MEM *)0);
        }
    #endif
    
    #ifdef OS_SAFETY_CRITICAL_IEC61508
        if (OSSafetyCriticalStartFlag == OS_TRUE) {
            OS_SAFETY_CRITICAL_EXCEPTION();
            return ((OS_MEM *)0);
        }
    #endif
    
    #if OS_ARG_CHK_EN > 0u
        if (addr == (void *)0) {                          /* Must pass a valid address for the memory part.*/
            *perr = OS_ERR_MEM_INVALID_ADDR;
            return ((OS_MEM *)0);
        }
        if (((INT32U)addr & (sizeof(void *) - 1u)) != 0u){  /* Must be pointer size aligned                */
            *perr = OS_ERR_MEM_INVALID_ADDR;
            return ((OS_MEM *)0);
        }
        if (nblks < 2u) {                                 /* Must have at least 2 blocks per partition     */
            *perr = OS_ERR_MEM_INVALID_BLKS;
            return ((OS_MEM *)0);
        }
        if (blksize < sizeof(void *)) {                   /* Must contain space for at least a pointer     */
            *perr = OS_ERR_MEM_INVALID_SIZE;
            return ((OS_MEM *)0);
        }
    #endif
        OS_ENTER_CRITICAL();
        pmem = OSMemFreeList;                             /* Get next free memory partition                */
        if (OSMemFreeList != (OS_MEM *)0) {               /* See if pool of free partitions was empty      */
            OSMemFreeList = (OS_MEM *)OSMemFreeList->OSMemFreeList;
        }
        OS_EXIT_CRITICAL();
        if (pmem == (OS_MEM *)0) {                        /* See if we have a memory partition             */
            *perr = OS_ERR_MEM_INVALID_PART;
            return ((OS_MEM *)0);
        }
        plink = (void **)addr;                            /* Create linked list of free memory blocks      */
        pblk  = (INT8U *)addr;
        loops  = nblks - 1u;
        for (i = 0u; i < loops; i++) {
            pblk +=  blksize;                             /* Point to the FOLLOWING block                  */
           *plink = (void  *)pblk;                        /* Save pointer to NEXT block in CURRENT block   */
            plink = (void **)pblk;                        /* Position to  NEXT      block                  */
        }
        *plink              = (void *)0;                  /* Last memory block points to NULL              */
        pmem->OSMemAddr     = addr;                       /* Store start address of memory partition       */
        pmem->OSMemFreeList = addr;                       /* Initialize pointer to pool of free blocks     */
        pmem->OSMemNFree    = nblks;                      /* Store number of free blocks in MCB            */
        pmem->OSMemNBlks    = nblks;
        pmem->OSMemBlkSize  = blksize;                    /* Store block size of each memory blocks        */
        *perr               = OS_ERR_NONE;
        return (pmem);
    }
    /*$PAGE*/
    /*
    *********************************************************************************************************
    *                                         GET A MEMORY BLOCK
    *
    * Description : Get a memory block from a partition
    *
    * Arguments   : pmem    is a pointer to the memory partition control block
    *
    *               perr    is a pointer to a variable containing an error message which will be set by this
    *                       function to either:
    *
    *                       OS_ERR_NONE             if the memory partition has been created correctly.
    *                       OS_ERR_MEM_NO_FREE_BLKS if there are no more free memory blocks to allocate to caller
    *                       OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem'
    *
    * Returns     : A pointer to a memory block if no error is detected
    *               A pointer to NULL if an error is detected
    *********************************************************************************************************
    */
    
    void  *OSMemGet (OS_MEM  *pmem,
                     INT8U   *perr)
    {
        void      *pblk;
    #if OS_CRITICAL_METHOD == 3u                          /* Allocate storage for CPU status register      */
        OS_CPU_SR  cpu_sr = 0u;
    #endif
    
    
    
    #ifdef OS_SAFETY_CRITICAL
        if (perr == (INT8U *)0) {
            OS_SAFETY_CRITICAL_EXCEPTION();
            return ((void *)0);
        }
    #endif
    
    #if OS_ARG_CHK_EN > 0u
        if (pmem == (OS_MEM *)0) {                        /* Must point to a valid memory partition        */
            *perr = OS_ERR_MEM_INVALID_PMEM;
            return ((void *)0);
        }
    #endif
        OS_ENTER_CRITICAL();
        if (pmem->OSMemNFree > 0u) {                      /* See if there are any free memory blocks       */
            pblk                = pmem->OSMemFreeList;    /* Yes, point to next free memory block          */
            pmem->OSMemFreeList = *(void **)pblk;         /*      Adjust pointer to new free list          */
            pmem->OSMemNFree--;                           /*      One less memory block in this partition  */
            OS_EXIT_CRITICAL();
            *perr = OS_ERR_NONE;                          /*      No error                                 */
            return (pblk);                                /*      Return memory block to caller            */
        }
        OS_EXIT_CRITICAL();
        *perr = OS_ERR_MEM_NO_FREE_BLKS;                  /* No,  Notify caller of empty memory partition  */
        return ((void *)0);                               /*      Return NULL pointer to caller            */
    }
    /*$PAGE*/
    /*
    *********************************************************************************************************
    *                                 GET THE NAME OF A MEMORY PARTITION
    *
    * Description: This function is used to obtain the name assigned to a memory partition.
    *
    * Arguments  : pmem      is a pointer to the memory partition
    *
    *              pname     is a pointer to a pointer to an ASCII string that will receive the name of the memory partition.
    *
    *              perr      is a pointer to an error code that can contain one of the following values:
    *
    *                        OS_ERR_NONE                if the name was copied to 'pname'
    *                        OS_ERR_MEM_INVALID_PMEM    if you passed a NULL pointer for 'pmem'
    *                        OS_ERR_PNAME_NULL          You passed a NULL pointer for 'pname'
    *                        OS_ERR_NAME_GET_ISR        You called this function from an ISR
    *
    * Returns    : The length of the string or 0 if 'pmem' is a NULL pointer.
    *********************************************************************************************************
    */
    
    #if OS_MEM_NAME_EN > 0u
    INT8U  OSMemNameGet (OS_MEM   *pmem,
                         INT8U   **pname,
                         INT8U    *perr)
    {
        INT8U      len;
    #if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */
        OS_CPU_SR  cpu_sr = 0u;
    #endif
    
    
    
    #ifdef OS_SAFETY_CRITICAL
        if (perr == (INT8U *)0) {
            OS_SAFETY_CRITICAL_EXCEPTION();
            return (0u);
        }
    #endif
    
    #if OS_ARG_CHK_EN > 0u
        if (pmem == (OS_MEM *)0) {                   /* Is 'pmem' a NULL pointer?                          */
            *perr = OS_ERR_MEM_INVALID_PMEM;
            return (0u);
        }
        if (pname == (INT8U **)0) {                  /* Is 'pname' a NULL pointer?                         */
            *perr = OS_ERR_PNAME_NULL;
            return (0u);
        }
    #endif
        if (OSIntNesting > 0u) {                     /* See if trying to call from an ISR                  */
            *perr = OS_ERR_NAME_GET_ISR;
            return (0u);
        }
        OS_ENTER_CRITICAL();
        *pname = pmem->OSMemName;
        len    = OS_StrLen(*pname);
        OS_EXIT_CRITICAL();
        *perr  = OS_ERR_NONE;
        return (len);
    }
    #endif
    
    /*$PAGE*/
    /*
    *********************************************************************************************************
    *                                 ASSIGN A NAME TO A MEMORY PARTITION
    *
    * Description: This function assigns a name to a memory partition.
    *
    * Arguments  : pmem      is a pointer to the memory partition
    *
    *              pname     is a pointer to an ASCII string that contains the name of the memory partition.
    *
    *              perr      is a pointer to an error code that can contain one of the following values:
    *
    *                        OS_ERR_NONE                if the name was copied to 'pname'
    *                        OS_ERR_MEM_INVALID_PMEM    if you passed a NULL pointer for 'pmem'
    *                        OS_ERR_PNAME_NULL          You passed a NULL pointer for 'pname'
    *                        OS_ERR_MEM_NAME_TOO_LONG   if the name doesn't fit in the storage area
    *                        OS_ERR_NAME_SET_ISR        if you called this function from an ISR
    *
    * Returns    : None
    *********************************************************************************************************
    */
    
    #if OS_MEM_NAME_EN > 0u
    void  OSMemNameSet (OS_MEM  *pmem,
                        INT8U   *pname,
                        INT8U   *perr)
    {
    #if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */
        OS_CPU_SR  cpu_sr = 0u;
    #endif
    
    
    
    #ifdef OS_SAFETY_CRITICAL
        if (perr == (INT8U *)0) {
            OS_SAFETY_CRITICAL_EXCEPTION();
            return;
        }
    #endif
    
    #if OS_ARG_CHK_EN > 0u
        if (pmem == (OS_MEM *)0) {                   /* Is 'pmem' a NULL pointer?                          */
            *perr = OS_ERR_MEM_INVALID_PMEM;
            return;
        }
        if (pname == (INT8U *)0) {                   /* Is 'pname' a NULL pointer?                         */
            *perr = OS_ERR_PNAME_NULL;
            return;
        }
    #endif
        if (OSIntNesting > 0u) {                     /* See if trying to call from an ISR                  */
            *perr = OS_ERR_NAME_SET_ISR;
            return;
        }
        OS_ENTER_CRITICAL();
        pmem->OSMemName = pname;
        OS_EXIT_CRITICAL();
        *perr           = OS_ERR_NONE;
    }
    #endif
    
    /*$PAGE*/
    /*
    *********************************************************************************************************
    *                                       RELEASE A MEMORY BLOCK
    *
    * Description : Returns a memory block to a partition
    *
    * Arguments   : pmem    is a pointer to the memory partition control block
    *
    *               pblk    is a pointer to the memory block being released.
    *
    * Returns     : OS_ERR_NONE              if the memory block was inserted into the partition
    *               OS_ERR_MEM_FULL          if you are returning a memory block to an already FULL memory
    *                                        partition (You freed more blocks than you allocated!)
    *               OS_ERR_MEM_INVALID_PMEM  if you passed a NULL pointer for 'pmem'
    *               OS_ERR_MEM_INVALID_PBLK  if you passed a NULL pointer for the block to release.
    *********************************************************************************************************
    */
    
    INT8U  OSMemPut (OS_MEM  *pmem,
                     void    *pblk)
    {
    #if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */
        OS_CPU_SR  cpu_sr = 0u;
    #endif
    
    
    
    #if OS_ARG_CHK_EN > 0u
        if (pmem == (OS_MEM *)0) {                   /* Must point to a valid memory partition             */
            return (OS_ERR_MEM_INVALID_PMEM);
        }
        if (pblk == (void *)0) {                     /* Must release a valid block                         */
            return (OS_ERR_MEM_INVALID_PBLK);
        }
    #endif
        OS_ENTER_CRITICAL();
        if (pmem->OSMemNFree >= pmem->OSMemNBlks) {  /* Make sure all blocks not already returned          */
            OS_EXIT_CRITICAL();
            return (OS_ERR_MEM_FULL);
        }
        *(void **)pblk      = pmem->OSMemFreeList;   /* Insert released block into free block list         */
        pmem->OSMemFreeList = pblk;
        pmem->OSMemNFree++;                          /* One more memory block in this partition            */
        OS_EXIT_CRITICAL();
        return (OS_ERR_NONE);                        /* Notify caller that memory block was released       */
    }
    /*$PAGE*/
    /*
    *********************************************************************************************************
    *                                       QUERY MEMORY PARTITION
    *
    * Description : This function is used to determine the number of free memory blocks and the number of
    *               used memory blocks from a memory partition.
    *
    * Arguments   : pmem        is a pointer to the memory partition control block
    *
    *               p_mem_data  is a pointer to a structure that will contain information about the memory
    *                           partition.
    *
    * Returns     : OS_ERR_NONE               if no errors were found.
    *               OS_ERR_MEM_INVALID_PMEM   if you passed a NULL pointer for 'pmem'
    *               OS_ERR_MEM_INVALID_PDATA  if you passed a NULL pointer to the data recipient.
    *********************************************************************************************************
    */
    
    #if OS_MEM_QUERY_EN > 0u
    INT8U  OSMemQuery (OS_MEM       *pmem,
                       OS_MEM_DATA  *p_mem_data)
    {
    #if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */
        OS_CPU_SR  cpu_sr = 0u;
    #endif
    
    
    
    #if OS_ARG_CHK_EN > 0u
        if (pmem == (OS_MEM *)0) {                   /* Must point to a valid memory partition             */
            return (OS_ERR_MEM_INVALID_PMEM);
        }
        if (p_mem_data == (OS_MEM_DATA *)0) {        /* Must release a valid storage area for the data     */
            return (OS_ERR_MEM_INVALID_PDATA);
        }
    #endif
        OS_ENTER_CRITICAL();
        p_mem_data->OSAddr     = pmem->OSMemAddr;
        p_mem_data->OSFreeList = pmem->OSMemFreeList;
        p_mem_data->OSBlkSize  = pmem->OSMemBlkSize;
        p_mem_data->OSNBlks    = pmem->OSMemNBlks;
        p_mem_data->OSNFree    = pmem->OSMemNFree;
        OS_EXIT_CRITICAL();
        p_mem_data->OSNUsed    = p_mem_data->OSNBlks - p_mem_data->OSNFree;
        return (OS_ERR_NONE);
    }
    #endif                                           /* OS_MEM_QUERY_EN                                    */
    /*$PAGE*/
    /*
    *********************************************************************************************************
    *                                 INITIALIZE MEMORY PARTITION MANAGER
    *
    * Description : This function is called by uC/OS-II to initialize the memory partition manager.  Your
    *               application MUST NOT call this function.
    *
    * Arguments   : none
    *
    * Returns     : none
    *
    * Note(s)    : This function is INTERNAL to uC/OS-II and your application should not call it.
    *********************************************************************************************************
    */
    
    void  OS_MemInit (void)
    {
    #if OS_MAX_MEM_PART == 1u
        OS_MemClr((INT8U *)&OSMemTbl[0], sizeof(OSMemTbl));   /* Clear the memory partition table          */
        OSMemFreeList               = (OS_MEM *)&OSMemTbl[0]; /* Point to beginning of free list           */
    #if OS_MEM_NAME_EN > 0u
        OSMemFreeList->OSMemName    = (INT8U *)"?";           /* Unknown name                              */
    #endif
    #endif
    
    #if OS_MAX_MEM_PART >= 2u
        OS_MEM  *pmem;
        INT16U   i;
    
    
        OS_MemClr((INT8U *)&OSMemTbl[0], sizeof(OSMemTbl));   /* Clear the memory partition table          */
        for (i = 0u; i < (OS_MAX_MEM_PART - 1u); i++) {       /* Init. list of free memory partitions      */
            pmem                = &OSMemTbl[i];               /* Point to memory control block (MCB)       */
            pmem->OSMemFreeList = (void *)&OSMemTbl[i + 1u];  /* Chain list of free partitions             */
    #if OS_MEM_NAME_EN > 0u
            pmem->OSMemName  = (INT8U *)(void *)"?";
    #endif
        }
        pmem                = &OSMemTbl[i];
        pmem->OSMemFreeList = (void *)0;                      /* Initialize last node                      */
    #if OS_MEM_NAME_EN > 0u
        pmem->OSMemName = (INT8U *)(void *)"?";
    #endif
    
        OSMemFreeList   = &OSMemTbl[0];                       /* Point to beginning of free list           */
    #endif
    }
    #endif                                                    /* OS_MEM_EN                                 */
    
    
  • 相关阅读:
    洛谷[ZJOI2008]骑士(基环树二次DP法+树形DP)
    洛谷P5022 旅行(基环树+断环法)
    AtCoder Beginner Contest 174 ——D.Alter Altar(思维)
    洛谷P1972 [SDOI2009]HH的项链(离线+树状数组)
    CF1365D Solve The Maze (BFS)
    codeforces1426——F. Number of Subsequences(DP)
    codeforces1324——E.Sleeping Schedule(DP+初始化)
    codeforces319——B. Psychos in a Line(思维+单调栈)
    codeforces292——D. Connected Components(并查集+前缀和优化)
    codeforces1013——D. Chemical table(思维+转化+并查集)
  • 原文地址:https://www.cnblogs.com/onepeace/p/4850705.html
Copyright © 2011-2022 走看看