13
Chapter 12 Memory Management

Chapter 12 Memory Management. The dynamic memory allocation can be achieved by using malloc() and free() function Using malloc() and free(0 in an embedded

Embed Size (px)

Citation preview

Page 1: Chapter 12 Memory Management. The dynamic memory allocation can be achieved by using malloc() and free() function Using malloc() and free(0 in an embedded

Chapter 12Memory Management

Page 2: Chapter 12 Memory Management. The dynamic memory allocation can be achieved by using malloc() and free() function Using malloc() and free(0 in an embedded

• 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 from partition made of a contiguous memory

– Allocation and deallocation of these memory blocks is done in constant time and is deterministic

• Memory service: OSMemCreate(0, OSMemGet(), OSMemPut(), OSMemQuery()

Partition

Block

Start addressPartition #1 Partition #2 Partition #3 Partition #4

Figure 7.1 memory partition Figure 7.2 multiple memory partitions

Page 3: Chapter 12 Memory Management. The dynamic memory allocation can be achieved by using malloc() and free() function Using malloc() and free(0 in an embedded

Memory control block data structure

• The memory partitions is maintained by memory control block

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

OSMemAddr

OSMemFreeList

OSMemBlkSize

OSMemNBlks

OSMemNFree

OSMemAddr

OSMemFreeList

OSMemBlkSize

OSMemNBlks

OSMemNFree

OSMemAddr

OSMemFreeList

OSMemBlkSize

OSMemNBlks

OSMemNFree

0OSMemFreeList

OS_MAX_MEM_PART

Page 4: Chapter 12 Memory Management. The dynamic memory allocation can be achieved by using malloc() and free() function Using malloc() and free(0 in an embedded

12.01 Creating a partition, OSMemCreate()

• 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 *CommTxBuf;INT8U CommTxPart[100][32];void main (void){ INT8U err; OSInit(); . . CommTxBuf = OSMemCreate(CommTxPart, 100, 32, &err); . . OSStart();}

Page 5: Chapter 12 Memory Management. The dynamic memory allocation can be achieved by using malloc() and free() function Using malloc() and free(0 in an embedded

OS_MEM *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *err){ OS_MEM *pmem; INT8U *pblk; void **plink; 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); }

OSMemCrate(): return MCB address or 0

Page 6: Chapter 12 Memory Management. The dynamic memory allocation can be achieved by using malloc() and free() function Using malloc() and free(0 in an embedded

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)}

Page 7: Chapter 12 Memory Management. The dynamic memory allocation can be achieved by using malloc() and free() function Using malloc() and free(0 in an embedded

Figure 12.4 The data structure after OSMemCreate() successful

0

OSMemAddr = addr

OSMemFreeList= addr

OSMemBlkSize = blksize

OSMemNBlks = nblks

OSMemNFree = nblks

Contiguous memory

pmem

OSMemCreate() arguments

Page 8: Chapter 12 Memory Management. The dynamic memory allocation can be achieved by using malloc() and free() function Using malloc() and free(0 in an embedded

12.02 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); }}

Page 9: Chapter 12 Memory Management. The dynamic memory allocation can be achieved by using malloc() and free() function Using malloc() and free(0 in an embedded

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); }

Page 10: Chapter 12 Memory Management. The dynamic memory allocation can be achieved by using malloc() and free() function Using malloc() and free(0 in an embedded

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); }

Page 11: Chapter 12 Memory Management. The dynamic memory allocation can be achieved by using malloc() and free() function Using malloc() and free(0 in an embedded

Using Memory Partitions

ErrMsgPart

ErrMsgQ

ErrorHandler

AITask

0

OSMemGet() OSMemPut()

OSQPost() OSQPend()

OSTime

OSTimeGet()

(1)

AnalogInputs

(2)

(3)

(4)

(5) (6)

(7)

(8)

Page 12: Chapter 12 Memory Management. The dynamic memory allocation can be achieved by using malloc() and free() function Using malloc() and free(0 in an embedded

Scanning analog inputs and reporting errorsAnalogInputTask(){ 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) }}

Page 13: Chapter 12 Memory Management. The dynamic memory allocation can be achieved by using malloc() and free() function Using malloc() and free(0 in an embedded

Waiting for memory blocks from a partitionOS_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) }}