/* ********************************************************************************************************* * 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 ********************************************************************************************************* */ #ifndef OS_MASTER_FILE #include "includes.h" #endif #if OS_MEM_EN && OS_MAX_MEM_PART >= 2 /* ********************************************************************************************************* * Áö¿ªÀû Àü¿ªº¯¼ö ********************************************************************************************************* */ static OS_MEM *OSMemFreeList; /* ¸Þ¸ð¸® ÆÄƼ¼ÇÀÇ ÀÚÀ¯ ¸®½ºÆ®¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ */ static OS_MEM OSMemTbl[OS_MAX_MEM_PART];/* ¸Þ¸ð¸® ÆÄƼ¼Ç °ü¸®ÀÚ°¡ »ç¿ëÇÏ´Â ÀúÀ念¿ª */ /*$PAGE*/ /* ********************************************************************************************************* * ¸Þ¸ð¸® ÆÄƼ¼Ç »ý¼º * * ¼³¸í : uC/OS-II°¡ °ü¸®ÇÏ´Â °íÁ¤ Å©±â ¸Þ¸ð¸® ÆÄƼ¼ÇÀ» »ý¼ºÇÑ´Ù. * * Àü´ÞÀÎÀÚ : addr ¸Þ¸ð¸® ÆÄƼ¼ÇÀÇ ½ÃÀÛ ¾îµå·¹½º. * * nblks ÆÄƼ¼Ç¿¡¼ »ý¼ºÇÒ ¸Þ¸ð¸® ºí·Ï ¼ö. * * blksize °¢ ºí·ÏÀÇ Å©±â(¹ÙÀÌÆ® ´ÜÀ§). * * err ¿¡·¯ Äڵ带 ÀúÀåÇÒ ¸Þ¸ð¸®¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ. * ´ÙÀ½°ú °°Àº °ªÀ» °®´Â´Ù. * * OS_NO_ERR ¸Þ¸ð¸® ÆÄƼ¼ÇÀ» Á¤»óÀûÀ¸·Î »ý¼ºÇßÀ½. * OS_MEM_INVALID_PART ÀÚÀ¯ ÆÄƼ¼ÇÀ» »ý¼ºÇÒ ¼ö ¾øÀ½. * OS_MEM_INVALID_BLKS ºí·Ï ¼ö¸¦ Àß ¸ø ÁöÁ¤ÇßÀ½(2¿Í °°°Å³ª Ä¿¾ßÇÔ). * OS_MEM_INVALID_SIZE ºí·Ï Å©±â¸¦ À߸ø ÁöÁ¤ÇßÀ½. * (Æ÷ÀÎÅÍ Å©±âº¸´Ù Ä¿¾ßÇÔ) * ¸®Åϰª : != (OS_MEM *)0 »ý¼ºÇÑ ÆÄƼ¼ÇÀ» °¡¸®Å°´Â Æ÷ÀÎÅÍ. * == (OS_MEM *)0 Àü´ÞÀÎÀÚ¸¦ Àß ¸ø ÁöÁ¤Çؼ ÆÄƼ¼ÇÀ» »ý¼ºÇÏÁö ¸øÇÑ °æ¿ì. * ÀÚÀ¯ ÆÄƼ¼ÇÀÌ ¾øÀ½. ********************************************************************************************************* */ OS_MEM *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *err) { OS_MEM *pmem; INT8U *pblk; void **plink; INT32U i; if (nblks < 2) { /* ÆÄƼ¼Ç´ç ÃÖ¼ÒÇÑ 2ºí·ÏÀ» Æ÷ÇÔÇØ¾ß ÇÔ */ *err = OS_MEM_INVALID_BLKS; return ((OS_MEM *)0); } if (blksize < sizeof(void *)) { /* ÃÖ¼ÒÇÑ Æ÷ÀÎÅ͸¦ ÀúÀåÇÒ ¼ö ÀÖ´Â ºí·ÏÅ©±â ÇÊ¿ä */ *err = OS_MEM_INVALID_SIZE; return ((OS_MEM *)0); } OS_ENTER_CRITICAL(); pmem = OSMemFreeList; /* ÀÚÀ¯ ¸Þ¸ð¸® ÆÄƼ¼ÇÀ» ¾òÀ½ */ if (OSMemFreeList != (OS_MEM *)0) { /* ÀÚÀ¯ ÆÄƼ¼Ç Ç®ÀÌ ºñ¾ú´ÂÁö È®ÀÎ */ OSMemFreeList = (OS_MEM *)OSMemFreeList->OSMemFreeList; } OS_EXIT_CRITICAL(); if (pmem == (OS_MEM *)0) { /* ¸Þ¸ð¸® ÆÄƼ¼ÇÀ» ¾ò¾ú´ÂÁö È®ÀÎ */ *err = OS_MEM_INVALID_PART; return ((OS_MEM *)0); } plink = (void **)addr; /* ÀÚÀ¯ ¸Þ¸ð¸® ºí·ÏÀÇ ¸µÅ©µå ¸®½ºÆ® »ý¼º */ pblk = (INT8U *)addr + blksize; for (i = 0; i < (nblks - 1); i++) { *plink = (void *)pblk; plink = (void **)pblk; pblk = pblk + blksize; } *plink = (void *)0; /* ¸¶Áö¸· ºí·ÏÀº NULLÀ» °¡¸®Å²´Ù */ OS_ENTER_CRITICAL(); pmem->OSMemAddr = addr; /* ¸Þ¸ð¸® ÆÄƼ¼ÇÀÇ ½ÃÀÛ ÁÖ¼Ò ÀúÀå */ pmem->OSMemFreeList = addr; /* Æ÷ÀÎÅ͸¦ ÀÚÀ¯ ºí·Ï pool·Î °¡¸®Å²´Ù */ pmem->OSMemNFree = nblks; /* ÀÚÀ¯ ºí·Ï ¼ö¸¦ MCB¿¡ ÀúÀå */ pmem->OSMemNBlks = nblks; pmem->OSMemBlkSize = blksize; /* °¢ ºí·ÏÀÇ Å©±â ÀúÀå */ OS_EXIT_CRITICAL(); *err = OS_NO_ERR; return (pmem); } /*$PAGE*/ /* ********************************************************************************************************* * ¸Þ¸ð¸® ºí·Ï ÇÒ´ç * * ¼³¸í : ÆÄƼ¼Ç¿¡¼ ¸Þ¸ð¸® ºí·ÏÀ» ¾ò´Â´Ù. * * Àü´ÞÀÎÀÚ : pmem ¸Þ¸ð¸® ÆÄƼ¼Ç ÄÁÆ®·Ñ ºí·ÏÀ» °¡¸®Å°´Â Æ÷ÀÎÅÍ. * * err ¿¡·¯ Äڵ带 ÀúÀåÇÒ ¸Þ¸ð¸®¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ. * ´ÙÀ½°ú °°Àº °ªÀ» °®´Â´Ù. * * OS_NO_ERR ¸Þ¸ð¸® ÆÄƼ¼ÇÀ» Á¤»óÀûÀ¸·Î »ý¼ºÇßÀ½. * OS_MEM_NO_FREE_BLKS È£ÃâÀÚ¿¡°Ô ÇÒ´çÇØÁÙ ÀÚÀ¯ ¸Þ¸ð¸® ºí·ÏÀÌ ¾øÀ½. * * ¸®Åϰª : ¿¡·¯°¡ ¾øÀ» °æ¿ì ÇÒ´çµÈ ºí·ÏÀ» °¡¸®Å°´Â Æ÷ÀÎÅÍ. * ¿¡·¯°¡ ¹ß»ýÇÑ °æ¿ì´Â NULLÀ» µ¹·ÁÁØ´Ù. ********************************************************************************************************* */ void *OSMemGet (OS_MEM *pmem, INT8U *err) { void *pblk; OS_ENTER_CRITICAL(); if (pmem->OSMemNFree > 0) { /* ÀÚÀ¯ ¸Þ¸ð¸® ºí·ÏÀÌ ÀÖ´ÂÁö È®ÀÎ */ pblk = pmem->OSMemFreeList; /* ¿¹, ´ÙÀ½ ÀÚÀ¯ ¸Þ¸ð¸® ºí·ÏÀ» °¡¸®Å²´Ù */ pmem->OSMemFreeList = *(void **)pblk; /* »õ ÀÚÀ¯ ¸®½ºÆ®¸¦ °¡¸®Å°µµ·Ï Æ÷ÀÎÅÍ Á¶Á¤ */ pmem->OSMemNFree--; /* ÀÌ ÆÄƼ¼Ç¿¡¼ÀÇ °¡¿ë ¸Þ¸ð¸® ºí·Ï ¼ö °¨¼Ò */ OS_EXIT_CRITICAL(); *err = OS_NO_ERR; /* ¿¡·¯ ¾øÀ½ */ return (pblk); /* È£ÃâÀÚ·Î ¸Þ¸ð¸® ºí·ÏÀ» ¸®ÅÏ */ } else { OS_EXIT_CRITICAL(); *err = OS_MEM_NO_FREE_BLKS; /* ¾Æ´Ï¿À, È£ÃâÀÚ¿¡°Ô ¸Þ¸ð¸® ºí·ÏÀÌ ¾øÀ½À» ¾Ë¸² */ return ((void *)0); /* NULL Æ÷ÀÎÅ͸¦ ¸®ÅÏ */ } } /*$PAGE*/ /* ********************************************************************************************************* * ¸Þ¸ð¸® ÆÄƼ¼Ç °ü¸®ÀÚ ÃʱâÈ * * ¼³¸í : ¸Þ¸ð¸® °ü¸®ÀÚ¸¦ ÃʱâÈÇϱâ À§ÇØ uC/OS-II°¡ È£ÃâÇÏ´Â ÇÔ¼ö. * ÀÀ¿ëÇÁ·Î±×·¥Àº ÀÌ ÇÔ¼ö¸¦ È£ÃâÇÏ¸é ¾ÈµÈ´Ù. * * Àü´ÞÀÎÀÚ : ¾øÀ½ * * ¸®Åϰª : ¾øÀ½ ********************************************************************************************************* */ void OSMemInit (void) { OS_MEM *pmem; INT16U i; pmem = (OS_MEM *)&OSMemTbl[0]; /* ¸Þ¸ð¸® ÄÁÆ®·Ñ ºí·Ï(MCB)À» °¡¸®Å²´Ù */ for (i = 0; i < (OS_MAX_MEM_PART - 1); i++) { /* ÀÚÀ¯ ¸Þ¸ð¸® ÆÄƼ¼Ç ¸®½ºÆ® ÃʱâÈ */ pmem->OSMemFreeList = (void *)&OSMemTbl[i+1]; /* ÀÚÀ¯ ÆÄƼ¼Ç ¿¬°á ¸®Æ®½º */ pmem->OSMemAddr = (void *)0; /* ¸Þ¸ð¸® ÆÄƼ¼ÇÀÇ ½ÃÀÛ ÁÖ¼Ò ÀúÀå */ pmem->OSMemNFree = 0; /* ÀÚÀ¯ ºí·ÏÀÌ ¾øÀ½ */ pmem->OSMemNBlks = 0; /* ºí·Ï ¾øÀ½ */ pmem->OSMemBlkSize = 0; /* Å©±â 0 */ pmem++; } OSMemTbl[OS_MAX_MEM_PART - 1].OSMemFreeList = (void *)0; OSMemFreeList = (OS_MEM *)&OSMemTbl[0]; } /*$PAGE*/ /* ********************************************************************************************************* * ¸Þ¸ð¸® ºí·Ï ÇØÁ¦ * * ¼³¸í : ¸Þ¸ð¸® ºí·ÏÀ» ÆÄƼ¼ÇÀ¸·Î µ¹·ÁÁØ´Ù. * * Àü´ÞÀÎÀÚ : pmem ¸Þ¸ð¸® ÆÄƼ¼Ç ÄÁÆ®·Ñ ºí·ÏÀ» °¡¸®Å°´Â Æ÷ÀÎÅÍ. * * pblk ÇØÁ¦ÇÏ·Á´Â ¸Þ¸ð¸® ºí·ÏÀ» °¡¸®Å°´Â Æ÷ÀÎÅÍ. * * ¸®Åϰª : OS_NO_ERR ¸Þ¸ð¸® ºí·ÏÀ» ¼º°øÀûÀ¸·Î ¸Þ¸ð¸® ÆÄƼ¼Ç¿¡ µ¹·ÁÁáÀ½. * OS_MEM_FULL ÀÌ¹Ì Âù ¸Þ¸ð¸® ÆÄƼ¼Ç¿¡ ºí·ÏÀ» µ¹·ÁÁÖ·Á°í ½ÃµµÇßÀ½. * (ÇÒ´çÇÑ ºí·Ï ÀÌ»óÀÇ ºí·ÏÀ» ÇØÁ¦ÇÏ·Á ÇßÀ½!) ********************************************************************************************************* */ INT8U OSMemPut (OS_MEM *pmem, void *pblk) { OS_ENTER_CRITICAL(); if (pmem->OSMemNFree >= pmem->OSMemNBlks) { /* ¸ðµç ºí·ÏÀ» ÀÌ¹Ì ÇØÁ¦Çß´ÂÁö È®ÀÎ */ OS_EXIT_CRITICAL(); return (OS_MEM_FULL); } *(void **)pblk = pmem->OSMemFreeList; /* ÇØÁ¦ÇÏ·Á´Â ºí·ÏÀ» ÀÚÀ¯ ºí·Ï ¸®½ºÆ®¿¡ »ðÀÔ */ pmem->OSMemFreeList = pblk; pmem->OSMemNFree++; /* ÆÄƼ¼Ç¿¡ ÀÖ´Â ºí·Ï ¼ö¸¦ Áõ°¡ */ OS_EXIT_CRITICAL(); return (OS_NO_ERR); /* ºí·ÏÀ» ÇØÁ¦ÇßÀ½À» È£ÃâÀÚ¿¡°Ô ¾Ë¸² */ } /*$PAGE*/ /* ********************************************************************************************************* * ¸Þ¸ð¸® ÆÄƼ¼Ç »óÅ ¾ò±â * * ¼³¸í : ÀÌ ÇÔ¼ö´Â ¸Þ¸ð¸® ÆÄƼ¼Ç¿¡¼ »ç¿ëÇÑ ¸Þ¸ð¸® ºí·Ï ¼ö¿Í ÀÚÀ¯ ¸Þ¸ð¸® ºí·Ï ¼ö¸¦ ¾Ë¾Æ³½´Ù. * * * Àü´ÞÀÎÀÚ : pmem ¸Þ¸ð¸® ÆÄƼ¼Ç ÄÁÆ®·Ñ ºí·ÏÀ» °¡¸®Å°´Â Æ÷ÀÎÅÍ. * * pdata ¸Þ¸ð¸® ÆÄƼ¼Ç¿¡ ´ëÇÑ Á¤º¸¸¦ ÀúÀåÇÒ ±¸Á¶Ã¼¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ. * * * ¸®Åϰª : OS_NO_ERR Ç×»ó ¿¡·¯°¡ ¾øÀ½. ********************************************************************************************************* */ INT8U OSMemQuery (OS_MEM *pmem, OS_MEM_DATA *pdata) { OS_ENTER_CRITICAL(); pdata->OSAddr = pmem->OSMemAddr; 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; return (OS_NO_ERR); } #endif