OS_MEM.c
上传用户:jinguanrq
上传日期:2022-06-04
资源大小:724k
文件大小:11k
源码类别:

uCOS

开发平台:

C/C++

  1. /*
  2. *********************************************************************************************************
  3. *                                                uC/OS-II
  4. *                                          The Real-Time Kernel
  5. *                                            MEMORY MANAGEMENT
  6. *
  7. *                        (c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL
  8. *                                           All Rights Reserved
  9. *
  10. *                                                  V2.00
  11. *
  12. * File : OS_MEM.C
  13. * By   : Jean J. Labrosse
  14. *********************************************************************************************************
  15. */
  16. #ifndef  OS_MASTER_FILE
  17. #include "includes.h"
  18. #endif
  19. #if OS_MEM_EN && OS_MAX_MEM_PART >= 2
  20. /*
  21. *********************************************************************************************************
  22. *                                         LOCAL GLOBAL VARIABLES
  23. *********************************************************************************************************
  24. */
  25. static  OS_MEM      *OSMemFreeList;            /* Pointer to free list of memory partitions            */
  26. static  OS_MEM       OSMemTbl[OS_MAX_MEM_PART];/* Storage for memory partition manager                 */
  27. /*$PAGE*/
  28. /*
  29. *********************************************************************************************************
  30. *                                        CREATE A MEMORY PARTITION
  31. *
  32. * Description : Create a fixed-sized memory partition that will be managed by uC/OS-II.
  33. *
  34. * Arguments   : addr     is the starting address of the memory partition
  35. *
  36. *               nblks    is the number of memory blocks to create from the partition.
  37. *
  38. *               blksize  is the size (in bytes) of each block in the memory partition.
  39. *
  40. *               err      is a pointer to a variable containing an error message which will be set by
  41. *                        this function to either:
  42. *             
  43. *                        OS_NO_ERR            if the memory partition has been created correctly.
  44. *                        OS_MEM_INVALID_PART  no free partitions available
  45. *                        OS_MEM_INVALID_BLKS  user specified an invalid number of blocks (must be >= 2)
  46. *                        OS_MEM_INVALID_SIZE  user specified an invalid block size 
  47. *                                             (must be greater than the size of a pointer)
  48. * Returns    : != (OS_MEM *)0  is the partition was created 
  49. *              == (OS_MEM *)0  if the partition was not created because of invalid arguments or, no
  50. *                              free partition is available.
  51. *********************************************************************************************************
  52. */
  53. OS_MEM *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *err)
  54. {
  55.     OS_MEM  *pmem;
  56.     INT8U   *pblk;
  57.     void   **plink;
  58.     INT32U   i;
  59.     if (nblks < 2) {                                  /* Must have at least 2 blocks per partition      */
  60.         *err = OS_MEM_INVALID_BLKS;
  61.         return ((OS_MEM *)0);
  62.     }
  63.     if (blksize < sizeof(void *)) {                   /* Must contain space for at least a pointer      */
  64.         *err = OS_MEM_INVALID_SIZE;
  65.         return ((OS_MEM *)0);
  66.     }
  67.     OS_ENTER_CRITICAL();
  68.     pmem = OSMemFreeList;                             /* Get next free memory partition                */
  69.     if (OSMemFreeList != (OS_MEM *)0) {               /* See if pool of free partitions was empty      */
  70.         OSMemFreeList = (OS_MEM *)OSMemFreeList->OSMemFreeList;
  71.     }
  72.     OS_EXIT_CRITICAL();
  73.     if (pmem == (OS_MEM *)0) {                        /* See if we have a memory partition             */
  74.         *err = OS_MEM_INVALID_PART;
  75.         return ((OS_MEM *)0);
  76.     }
  77.     plink = (void **)addr;                            /* Create linked list of free memory blocks      */
  78.     pblk  = (INT8U *)addr + blksize;
  79.     for (i = 0; i < (nblks - 1); i++) {
  80.         *plink = (void *)pblk;
  81.         plink  = (void **)pblk;
  82.         pblk   = pblk + blksize;
  83.     }
  84.     *plink = (void *)0;                               /* Last memory block points to NULL              */
  85.     OS_ENTER_CRITICAL();
  86.     pmem->OSMemAddr     = addr;                       /* Store start address of memory partition       */
  87.     pmem->OSMemFreeList = addr;                       /* Initialize pointer to pool of free blocks     */
  88.     pmem->OSMemNFree    = nblks;                      /* Store number of free blocks in MCB            */
  89.     pmem->OSMemNBlks    = nblks;
  90.     pmem->OSMemBlkSize  = blksize;                    /* Store block size of each memory blocks        */
  91.     OS_EXIT_CRITICAL();
  92.     *err   = OS_NO_ERR;
  93.     return (pmem);
  94. }
  95. /*$PAGE*/
  96. /*
  97. *********************************************************************************************************
  98. *                                          GET A MEMORY BLOCK
  99. *
  100. * Description : Get a memory block from a partition
  101. *
  102. * Arguments   : pmem    is a pointer to the memory partition control block
  103. *
  104. *               err     is a pointer to a variable containing an error message which will be set by this
  105. *                       function to either:
  106. *
  107. *                       OS_NO_ERR           if the memory partition has been created correctly.
  108. *                       OS_MEM_NO_FREE_BLKS if there are no more free memory blocks to allocate to caller
  109. *
  110. * Returns     : A pointer to a memory block if no error is detected
  111. *               A pointer to NULL if an error is detected
  112. *********************************************************************************************************
  113. */
  114. void *OSMemGet (OS_MEM *pmem, INT8U *err)
  115. {
  116.     void    *pblk;
  117.     OS_ENTER_CRITICAL();
  118.     if (pmem->OSMemNFree > 0) {                       /* See if there are any free memory blocks       */
  119.         pblk                = pmem->OSMemFreeList;    /* Yes, point to next free memory block          */
  120.         pmem->OSMemFreeList = *(void **)pblk;         /*      Adjust pointer to new free list          */
  121.         pmem->OSMemNFree--;                           /*      One less memory block in this partition  */
  122.         OS_EXIT_CRITICAL();
  123.         *err = OS_NO_ERR;                             /*      No error                                 */
  124.         return (pblk);                                /*      Return memory block to caller            */
  125.     } else {
  126.         OS_EXIT_CRITICAL();
  127.         *err = OS_MEM_NO_FREE_BLKS;                   /* No,  Notify caller of empty memory partition  */
  128.         return ((void *)0);                           /*      Return NULL pointer to caller            */
  129.     }
  130. }
  131. /*$PAGE*/
  132. /*
  133. *********************************************************************************************************
  134. *                                    INITIALIZE MEMORY PARTITION MANAGER
  135. *
  136. * Description : This function is called by uC/OS-II to initialize the memory partition manager.  Your
  137. *               application MUST NOT call this function.
  138. *
  139. * Arguments   : none
  140. *
  141. * Returns     : none
  142. *********************************************************************************************************
  143. */
  144. void OSMemInit (void)
  145. {
  146.     OS_MEM  *pmem;
  147.     INT16U   i;
  148.     pmem = (OS_MEM *)&OSMemTbl[0];                    /* Point to memory control block (MCB)           */
  149.     for (i = 0; i < (OS_MAX_MEM_PART - 1); i++) {     /* Init. list of free memory partitions          */
  150.         pmem->OSMemFreeList = (void *)&OSMemTbl[i+1]; /* Chain list of free partitions                 */
  151.         pmem->OSMemAddr     = (void *)0;              /* Store start address of memory partition       */
  152.         pmem->OSMemNFree    = 0;                      /* No free blocks                                */
  153.         pmem->OSMemNBlks    = 0;                      /* No blocks                                     */
  154.         pmem->OSMemBlkSize  = 0;                      /* Zero size                                     */
  155.         pmem++;
  156.     }
  157.     OSMemTbl[OS_MAX_MEM_PART - 1].OSMemFreeList = (void *)0;
  158.     OSMemFreeList                               = (OS_MEM *)&OSMemTbl[0];
  159. }
  160. /*$PAGE*/
  161. /*
  162. *********************************************************************************************************
  163. *                                         RELEASE A MEMORY BLOCK
  164. *
  165. * Description : Returns a memory block to a partition
  166. *
  167. * Arguments   : pmem    is a pointer to the memory partition control block
  168. *
  169. *               pblk    is a pointer to the memory block being released.
  170. *
  171. * Returns     : OS_NO_ERR         if the memory block was inserted into the partition
  172. *               OS_MEM_FULL       if you are returning a memory block to an already FULL memory partition
  173. *                                 (You freed more blocks than you allocated!)
  174. *********************************************************************************************************
  175. */
  176. INT8U OSMemPut (OS_MEM  *pmem, void *pblk)
  177. {
  178.     OS_ENTER_CRITICAL();
  179.     if (pmem->OSMemNFree >= pmem->OSMemNBlks) {  /* Make sure all blocks not already returned          */
  180.         OS_EXIT_CRITICAL();
  181.         return (OS_MEM_FULL);       
  182.     }
  183.     *(void **)pblk      = pmem->OSMemFreeList;   /* Insert released block into free block list         */
  184.     pmem->OSMemFreeList = pblk;
  185.     pmem->OSMemNFree++;                          /* One more memory block in this partition            */
  186.     OS_EXIT_CRITICAL();
  187.     return (OS_NO_ERR);                          /* Notify caller that memory block was released       */
  188. }
  189. /*$PAGE*/
  190. /*
  191. *********************************************************************************************************
  192. *                                          QUERY MEMORY PARTITION
  193. *
  194. * Description : This function is used to determine the number of free memory blocks and the number of 
  195. *               used memory blocks from a memory partition.
  196. *
  197. * Arguments   : pmem    is a pointer to the memory partition control block
  198. *
  199. *               pdata   is a pointer to a structure that will contain information about the memory
  200. *                       partition.
  201. *
  202. * Returns     : OS_NO_ERR         Always returns no error.
  203. *********************************************************************************************************
  204. */
  205. INT8U OSMemQuery (OS_MEM *pmem, OS_MEM_DATA *pdata)
  206. {
  207.     OS_ENTER_CRITICAL();
  208.     pdata->OSAddr     = pmem->OSMemAddr;
  209.     pdata->OSFreeList = pmem->OSMemFreeList;
  210.     pdata->OSBlkSize  = pmem->OSMemBlkSize;
  211.     pdata->OSNBlks    = pmem->OSMemNBlks;
  212.     pdata->OSNFree    = pmem->OSMemNFree;
  213.     OS_EXIT_CRITICAL();
  214.     pdata->OSNUsed    = pdata->OSNBlks - pdata->OSNFree;
  215.     return (OS_NO_ERR);                         
  216. }
  217. #endif