Docstoc

Chapter 7 Memory Management - PowerPoint

Document Sample
Chapter 7 Memory Management - PowerPoint Powered By Docstoc
					    Chapter 7
Memory Management
• The dynamic memory allocation can be achieved by using
  malloc() and free() function
• Using malloc() and free(0 in an embedded real-time
  system is dangerous
     – Eventually may incur fragmentation
     – Execution time of malloc() and free(0) are nondeterministic
• uC/OS-II provides fixed-sized memory blocks for dynamic
  memory allocation
Figure 7.1 memory partition
                                        Figure 7.2 multiple memory partitions
Start address                         atto 1
                                      Priin#    Priin#
                                                atto 2    atto 3
                                                          Priin#     atto 4
                                                                     Priin#




                   Partition




        Block
                Memory control block data structure
          typedef struct {
            void *OSMemAddr; //point to the beginning of memory block
            void *OSMemFreeList; //point to MCB or memory block
            INT32U OSMemBlkSize;
            INT32U OSMemNBlks; //total memory blocks
            INT32U OSMemNFree; //current available memory blocks
          } OS_MEM;

                   List of free memory control blocks



                    SM Ad
                   O em dr          SM Ad
                                   O em dr                    SM Ad
                                                             O em dr

OSMemFreeList       SM Fr L t
                   O em ee is       SM Fr L t
                                   O em ee is                 SM Fr L t
                                                             O em ee is   0
                    SM Bl i
                   O em kS ze       SM Bl i
                                   O em kS ze                 SM Bl i
                                                             O em kS ze

                    SM NB s
                   O em lk          SM NB s
                                   O em lk                    SM NB s
                                                             O em lk

                    SM NF e
                   O em re          SM NF e
                                   O em re                    SM NF e
                                                             O em re


                                    OS_MAX_MEM_PART
          Creating a partition, OSMemCreate()

OS_MEM *CommTxBuf;
INT8U CommTxPart[100][32];
void main (void)
{
  INT8U err;
  OSInit();
  .
  .
  CommTxBuf = OSMemCreate(CommTxPart, 100, 32, &err);
  .
  .
  OSStart();
}


• Four arguments are required
     –   Beginning address of the memory partition
     –   The number of blocks to be allocated from this partition
     –   The size (in bytes) of each block
     –   A pointer to a variable that contains an error code
OS_MEM *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *err)
{
  OS_MEM *pmem;                                    OSMemCrate():
  INT8U *pblk;
  void **plink;                                    return MCB or 0
  INT32U i;
  if (nblks < 2) {      //each memory partition must contain at least two memory blocks          (1)
     *err = OS_MEM_INVALID_BLKS;
     return ((OS_MEM *)0);
  }
  if (blksize < sizeof(void *)) { //each memory block must be able to hold the size of a pointer (2)
     *err = OS_MEM_INVALID_SIZE;
     return ((OS_MEM *)0);
  }
  OS_ENTER_CRITICAL();
  pmem = OSMemFreeList; //obtain a MCB                                  (3)
  if (OSMemFreeList != (OS_MEM *)0) {
     OSMemFreeList = (OS_MEM *)OSMemFreeList->OSMemFreeList;
  }
  OS_EXIT_CRITICAL();
  if (pmem == (OS_MEM *)0) {                            (4)
     *err = OS_MEM_INVALID_PART;
     return ((OS_MEM *)0);
  }
    plink = (void **)addr;                 (5)
    pblk = (INT8U *)addr + blksize;
    for (i = 0; i < (nblks - 1); i++) {
        *plink = (void *)pblk;
        plink = (void **)pblk;
        pblk = pblk + blksize;
     }
     *plink = (void *)0;
     OS_ENTER_CRITICAL();
     pmem->OSMemAddr = addr;                     (6)
     pmem->OSMemFreeList = addr;
     pmem->OSMemNFree = nblks;
     pmem->OSMemNBlks = nblks;
     pmem->OSMemBlkSize = blksize;
     OS_EXIT_CRITICAL();
     *err = OS_NO_ERR;
     return (pmem);                       (7)
}
Figure 7.4 The data structure after OSMemCreate() successful


  pmem      SeAd
            OMmdr         dr
                         =ad

            SeFeLs= dr
            OMmreit ad
            SeBkie  lsz
            OMmlSz =bkie
            SeNls
            OMmBk         bk
                         =nls

            SeNre
            OMmFe         bk
                         =nls


                                              Contiguous memory

           OSMemCreate() arguments




                                          0
  Obtaining a Memory block, OSMemGet()
 • The APs need to understand how size of memory block is
   required
      – Need to provide the associated pointer of memory control block
      – When you are done using the block, you must return it to the
        proper memory partition
