/* ********************************************************************************************************* * uC/OS-II * The Real-Time Kernel * MESSAGE MAILBOX MANAGEMENT * * (c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL * All Rights Reserved * * V2.00 * * File : OS_MBOX.C * By : Jean J. Labrosse ********************************************************************************************************* */ #ifndef OS_MASTER_FILE #include "includes.h" #endif #if OS_MBOX_EN /* ********************************************************************************************************* * ´ë±â¾øÀÌ ¸ÞÀϹڽº¿¡¼ ¸Þ½ÃÁö ¹Þ±â * * ¼³¸í : ÀÌ ÇÔ¼ö´Â ¸ÞÀϹڽº¿¡ ¸Þ½ÃÁö°¡ À¯È¿ÇÑÁö Á¡°ËÇÑ´Ù. OSMboxPend()¿Í ´Ù¸¥ Á¡Àº, ¸Þ½ÃÁö°¡ * ¾ø´Â °æ¿ì¿¡µµ OSMboxAccept()¸¦ È£ÃâÇÑ Å½ºÅ©¸¦ ´ë±â»óÅ·Π¸¸µéÁö ¾Ê´Â´Ù´Â Á¡ÀÌ´Ù * * Àü´ÞÀÎÀÚ : pevent ÇØ´ç ¸ÞÀϹڽºÀÇ À̺¥Æ® ÄÁÆ®·Ñ ºí·Ï¿¡ ´ëÇÑ Æ÷ÀÎÅÍ. * * ¸®Åϰª : != (void *)0 ¸Þ½ÃÁö°¡ À¯È¿ÇÑ °æ¿ì ¸ÞÀϹڽº¿¡¼ Àоî¿Â ¸Þ½ÃÁö. ¸ÞÀϹڽº´Â Ŭ¸®¾îµÇ¹Ç·Î * ´ÙÀ½ ¹ø¿¡ OSMboxAccept()¸¦ È£ÃâÇÏ¸é ¸ÞÀϹڽº´Â ºñ¾îÀÖÀ» °ÍÀÌ´Ù. * == (void *)0 ¸ÞÀϹڽº°¡ ºñ¾î Àְųª, ºÎÀûÀýÇÑ À̺¥Æ® ÄÁÆ®·Ñ ºí·Ï Æ÷ÀÎÅ͸¦ Àü´ÞÇßÀ½. ********************************************************************************************************* */ void *OSMboxAccept (OS_EVENT *pevent) { void *msg; OS_ENTER_CRITICAL(); if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* À¯È¿ÇÑ À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀÎÁö Á¡°Ë */ OS_EXIT_CRITICAL(); return ((void *)0); } msg = pevent->OSEventPtr; if (msg != (void *)0) { /* ÀÌ¹Ì ¸Þ½ÃÁö°¡ ÀÖ´ÂÁö È®ÀÎ */ pevent->OSEventPtr = (void *)0; /* ¸ÞÀϹڽº Ŭ¸®¾î */ } OS_EXIT_CRITICAL(); return (msg); /* NULL ¶Ç´Â ¼ö½ÅÇÑ ¸Þ½ÃÁö¸¦ ¸®ÅÏ */ } /*$PAGE*/ /* ********************************************************************************************************* * ¸Þ½ÃÁö ¸ÞÀϹڽº »ý¼º * * ¼³¸í : ÀÌ ÇÔ¼ö´Â ºó À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀÌ ÀÖÀ» °æ¿ì ¸Þ½ÃÁö ¸ÞÀϹڽº¸¦ »ý¼ºÇÑ´Ù. * * Àü´ÞÀÎÀÚ : msg ¸ÞÀϹڽº¿¡ ¼ÛºÎÇϰíÀÚ ÇÏ´Â ¸Þ½ÃÁö¿¡ ´ëÇÑ Æ÷ÀÎÅÍ. * ÀÌ °ªÀ» NULL·Î ¼³Á¤Çϸé(i.e. (void *)0) ¸ÞÀϹڽº´Â ºñ¾îÀÖ´Â * °ÍÀ¸·Î °£ÁֵȴÙ. * * ¸®Åϰª : != (void *)0 »ý¼ºµÈ ¸ÞÀϹڽº¿¡ ÇØ´çÇÏ´Â À̺¥Æ® ÄÁÆ®·Ñ ºí·Ï(OS_EVENT)¿¡ ´ëÇÑ Æ÷ÀÎÅÍ * * == (void *)0 ÇÒ´çÇÒ À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀÌ ¾øÀ½. ********************************************************************************************************* */ OS_EVENT *OSMboxCreate (void *msg) { OS_EVENT *pevent; OS_ENTER_CRITICAL(); pevent = OSEventFreeList; /* ºó À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀ» ¾ò´Â´Ù */ if (OSEventFreeList != (OS_EVENT *)0) { /* ¾òÀº À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀÌ À¯È¿ÇÑÁö È®ÀÎ */ OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; } OS_EXIT_CRITICAL(); if (pevent != (OS_EVENT *)0) { pevent->OSEventType = OS_EVENT_TYPE_MBOX; pevent->OSEventPtr = msg; /* À̺¥Æ® ÄÁÆ®·Ñ ºí·Ï¿¡ ¸Þ½ÃÁö¸¦ ¼ÛºÎ */ OSEventWaitListInit(pevent); } return (pevent); /* À̺¥Æ® ÄÁÆ®·Ñ ºí·Ï¿¡ ´ëÇÑ Æ÷ÀÎÅ͸¦ ¸®ÅÏ */ } /*$PAGE*/ /* ********************************************************************************************************* * ¸ÞÀϹڽº¿¡ ¸Þ½ÃÁö°¡ µµÂøÇÒ ¶§±îÁö ´ë±â * * ¼³¸í : ÀÌ ÇÔ¼ö´Â ¸ÞÀϹڽº¿¡ ¸Þ½ÃÁö°¡ µµÂøÇÒ ¶§¸¦ ±â´Ù¸°´Ù * * Àü´ÞÀÎÀÚ : pevent ÇØ´ç ¸ÞÀϹڽºÀÇ À̺¥Æ® ÄÁÆ®·Ñ ºí·Ï¿¡ ´ëÇÑ Æ÷ÀÎÅÍ. * * timeout ¿É¼Ç ŸÀӾƿô °ª(Ŭ·° ƽ ´ÜÀ§). ÀÌ °ªÀÌ 0ÀÌ ¾Æ´Ñ °æ¿ì, ŽºÅ©´Â ÁöÁ¤ÇÑ ½Ã°£ * µ¿¾È ¸ÞÀϹڽº¿¡ ¸Þ½ÃÁö°¡ µµÂøÇϱ⸦ ±â´Ù¸°´Ù. * ±×·¯³ª ÀÌ °ª¿¡ 0À» ÁöÁ¤ÇÑ °æ¿ì, ¸Þ½ÃÁö°¡ µµÂøÇÒ ¶§±îÁö ¿µ¿øÈ÷ ´ë±â»óÅ·Π* ³²¾Æ Àִ´Ù. * * err ¿¡·¯Äڵ带 ÀúÀåÇÒ ¸Þ¸ð¸®¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ. * °¡´ÉÇÑ ¿¡·¯ÄÚµå´Â ´ÙÀ½°ú °°´Ù. * * OS_NO_ERR È£ÃâÀÌ ¼º°øÇßÀ¸¸ç, ¸Þ½ÃÁö¸¦ ¹Þ¾ÒÀ½. * OS_TIMEOUT ÁöÁ¤ÇÑ Å¸ÀӾƿôµ¿¾È ¸Þ½ÃÁö¸¦ ¹ÞÁö ¸øÇßÀ½. * OS_ERR_EVENT_TYPE ¹«È¿ÇÑ À̺¥Æ® ŸÀÔÀ» ÁöÁ¤ÇßÀ½. * OS_ERR_PEND_ISR ÀÌ ÇÔ¼ö¸¦ ISR¿¡¼ È£ÃâÇßÀ½. * ISRÀº ´ë±â»óŰ¡ µÉ ¼ö ¾øÀ¸¹Ç·Î ¹Ù·Î ¸®ÅÏÇßÀ½. * * ¸®Åϰª : != (void *)0 ¼ö½ÅµÈ ¸Þ½ÃÁö¿¡ ´ëÇÑ Æ÷ÀÎÅÍ. * == (void *)0 ¸Þ½ÃÁö°¡ µµÂøÇÏÁö ¾Ê¾Ò°Å³ª, ºÎÀûÀýÇÑ À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀ» ÁöÁ¤ÇßÀ½. * ********************************************************************************************************* */ void *OSMboxPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) { void *msg; OS_ENTER_CRITICAL(); if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* À¯È¿ÇÑ À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀÎÁö Á¡°Ë */ OS_EXIT_CRITICAL(); *err = OS_ERR_EVENT_TYPE; return ((void *)0); } msg = pevent->OSEventPtr; if (msg != (void *)0) { /* ÀÌ¹Ì ¸Þ½ÃÁö°¡ ÀÖ´ÂÁö È®ÀÎ */ pevent->OSEventPtr = (void *)0; /* ¸ÞÀϹڽº Ŭ¸®¾î */ OS_EXIT_CRITICAL(); *err = OS_NO_ERR; } else if (OSIntNesting > 0) { /* ISR¿¡¼ È£ÃâÇß´ÂÁö È®ÀÎ... */ OS_EXIT_CRITICAL(); /* ... ISRÀº ´ë±âÇÏ¸é ¾ÈµÊ */ *err = OS_ERR_PEND_ISR; } else { OSTCBCur->OSTCBStat |= OS_STAT_MBOX; /* ¸Þ½ÃÁö°¡ ¾øÀ½, ŽºÅ©´Â ´ë±â»óŰ¡ µÊ */ OSTCBCur->OSTCBDly = timeout; /* TCB¿¡ ŸÀӾƿô °ªÀ» ÀúÀå */ OSEventTaskWait(pevent); /* ŸÀӾƿô ¸¸·á³ª ¸Þ½ÃÁö°¡ µµÂøÇÒ ¶§±îÁö ´ë±â */ OS_EXIT_CRITICAL(); OSSched(); /* ½ÇÇà Áغñ»óÅÂÀÎ ´ÙÀ½ ¿ì¼±¼øÀ§ ŽºÅ© °áÁ¤ */ OS_ENTER_CRITICAL(); if ((msg = OSTCBCur->OSTCBMsg) != (void *)0) { /* ¸Þ½ÃÁö°¡ ÀÖ´ÂÁö È®ÀÎ */ OSTCBCur->OSTCBMsg = (void *)0; /* ¿¹, ¹ÞÀº ¸Þ½ÃÁö¸¦ Áö¿ò */ OSTCBCur->OSTCBStat = OS_STAT_RDY; OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* ´õÀÌ»ó À̺¥Æ®¸¦ ±â´Ù¸®Áö ¾ÊÀ½ */ OS_EXIT_CRITICAL(); *err = OS_NO_ERR; } else if (OSTCBCur->OSTCBStat & OS_STAT_MBOX) { /* OS_STAT_RDY »óŰ¡ ¾Æ´Ï°í, ŸÀӾƿô ¹ß»ý */ OSEventTO(pevent); /* ŽºÅ©¸¦ Áغñ»óÅ·Π¸¸µç´Ù */ OS_EXIT_CRITICAL(); msg = (void *)0; /* ¸Þ½ÃÁö ³»¿ëÀ» NULL·Î ¼³Á¤ */ *err = OS_TIMEOUT; /* ŸÀӾƿôÀÌ ¹ß»ýÇßÀ½À» ¾Ë¸² */ } else { msg = pevent->OSEventPtr; /* ¸Þ½ÃÁö ¼ö½Å */ pevent->OSEventPtr = (void *)0; /* ¸ÞÀϹڽº Áö¿ò */ OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; OS_EXIT_CRITICAL(); *err = OS_NO_ERR; } } return (msg); /* ¹ÞÀº ¸Þ½ÃÁö³ª NULLÀ» ¸®ÅÏÇÔ */ } /*$PAGE*/ /* ********************************************************************************************************* * ¸ÞÀϹڽº¿¡ ¸Þ½ÃÁö ¼ÛºÎ * * ¼³¸í : ÀÌ ÇÔ¼ö´Â ¸ÞÀϹڽº·Î ¸Þ½ÃÁö¸¦ º¸³½´Ù. * * Àü´ÞÀÎÀÚ : pevent ÇØ´ç ¸ÞÀϹڽºÀÇ À̺¥Æ® ÄÁÆ®·Ñ ºí·Ï¿¡ ´ëÇÑ Æ÷ÀÎÅÍ. * * msg º¸³»·Á´Â ¸Þ½ÃÁö¿¡ ´ëÇÑ Æ÷ÀÎÅÍ. NULL Æ÷ÀÎÅ͸¦ º¸³»¸é ¾ÈµÈ´Ù. * * ¸®Åϰª : OS_NO_ERR È£Ãâ¿¡ ¼º°øÇؼ ¸Þ½ÃÁö¸¦ º¸³ÂÀ½. * OS_MBOX_FULL ¸ÞÀϹڽº¿¡ 󸮵ÇÁö ¾ÊÀº ¸Þ½ÃÁö°¡ ÀÖÀ½. ¸ÞÀϹڽº´Â Çѹø¿¡ ÇϳªÀÇ * ¸Þ½ÃÁö¸¸ ó¸®ÇÒ ¼ö ÀÖÀ¸¹Ç·Î, »õ·Î¿î ¸Þ½ÃÁö¸¦ Àü¼ÛÇϱâ Àü¿¡ ¸ÞÀϹڽº¿¡ * ÀÖ´Â ¸Þ½ÃÁö´Â ¹Ýµå½Ã ±× ÀÌÀü¿¡ ó¸®µÅ¾ß ÇÑ´Ù. * OS_ERR_EVENT_TYPE ¾ø´Â ¸ÞÀϹڽº¿¡ ¸Þ½ÃÁö¸¦ ¼ÛºÎÇÏ·Á ÇßÀ½. ********************************************************************************************************* */ INT8U OSMboxPost (OS_EVENT *pevent, void *msg) { OS_ENTER_CRITICAL(); if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* À¯È¿ÇÑ À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀÎÁö Á¡°Ë */ OS_EXIT_CRITICAL(); return (OS_ERR_EVENT_TYPE); } if (pevent->OSEventGrp) { /* ´Ù¸¥ ŽºÅ©°¡ ¸ÞÀϹڽº¿¡ ´ë±âÇϰí ÀÖ´ÂÁö È®ÀÎ */ OSEventTaskRdy(pevent, msg, OS_STAT_MBOX); /* °¡Àå ¿ì¼±¼øÀ§°¡ ³ôÀº ŽºÅ©¸¦ Áغñ»óÅ·ΠÇÔ */ OS_EXIT_CRITICAL(); OSSched(); /* Áغñ»óÅÂÀÇ Å½ºÅ© Áß ÃÖ»óÀ§ ¿ì¼±¼øÀ§¸¦ °áÁ¤ */ return (OS_NO_ERR); } else { if (pevent->OSEventPtr != (void *)0) { /* ¸ÞÀϹڽº°¡ ºñ¾ú´ÂÁö È®ÀÎ */ OS_EXIT_CRITICAL(); return (OS_MBOX_FULL); } else { pevent->OSEventPtr = msg; /* ¸ÞÀϹڽº¿¡ ¸Þ½ÃÁö¸¦ ÀúÀå */ OS_EXIT_CRITICAL(); return (OS_NO_ERR); } } } /*$PAGE*/ /* ********************************************************************************************************* * ¸Þ½ÃÁö ¸ÞÀϹڽºÀÇ »óÅ ¾ò±â * * ¼³¸í : ÀÌ ÇÔ¼ö´Â ¸Þ½ÃÁö ¸ÞÀϹڽº¿¡ ´ëÇÑ Á¤º¸¸¦ ¾ò¾î³½´Ù. * * Àü´ÞÀÎÀÚ : pevent ÇØ´ç ¸ÞÀϹڽºÀÇ À̺¥Æ® ÄÁÆ®·Ñ ºí·Ï¿¡ ´ëÇÑ Æ÷ÀÎÅÍ. * * pdata ¸Þ½ÃÁö ¸ÞÀϹڽº¿¡ ´ëÇÑ Á¤º¸¸¦ ÀúÀåÇÒ ±¸Á¶Ã¼¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ. * * * ¸®Åϰª : OS_NO_ERR È£ÃâÀÌ ¼º°øÇßÀ½. * OS_ERR_EVENT_TYPE ¾ø´Â ¸ÞÀϹڽº¿¡ ´ëÇÑ Á¶È¸¸¦ ½ÃµµÇßÀ½. ********************************************************************************************************* */ INT8U OSMboxQuery (OS_EVENT *pevent, OS_MBOX_DATA *pdata) { INT8U i; INT8U *psrc; INT8U *pdest; OS_ENTER_CRITICAL(); if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* À¯È¿ÇÑ À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀÎÁö Á¡°Ë */ OS_EXIT_CRITICAL(); return (OS_ERR_EVENT_TYPE); } pdata->OSEventGrp = pevent->OSEventGrp; /* ¸Þ½ÃÁö ¸ÞÀϹڽºÀÇ ´ë±â ¸®½ºÆ®¸¦ º¹»ç */ psrc = &pevent->OSEventTbl[0]; pdest = &pdata->OSEventTbl[0]; for (i = 0; i < OS_EVENT_TBL_SIZE; i++) { *pdest++ = *psrc++; } pdata->OSMsg = pevent->OSEventPtr; /* ¸ÞÀϹڽº¿¡¼ ¸Þ½ÃÁö¸¦ ¾òÀ½ */ OS_EXIT_CRITICAL(); return (OS_NO_ERR); } #endif