| 
 
 
 前言
   环形队列,链表,内存管理,这些典型的数据缓存处理方式   作为一个开发者是应该掌握的知识点   由于后面的文章涉及到了内存管理   故,这节先说一下内存管理 uCOSII中的内存管理源码
   我把uCOS中的内存管理程序拷贝出来了 
 
 
   OS_MEM.C /* ********************************************************************************************************* *                                                uC/OS-II *                                          The Real-Time Kernel *                                            MEMORY MANAGEMENT * *                        (c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL *                                           All Rights Reserved * *                                                  V2.00 * * File : OS_MEM.C * By   : Jean J. Labrosse ********************************************************************************************************* */ 
 #define  OS_MEM_C_ #include "OS_MEM.h" 
 
 //#if OS_MEM_EN && OS_MAX_MEM_PART >= 2 /* ********************************************************************************************************* *                                         LOCAL GLOBAL VARIABLES ********************************************************************************************************* */ 
 static  OS_MEM      *OSMemFreeList;            /* Pointer to free list of memory partitions            */ static  OS_MEM       OSMemTbl[OS_MAX_MEM_PART];/* Storage for memory partition manager                 */ /*$PAGE*/ 
 
 /* ********************************************************************************************************* *                                        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. * *               err      is a pointer to a variable containing an error message which will be set by *                        this function to either: *              *                        OS_NO_ERR            if the memory partition has been created correctly. *                        OS_MEM_INVALID_PART  no free partitions available *                        OS_MEM_INVALID_BLKS  user specified an invalid number of blocks (must be >= 2) *                        OS_MEM_INVALID_SIZE  user specified an invalid block size  *                                             (must be greater than the size of a pointer) * 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 *err) {     OS_MEM  *pmem;     INT8U   *pblk;     void   **plink;     INT32U   i;     //注意这里 (INT8U *)addr 和 (INT8U)*addr 完全不同啊啊,前者 addr是指向的一个地址,而这个地址内数据不知道是什么类型的     //所以(INT8U *)说明这个地址的内容是INT8U型的,(INT8U *)addr 表示的是一个新的  addr,而后面(INT8U)*addr 表示把 *addr转换成     //一个八位的无符号整形数据              if (nblks < 2) {                                  /* Must have at least 2 blocks per partition      */         *err = OS_MEM_INVALID_BLKS;         return ((OS_MEM *)0);     }     if (blksize < sizeof(void *)) {                   /* Must contain space for at least a pointer      */         *err = OS_MEM_INVALID_SIZE;         return ((OS_MEM *)0);     } //    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             */         *err = OS_MEM_INVALID_PART;         return ((OS_MEM *)0);     } 
     plink = (void **)addr;                            /* Create linked list of free memory blocks      */ 
     pblk  = (INT8U *)addr + blksize;               for (i = 0; i < (nblks - 1); i++) {         *plink = (void *)pblk;         plink  = (void **)pblk;         pblk   = pblk + blksize;     }     *plink = (void *)0;                               /* Last memory block points to NULL              */ //    OS_ENTER_CRITICAL();     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        */ //    OS_EXIT_CRITICAL();     *err   = OS_NO_ERR;     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 * *               err     is a pointer to a variable containing an error message which will be set by this *                       function to either: * *                       OS_NO_ERR           if the memory partition has been created correctly. *                       OS_MEM_NO_FREE_BLKS if there are no more free memory blocks to allocate to caller * * 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 *err) {     void    *pblk; 
 //    OS_ENTER_CRITICAL();     if (pmem->OSMemNFree > 0) {                       /* 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();         *err = OS_NO_ERR;                             /*      No error                                 */         return (pblk);                                /*      Return memory block to caller            */     } else { //        OS_EXIT_CRITICAL();         *err = OS_MEM_NO_FREE_BLKS;                   /* No,  Notify caller of empty memory partition  */         return ((void *)0);                           /*      Return NULL pointer to caller            */     } } /*$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 ********************************************************************************************************* */ 
 void OSMemInit (void) {     OS_MEM  *pmem;     INT16U   i; 
 
     pmem = (OS_MEM *)&OSMemTbl[0];                    /* Point to memory control block (MCB)           */     for (i = 0; i < (OS_MAX_MEM_PART - 1); i++) {     /* Init. list of free memory partitions          */         pmem->OSMemFreeList = (void *)&OSMemTbl[i+1]; /* Chain list of free partitions                 */         pmem->OSMemAddr     = (void *)0;              /* Store start address of memory partition       */         pmem->OSMemNFree    = 0;                      /* No free blocks                                */         pmem->OSMemNBlks    = 0;                      /* No blocks                                     */         pmem->OSMemBlkSize  = 0;                      /* Zero size                                     */         pmem++;     }     OSMemTbl[OS_MAX_MEM_PART - 1].OSMemFreeList = (void *)0;     OSMemFreeList                               = (OS_MEM *)&OSMemTbl[0]; } /*$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_NO_ERR         if the memory block was inserted into the partition *               OS_MEM_FULL       if you are returning a memory block to an already FULL memory partition *                                 (You freed more blocks than you allocated!) ********************************************************************************************************* */ 
 INT8U OSMemPut (OS_MEM  *pmem, void *pblk) { //    OS_ENTER_CRITICAL();     if (pmem->OSMemNFree >= pmem->OSMemNBlks) {  /* Make sure all blocks not already returned          */ //        OS_EXIT_CRITICAL();         return (OS_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_NO_ERR);                          /* 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 * *               pdata   is a pointer to a structure that will contain information about the memory *                       partition. * * Returns     : OS_NO_ERR         Always returns no error. ********************************************************************************************************* */ 
 INT8U OSMemQuery (OS_MEM *pmem, OS_MEM_DATA *ppdata) { //    OS_ENTER_CRITICAL();     ppdata->OSAddr     = pmem->OSMemAddr;     ppdata->OSFreeList = pmem->OSMemFreeList;     ppdata->OSBlkSize  = pmem->OSMemBlkSize;     ppdata->OSNBlks    = pmem->OSMemNBlks;     ppdata->OSNFree    = pmem->OSMemNFree; //    OS_EXIT_CRITICAL();     ppdata->OSNUsed    = ppdata->OSNBlks - ppdata->OSNFree;     return (OS_NO_ERR);                          } //#endif   
 
 
   OS_MEM.h#ifndef OS_MEM_H_ #define OS_MEM_H_
 #include "stm32f10x.h"
 
 #ifndef OS_MEM_C_
 #define OS_MEM_Cx_  extern
 #else
 #define OS_MEM_Cx_
 #endif
 
 #define OS_MAX_MEM_PART           4
 
 
 #define OS_NO_ERR                 0
 #define OS_MEM_INVALID_PART     110
 #define OS_MEM_INVALID_BLKS     111
 #define OS_MEM_INVALID_SIZE     112
 #define OS_MEM_NO_FREE_BLKS     113
 #define OS_MEM_FULL             114
 
 
 typedef unsigned char  INT8U;         //无符号8位数
 typedef unsigned int   INT16U;        //无符号16位数
 typedef unsigned long  INT32U;        //无符号32位数
 
 
 typedef struct {                       /* MEMORY CONTROL BLOCK                                         */
 void   *OSMemAddr;                 /* Pointer to beginning of memory partition                     */
 void   *OSMemFreeList;             /* Pointer to list of free memory blocks                        */
 INT32U  OSMemBlkSize;              /* Size (in bytes) of each block of memory                      */
 INT32U  OSMemNBlks;                /* Total number of blocks in this partition                     */
 INT32U  OSMemNFree;                /* Number of memory blocks remaining in this partition          */
 } OS_MEM;
 
 
 typedef struct {
 void   *OSAddr;                    /* Pointer to the beginning address of the memory partition     */
 void   *OSFreeList;                /* Pointer to the beginning of the free list of memory blocks   */
 INT32U  OSBlkSize;                 /* Size (in bytes) of each memory block                         */
 INT32U  OSNBlks;                   /* Total number of blocks in the partition                      */
 INT32U  OSNFree;                   /* Number of memory blocks free                                 */
 INT32U  OSNUsed;                   /* Number of memory blocks used                                 */
 } OS_MEM_DATA;
 
 
 OS_MEM *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *err);
 void *OSMemGet (OS_MEM *pmem, INT8U *err);
 void OSMemInit (void);
 INT8U OSMemPut (OS_MEM  *pmem, void *pblk);
 INT8U OSMemQuery (OS_MEM *pmem, OS_MEM_DATA *ppdata);
 
 
 
 #endif
 
 
 
 
 
 
 
 uCOSII提供的内存管理实质
   一,实际上就是用一些程序对一个二维的数组进行管理
 
 
   二,整个数组叫做 "内存分区" 
   三,数组的行数代表内存块的个数
 
   四,数组的每一行叫做 "内存块",每一行的长度叫做内存块长度 
   五,申请内存块,实际上就是返回数组某一行的首地址, 
     咱可以把数据存储到那一行里面! 
   六,每一次申请内存块的时候,内部会判断哪一行没有被申请过  
     然后把哪一行的首地址返回过来 使用
   一,创建内存   定义了一个二维数组,行数20(20个内存块)   列数16(每一个内存块最大存储16个数据) 
 
   二,申请一个内存块 
 
 
   三,往内存块里面存储数据 
 
 
 
     实际上就是存储到了那个二维数组里面     现在数组的第一行存储了数据 
 
 
 
 
 
   四,再申请一个,再存储数据 
 
     现在数组的第二行存储了数据 
 
 
 
 
 
 
 
 
   四,使用存储的数据     操作存储数据的首地址即可 
 
 
 
 
 
 总结
   μCOS-II提供的内存管理实际上就是对一个二维的数组进行管理   事先先定义好内存块,和每个内存块长度   二维数组的行数代表内存块个数   二维数组的列数代表每个内存块的长度      申请内存块其实就是内部程序判断数组哪一行没有使用过   然后返回那一行的首地址   然后咱就可以往里面存数据注意   往里面存储数据的时候不得超出内存块长度(数组每一行的列数)   有人可能会问,如果我有很大的数据量呢??   办法1.用多个内存块存储   办法2.设置内存块的长度足够长 补充1(释放使用的内存块)
   咱使用完某一个内存块存储的数据以后需要告诉内部程序   释放这个内存块,以便这个内存块可以再次被申请使用   OSMemPut (OS_MEM  *pmem, void *pblk)   第一个参数: 内存指针   第二个参数:内存块指针 
 
 
 
 
 
 
 补充2(查询内存分区信息)
 
 
 
 
 
 
 
 
 
 
 |