void *OSMemGet (OS_MEM *pmem, INT8U *err)               (1)
{
  void *pblk;
  OS_ENTER_CRITICAL();
  if (pmem->OSMemNFree > 0) {                (2)
     pblk           = pmem->OSMemFreeList;    (3)
     pmem->OSMemFreeList = *(void **)pblk;        (4)
     pmem->OSMemNFree--;                   (5)
     OS_EXIT_CRITICAL();
     *err = OS_NO_ERR;
     return (pblk);                (6)
  } else {
     OS_EXIT_CRITICAL();
     *err = OS_MEM_NO_FREE_BLKS;
     return ((void *)0);
  }
}
       Returning a Memory Block, OSMemPut()

• If you return a wrong memory partition, the system may be
  crash or waste memory space


    INT8U OSMemPut (OS_MEM *pmem, void *pblk)          (1)
    {
      OS_ENTER_CRITICAL();
      if (pmem->OSMemNFree >= pmem->OSMemNBlks) {        (2)
         OS_EXIT_CRITICAL();
         return (OS_MEM_FULL);
      }
      *(void **)pblk = pmem->OSMemFreeList;      (3)
      pmem->OSMemFreeList = pblk;
      pmem->OSMemNFree++;                    (4)
      OS_EXIT_CRITICAL();
      return (OS_NO_ERR);
    }
Obtaining Status of a Memory Partition, OSMemQuery()

typedef struct {
  void *OSAddr;     /* Points to beginning address of the memory partition */
  void *OSFreeList; /* Points to 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;




INT8U OSMemQuery (OS_MEM *pmem, OS_MEM_DATA *pdata)
{
  OS_ENTER_CRITICAL();
  pdata->OSAddr = pmem->OSMemAddr;               (1)
  pdata->OSFreeList = pmem->OSMemFreeList;
  pdata->OSBlkSize = pmem->OSMemBlkSize;
  pdata->OSNBlks = pmem->OSMemNBlks;
  pdata->OSNFree = pmem->OSMemNFree;
  OS_EXIT_CRITICAL();
  pdata->OSNUsed = pdata->OSNBlks - pdata->OSNFree; (2)
  return (OS_NO_ERR);
}
         Using Memory Partitions
                        Sie
                        OTm

        Siee(
        OTmGt)
         (3)

                         ErrMsgQ

nlg
Aao      AI     SPs(
                OQot)              SPn(
                                   OQed)      Error
nus
Ipt     Task     (5)                (6)      Handler
(1)

                  (4)                 (7)

        SeGt)
        OMme(                               SePt)
                                            OMmu(
         (2)                                 (8)



      rMgat
      ErsPr                                            0
        Scanning analog inputs and reporting errors
AnalogInputTask()
{
  for (;;) {
    for (all analog inputs to read) {
       Read analog input;                            (1)
       if (analog input exceed threshold) {
           Get memory block;                          (2)
           Get current system time (in clock ticks);       (3)
           Store the following items in the memory block:      (4)
             System time (i.e. a time stamp);
             The channel that exceeded the threshold;
             An error code;
             The severity of the error;
             Etc.
           Post the error message to error queue;          (5)
             (A pointer to the memory block containing the data)
       }
    }
    Delay task until it’s time to sample analog inputs again;
  }
}
ErrorHandlerTask()
{
  for (;;) {
    Wait for message from error queue;                     (6)
       (Gets a pointer to a memory block containing information
        about the error reported)
    Read the message and take action based on error reported;         (7)
    Return the memory block to the memory partition;               (8)
  }
}
Waiting for memory blocks from a partition
OS_EVENT *SemaphorePtr;                            (1)
OS_MEM *PartitionPtr;
INT8U Partition[100][32];
OS_STK TaskStk[1000];
void main (void)
{
  INT8U err;
  OSInit();                           (2)
  .
  .
  SemaphorePtr = OSSemCreate(100);                    (3)
  PartitionPtr = OSMemCreate(Partition, 100, 32, &err);     (4)
  .
  OSTaskCreate(Task, (void *)0, &TaskStk[999], &err);       (5)
  .
  OSStart();                           (6)
}
void Task (void *pdata)
{
  INT8U err;
  INT8U *pblock;
  for (;;) {
     OSSemPend(SemaphorePtr, 0, &err);                (7)
     pblock = OSMemGet(PartitionPtr, &err);             (8)
     .
     . /* Use the memory block */
     .
     OSMemPut(PartitionPtr, pblock);               (9)
     OSSemPost(SemaphorePtr);                    (10)
  }
}

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:11
posted:8/18/2012
language:English
pages:13