/* ********************************************************************************************************* * uC/OS-II * The Real-Time Kernel * SEMAPHORE MANAGEMENT * * (c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL * All Rights Reserved * * V2.00 * * File : OS_SEM.C * By : Jean J. Labrosse ********************************************************************************************************* */ #ifndef OS_MASTER_FILE #include "includes.h" #endif #if OS_SEM_EN /* ********************************************************************************************************* * ´ë±â¾øÀÌ ¼¼¸¶Æ÷¾î ¾ò±â * * ¼³¸í : ÀÌ ÇÔ¼ö´Â ÀÚ¿øÀÌ »ç¿ë °¡´ÉÇÑÁö ¶Ç´Â À̺¥Æ®°¡ ¹ß»ýÇß´ÂÁö ¾Ë¾Æº¸±â À§ÇØ ¼¼¸¶Æ÷¾î¸¦ Á¡°ËÇÑ´Ù. * OSSemAccept()°¡ OSSemPend()¿Í ´Ù¸¥ Á¡Àº À̺¥Æ®°¡ ¹ß»ýÇÏÁö ¾Ê¾Ò°í, ÀÚ¿øÀÌ »ç¿ë °¡´É »óŰ¡ * ¾Æ´Ò °æ¿ì ŽºÅ©¸¦ ´ë±â»óÅ·Π¸¸µéÁö ¾Ê´Â´Ù´Â Á¡ÀÌ´Ù. * * Àü´ÞÀÎÀÚ : pevent ÇØ´ç ¼¼¸¶Æ÷¾îÀÇ À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀ» °¡¸®Å°´Â Æ÷ÀÎÅÍ. * * ¸®Åϰª : > 0 ÀÚ¿øÀÌ »ç¿ë °¡´ÉÇϰųª À̺¥Æ®°¡ ¹ß»ýÇß´Ù¸é ÀÚ¿øÀ» ¾ò±âÀ§ÇØ ¼¼¸¶Æ÷¾î Ä«¿îÆ®¸¦ * °¨¼ÒÇÑ´Ù. * == 0 ÀÚ¿øÀÌ »ç¿ë°¡´ÉÇÏÁö ¾Ê°Å³ª, À̺¥Æ®°¡ ¹ß»ýÇÏÁö ¾Ê¾Ò°Å³ª, * ¼¼¸¶Æ÷¾î¸¦ °¡¸®Å°´Â Æ÷ÀÎÅ͸¦ ÁöÁ¤ÇÏÁö ¾ÊÀº °æ¿ì. ********************************************************************************************************* */ INT16U OSSemAccept (OS_EVENT *pevent) { INT16U cnt; OS_ENTER_CRITICAL(); if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* À̺¥Æ® ºí·Ï ŸÀÔ Á¡°Ë */ OS_EXIT_CRITICAL(); return (0); } cnt = pevent->OSEventCnt; if (cnt > 0) { /* ÀÚ¿øÀÌ »ç¿ë °¡´ÉÇÑÁö È®ÀÎ */ pevent->OSEventCnt--; /* ¿¹, ¼¼¸¶Æ÷¾î¸¦ °¨¼ÒÇϰí È£ÃâÀÚ¿¡°Ô ¾Ë¸°´Ù */ } OS_EXIT_CRITICAL(); return (cnt); /* ¼¼¸¶Æ÷¾î Ä«¿îÆ® ¸®ÅÏ */ } /*$PAGE*/ /* ********************************************************************************************************* * ¼¼¸¶Æ÷¾î »ý¼º * * ¼³¸í : ÀÌ ÇÔ¼ö´Â ¼¼¸¶Æ÷¾î¸¦ »ý¼ºÇÑ´Ù. * * Àü´ÞÀÎÀÚ : cnt ¼¼¸¶Æ÷¾îÀÇ ÃʱⰪ. ÀÌ °ªÀÌ 0À̸é ÀÚ¿øÀÌ »ç¿ë °¡´ÉÇÏÁö ¾ÊÀ½ * (¶Ç´Â À̺¥Æ®°¡ ¹ß»ýÇÏÁö ¾Ê¾ÒÀ½). ÀÚ¿øÀÌ »ç¿ë °¡´ÉÇÏ´Ù¸é ÀÌ °ªÀ» 0 ¸»°í ´Ù¸¥ * °ªÀ¸·Î ÃʱâÈÇØ¾ß ÇÑ´Ù(¿¹¸¦ µé¾î, 10°³ÀÇ ÀÚ¿øÀÌ °¡¿ëÇÏ´Ù¸é ¼¼¸¶Æ÷¾î¸¦ * 10À¸·Î ÃʱâÈÇØ¾ß ÇÒ °ÍÀÌ´Ù). * * ¸®Åϰª : != (void *)0 »ý¼ºÇÑ ¼¼¸¶Æ÷¾î¿¡ ´ëÇÑ À̺¥Æ® ÄÁÆ®·Ñ ºí·Ï(OS_EVENT)À» °¡¸®Å°´Â Æ÷ÀÎÅÍ. * * == (void *)0 À̺¥Æ® ÄÜÆ®·Ñ ºí·ÏÀ» »ç¿ëÇÒ ¼ö ¾øÀ½. ********************************************************************************************************* */ OS_EVENT *OSSemCreate (INT16U cnt) { OS_EVENT *pevent; OS_ENTER_CRITICAL(); pevent = OSEventFreeList; /* ´ÙÀ½¹ø ÀÚÀ¯ À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀ» ¾ò´Â´Ù */ if (OSEventFreeList != (OS_EVENT *)0) { /* ÀÚÀ¯ ECB Ç®ÀÌ ºñ¾ú´ÂÁö È®ÀÎ */ OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; } OS_EXIT_CRITICAL(); if (pevent != (OS_EVENT *)0) { /* À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀ» ¾ò´Â´Ù */ pevent->OSEventType = OS_EVENT_TYPE_SEM; pevent->OSEventCnt = cnt; /* ¼¼¸¶Æ÷¾î ÃʱⰪ ¼³Á¤ */ 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 OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) { OS_ENTER_CRITICAL(); if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* À̺¥Æ® ºí·Ï ŸÀÔ Á¡°Ë */ OS_EXIT_CRITICAL(); *err = OS_ERR_EVENT_TYPE; } if (pevent->OSEventCnt > 0) { /* Ä«¿îÅÍ °ªÀÌ ¾ç¼öÀ̸é ÀÚ¿øÀ» »ç¿ëÇÒ ¼ö ÀÖÀ½ */ pevent->OSEventCnt--; /* Ä«¿îÅÍ °ªÀÌ ¾ç¼öÀ϶§¸¸ °ªÀ» °¨¼ÒÇÑ´Ù */ 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_SEM; /* ÀÚ¿øÀ» »ç¿ëÇÒ ¼ö ¾øÀ½. ¼¼¸¶Æ÷¾î¸¦ ±â´Ù¸² */ OSTCBCur->OSTCBDly = timeout; /* TCB¿¡ ŸÀӾƿôÀ» ÀúÀå */ OSEventTaskWait(pevent); /* ŸÀӾƿôÀ̳ª À̺¥Æ®¸¦ ±â´Ù¸®µµ·Ï ŽºÅ© ´ë±â */ OS_EXIT_CRITICAL(); OSSched(); /* ´ÙÀ½ ½ÇÇà Áغñ»óŰ¡ µÈ ¿ì¼±¼øÀ§ °áÁ¤ */ OS_ENTER_CRITICAL(); if (OSTCBCur->OSTCBStat & OS_STAT_SEM) { /* ¾ÆÁ÷µµ À̺¥Æ®¸¦ ±â´Ù¸°´Ù¸é ŸÀӾƿôÀÌ ¹ß»ýÇÑ °ÍÀÓ */ OSEventTO(pevent); OS_EXIT_CRITICAL(); *err = OS_TIMEOUT; /* ŸÀӾƿô ±â°£ ³»¿¡ À̺¥Æ®°¡ ¹ß»ýÇÏÁö ¾Ê¾ÒÀ½À» ¾Ë¸²*/ } else { OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; OS_EXIT_CRITICAL(); *err = OS_NO_ERR; } } } /*$PAGE*/ /* ********************************************************************************************************* * ¼¼¸¶Æ÷¾î ¹Ýȯ * * ¼³¸í : ÀÌ ÇÔ¼ö´Â ¼¼¸¶Æ÷¾î¿¡ ½ÅÈ£¸¦ º¸³½´Ù(½Ã±×³Îµå »óÅ·Π¸¸µç´Ù). * * Àü´ÞÀÎÀÚ : pevent ÇØ´ç ¼¼¸¶Æ÷¾îÀÇ À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀ» °¡¸®Å°´Â Æ÷ÀÎÅÍ. * * * ¸®Åϰª : OS_NO_ERR È£ÃâÀÌ ¼º°øÇؼ ¼¼¸¶Æ÷¾î·Î ½ÅÈ£¸¦ º¸³ÂÀ½. * OS_SEM_OVF ¼¼¸¶Æ÷¾î Ä«¿îÅͰ¡ ÇѰ踦 ³Ñ¾úÀ½. Áï, OSSemAccept()³ª OSSemPend()¸¦ * È£ÃâÇØ¼ ¼¼¸¶Æ÷¾î¸¦ ±â´Ù¸®´Â Ƚ¼öº¸´Ù ÀÚÁÖ ½ÅÈ£¸¦ º¸³Â´Ù´Â °ÍÀÌ´Ù. * * OS_ERR_EVENT_TYPE ¼¼¸¶Æ÷¾î¿¡ ´ëÇÑ Æ÷ÀÎÅ͸¦ ÁöÁ¤ÇÏÁö ¾Ê¾ÒÀ½. ********************************************************************************************************* */ INT8U OSSemPost (OS_EVENT *pevent) { OS_ENTER_CRITICAL(); if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* À̺¥Æ® ºí·Ï ŸÀÔ Á¡°Ë */ OS_EXIT_CRITICAL(); return (OS_ERR_EVENT_TYPE); } if (pevent->OSEventGrp) { /* ¾Æ¹« ŽºÅ©³ª ¼¼¸¶Æ÷¾î¸¦ ±â´Ù¸®´ÂÁö È®ÀÎ */ OSEventTaskRdy(pevent, (void *)0, OS_STAT_SEM); /* ´ë±â Áß ÃÖ¿ì¼±¼øÀ§ ŽºÅ©¸¦ Áغñ»óÅ·ΠÇÔ*/ OS_EXIT_CRITICAL(); OSSched(); /* ½ÇÇà Áغñ»óŠŽºÅ© Áß ÃÖ»óÀ§ ¿ì¼±¼øÀ§ °áÁ¤ */ return (OS_NO_ERR); } else { if (pevent->OSEventCnt < 65535) { /* ¼¼¸¶Æ÷¾î ¿À¹öÇ÷ο찡 ¹ß»ýÇÏÁö ¾ÊÀ» °ÍÀ» È®ÀÎ */ pevent->OSEventCnt++; /* À̺¥Æ®¸¦ µî·ÏÇϱâ À§ÇØ ¼¼¸¶Æ÷¾î Ä«¿îÆ® Áõ°¡ */ OS_EXIT_CRITICAL(); return (OS_NO_ERR); } else { /* ¼¼¸¶Æ÷¾î Ä«¿îÅͰªÀÌ ÃÖ´ë°ª¿¡ µµ´ÞÇßÀ½ */ OS_EXIT_CRITICAL(); return (OS_SEM_OVF); } } } /* ********************************************************************************************************* * ¼¼¸¶Æ÷¾î »óÅ ¾ò±â * * ¼³¸í : ÀÌ ÇÔ¼ö´Â ¼¼¸¶Æ÷¾î¿¡ ´ëÇÑ Á¤º¸¸¦ ¾ò¾î³½´Ù. * * Àü´ÞÀÎÀÚ : pevent ÇØ´ç ¼¼¸¶Æ÷¾îÀÇ À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀ» °¡¸®Å°´Â Æ÷ÀÎÅÍ. * * * pdata ¼¼¸¶Æ÷¾î¿¡ ´ëÇÑ Á¤º¸¸¦ ÀúÀåÇÒ ±¸Á¶Ã¼¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ. * * * ¸®Åϰª : OS_NO_ERR È£ÃâÀÌ ¼º°øÇؼ ¼¼¸¶Æ÷¾î Á¤º¸¸¦ ¾ò¾î³ÂÀ½. * OS_ERR_EVENT_TYPE ¼¼¸¶Æ÷¾î°¡ ¾Æ´Ñ ±¸Á¶Ã¼ÀÇ Á¤º¸¸¦ ¾Ë·Á ÇßÀ½. ********************************************************************************************************* */ INT8U OSSemQuery (OS_EVENT *pevent, OS_SEM_DATA *pdata) { INT8U i; INT8U *psrc; INT8U *pdest; OS_ENTER_CRITICAL(); if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* À̺¥Æ® ºí·Ï ŸÀÔ Á¡°Ë */ 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->OSCnt = pevent->OSEventCnt; /* ¼¼¸¶Æ÷¾î Ä«¿îÅͰªÀ» ¾ò´Â´Ù */ OS_EXIT_CRITICAL(); return (OS_NO_ERR); } #endif