/*
*********************************************************************************************************
*                                                uC/OS-II
*                                          The Real-Time Kernel
*                                        MESSAGE QUEUE MANAGEMENT
*
*                        (c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL
*                                           All Rights Reserved
*
*                                                  V2.00
*
* File : OS_Q.C
* By   : Jean J. Labrosse
*********************************************************************************************************
*/

#ifndef  OS_MASTER_FILE
#include "includes.h"
#endif

#if OS_Q_EN && (OS_MAX_QS >= 2)
/*
*********************************************************************************************************
*                                           Áö¿ª µ¥ÀÌÅÍ Å¸ÀÔ
*********************************************************************************************************
*/

typedef struct os_q {                  /* Å¥ ÄÁÆ®·Ñ ºí·Ï                                               */
    struct os_q   *OSQPtr;             /* ÀÚÀ¯ ºí·Ï ¸®½ºÆ®¿¡¼­ÀÇ ´ÙÀ½ Å¥ ÄÁÆ®·Ñ ºí·ÏÀ¸·ÎÀÇ ¸µÅ©        */
    void         **OSQStart;           /* Å¥ µ¥ÀÌÅÍÀÇ ½ÃÀÛÀ» °¡¸®Å°´Â Æ÷ÀÎÅÍ                           */
    void         **OSQEnd;             /* Å¥ µ¥ÀÌÅÍÀÇ ¸¶Áö¸·À» °¡¸®Å°´Â Æ÷ÀÎÅÍ                         */
    void         **OSQIn;              /* Å¥¿¡¼­ ´ÙÀ½ µ¥ÀÌÅ͸¦ »ðÀÔÇÒ °÷À» °¡¸®Å°´Â Æ÷ÀÎÅÍ             */
    void         **OSQOut;             /* Å¥¿¡¼­ ´ÙÀ½À¸·Î »©³¾ µ¥ÀÌÅ͸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ                */
    INT16U         OSQSize;            /* Å¥ Å©±â(¿ä¼ÒÀÇ ÃÖ´ë ¼ö)                                      */
    INT16U         OSQEntries;         /* Å¥¿¡ ÀÖ´Â µ¥ÀÌÅÍ ¿ä¼Ò ¼ö                                     */
} OS_Q;

/*
*********************************************************************************************************
*                                             Áö¿ªÀû Àü¿ªº¯¼ö
*********************************************************************************************************
*/

static  OS_Q        *OSQFreeList;              /* ÀÚÀ¯ Å¥ ÄÁÆ®·Ñ ºí·Ï ¸®½ºÆ®¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ         */
static  OS_Q         OSQTbl[OS_MAX_QS];        /* Å¥ ÄÁÆ®·Ñ ºí·Ï Å×ÀÌºí                                */

/*$PAGE*/
/*
*********************************************************************************************************
*                                    ´ë±â¾øÀÌ ¸Þ½ÃÁö Å¥¿¡¼­ ¸Þ½ÃÁö ¹Þ±â
*
* ¼³¸í       : ÀÌ ÇÔ¼ö´Â Å¥¿¡ ¸Þ½ÃÁö°¡ ÀÖ´ÂÁö Á¡°ËÇÑ´Ù. OSQAccept()°¡ OSQPend()¿Í ´Ù¸¥ Á¡Àº
*              ¸Þ½ÃÁö°¡ ¾ø´õ¶óµµ È£Ãâ ŽºÅ©°¡ ´ë±â»óÅ·Πµé¾î°¡Áö ¾Ê´Â´Ù´Â °ÍÀÌ´Ù.
*
* Àü´ÞÀÎÀÚ   : pevent        ÇØ´ç Å¥ÀÇ À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀ» °¡¸®Å°´Â Æ÷ÀÎÅÍ.
*
* ¸®Åϰª     : != (void *)0  Å¥¿¡ ÀÖ´Â À¯È¿ÇÑ ¸Þ½ÃÁö. ½ÇÁ¦·Î ÀÌ ¸Þ½ÃÁö´Â Å¥¿¡¼­ Áö¿öÁö¹Ç·Î
*                            ´ÙÀ½¿¡ OSQAccept()¸¦ È£ÃâÇϸé Å¥¿¡ ÀÖ´Â ¸Þ½ÃÁö´Â Çϳª°¡ ÁÙ¾îµç »óŰ¡
*                            µÉ °ÍÀÌ´Ù.
*              == (void *)0  Å¥°¡ ºó °æ¿ì.
*                            ¹«È¿ÇÑ À̺¥Æ® ÄÁÆ®·Ñ ºí·Ï ŸÀÔÀ» ÁöÁ¤ÇÑ °æ¿ì.
*********************************************************************************************************
*/

void *OSQAccept (OS_EVENT *pevent)
{
    void  *msg;
    OS_Q  *pq;


    OS_ENTER_CRITICAL();
    if (pevent->OSEventType != OS_EVENT_TYPE_Q) {     /* À¯È¿ÇÑ À̺¥Æ® ºí·Ï ŸÀÔÀÎÁö È®ÀÎ              */
        OS_EXIT_CRITICAL();
        return ((void *)0);
    }
    pq = pevent->OSEventPtr;                     /* Å¥ ÄÁÆ®·Ñ ºí·ÏÀ» °¡¸®Å²´Ù                          */
    if (pq->OSQEntries != 0) {                   /* Å¥¿¡ ¸Þ½ÃÁö°¡ ÀÖ´ÂÁö È®ÀÎ                          */
        msg = *pq->OSQOut++;                     /* ¿¹, Å¥¿¡ °¡Àå ¸ÕÀú ÀúÀåÇÑ ¸Þ½ÃÁö¸¦ »©³½´Ù          */
        pq->OSQEntries--;                        /* Å¥ÀÇ ¸Þ½ÃÁö Ä«¿îÅÍ °»½Å                            */
        if (pq->OSQOut == pq->OSQEnd) {          /* Å¥ÀÇ ¸¶Áö¸·À» °¡¸®Å°°í ÀÖ´Ù¸é ½ÃÀÛÀ» °¡¸®Å²´Ù      */
            pq->OSQOut = pq->OSQStart;
        }
    } else {
        msg = (void *)0;                         /* Å¥°¡ ºñ¾úÀ½                                        */
    }
    OS_EXIT_CRITICAL();
    return (msg);                                /* ¸Þ½ÃÁö ¶Ç´Â NULLÀ» ¸®ÅÏ                            */
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                            ¸Þ½ÃÁö Å¥ »ý¼º
*
* ¼³¸í       : ÀÌ ÇÔ¼ö´Â ÀÚÀ¯ À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀÌ À¯È¿ÇÑ °æ¿ì ¸Þ½ÃÁö Å¥¸¦ »ý¼ºÇÑ´Ù.
*
* Àü´ÞÀÎÀÚ   : start         Å¥¿¡¼­ ¸Þ½ÃÁö ÀúÀå ¿µ¿ªÀÇ ±âÁØ ¾îµå·¹½º¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ.
*                            ÀúÀå ¿µ¿ªÀº ´ÙÀ½°ú °°ÀÌ voidÇü Æ÷ÀÎÅÍÀÇ ¹è¿­·Î ¼±¾ðÇØ¾ß ÇÑ´Ù.
*
*                            void *MessageStorage[size]
*
*              size          ÀúÀå ¿µ¿ªÀÇ ¿ä¼ö ¼ö.
*
* ¸®Åϰª     : != (void *)0  »ý¼ºÇÑ Å¥ÀÇ À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀ» °¡¸®Å°´Â Æ÷ÀÎÅÍ.
*
*              == (void *)0  À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀÌ À¯¿ëÇÏÁö ¾ÊÀº °æ¿ì.
*********************************************************************************************************
*/

OS_EVENT *OSQCreate (void **start, INT16U size)
{
    OS_EVENT *pevent;
    OS_Q     *pq;


    OS_ENTER_CRITICAL();
    pevent = OSEventFreeList;                    /* ´ÙÀ½ ÀÚÀ¯ À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀ» ¾ò´Â´Ù              */
    if (OSEventFreeList != (OS_EVENT *)0) {      /* ÀÚÀ¯ ECB Ç®ÀÌ ºñ¾ú´ÂÁö È®ÀÎ                        */
        OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
    }
    OS_EXIT_CRITICAL();
    if (pevent != (OS_EVENT *)0) {               /* À¯È¿ÇÑ À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀ» ¾ò¾ú´ÂÁö È®ÀÎ          */
        OS_ENTER_CRITICAL();                     /* ÀÚÀ¯ Å¥ ÄÁÆ®·Ñ ºí·ÏÀ» ¾ò´Â´Ù                       */
        pq = OSQFreeList;
        if (OSQFreeList != (OS_Q *)0) {
            OSQFreeList = OSQFreeList->OSQPtr;
        }
        OS_EXIT_CRITICAL();
        if (pq != (OS_Q *)0) {                   /* À¯È¿ÇÑ Å¥ ÄÁÆ®·Ñ ºí·ÏÀ» ¾ò¾ú´ÂÁö È®ÀÎ              */
            pq->OSQStart        = start;         /* ¿¹, Å¥ ÃʱâÈ­                                      */
            pq->OSQEnd          = &start[size];
            pq->OSQIn           = start;
            pq->OSQOut          = start;
            pq->OSQSize         = size;
            pq->OSQEntries      = 0;
            pevent->OSEventType = OS_EVENT_TYPE_Q;
            pevent->OSEventPtr  = pq;
            OSEventWaitListInit(pevent);
        } else {                                 /* ¾Æ´Ï¿À,  Å¥ ÄÁÆ®·Ñ ºí·ÏÀ» ¾òÁö ¸øÇßÀ¸¹Ç·Î...       */
            OS_ENTER_CRITICAL();                 /* ...¿¡·¯¸¦ ¾Ë·ÁÁÖ´Â °ªÀ» ¸®ÅÏ                       */
            pevent->OSEventPtr = (void *)OSEventFreeList;
            OSEventFreeList    = pevent;
            OS_EXIT_CRITICAL();
            pevent = (OS_EVENT *)0;
        }
    }
    return (pevent);
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                           ¸Þ½ÃÁö Å¥ ºñ¿ì±â
*
* ¼³¸í       : ÀÌ ÇÔ¼ö´Â ¸Þ½ÃÁö Å¥ÀÇ ³»¿ëÀ» Áö¿î´Ù.
*
* Àü´ÞÀÎÀÚ   : ¾øÀ½
*
* ¸®Åϰª     : OS_NO_ERR          È£Ãâ ¼º°ø.
*              OS_ERR_EVENT_TYPE  Å¥¸¦ °¡¸®Å°´Â Æ÷ÀÎÅ͸¦ Àü´ÞÇÏÁö ¾ÊÀº °æ¿ì.
*********************************************************************************************************
*/

INT8U OSQFlush (OS_EVENT *pevent)
{
    OS_Q  *pq;
    

    OS_ENTER_CRITICAL();
    if (pevent->OSEventType != OS_EVENT_TYPE_Q) {     /* À̺¥Æ® ÄÁÆ®·Ñ ºí·Ï ŸÀÔ È®ÀÎ                  */
        OS_EXIT_CRITICAL();
        return (OS_ERR_EVENT_TYPE);
    }
    pq             = pevent->OSEventPtr;              /* Å¥ ÀúÀ念¿ªÀ» °¡¸®Å²´Ù                        */
    pq->OSQIn      = pq->OSQStart;
    pq->OSQOut     = pq->OSQStart;
    pq->OSQEntries = 0;
    OS_EXIT_CRITICAL();
    return (OS_NO_ERR);
}

/*$PAGE*/
/*
*********************************************************************************************************
*                                             Å¥ ¸ðµâ ÃʱâÈ­
*
* ¼³¸í       : ÀÌ ÇÔ¼ö´Â ¸Þ½ÃÁö Å¥ ¸ðµâÀ» ÃʱâÈ­ Çϱâ À§ÇØ uC/OS-II°¡ È£ÃâÇÑ´Ù.
*              ÀÀ¿ëÇÁ·Î±×·¥Àº ÀÌ ÇÔ¼ö¸¦ È£ÃâÇÏ¸é ¾ÈµÈ´Ù.
*
* Àü´ÞÀÎÀÚ   : ¾øÀ½
*
* ¸®Åϰª     : ¾øÀ½
*********************************************************************************************************
*/

void OSQInit (void)
{
    INT16U i;


    for (i = 0; i < (OS_MAX_QS - 1); i++) {      /* ÀÚÀ¯ Å¥ ÄÁÆ®·Ñ ºí·Ï ¸®½ºÆ® ÃʱâÈ­                  */
        OSQTbl[i].OSQPtr = &OSQTbl[i+1];
    }
    OSQTbl[OS_MAX_QS - 1].OSQPtr = (OS_Q *)0;
    OSQFreeList                  = &OSQTbl[0];
}

/*$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 *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
{
    void  *msg;
    OS_Q  *pq;


    OS_ENTER_CRITICAL();
    if (pevent->OSEventType != OS_EVENT_TYPE_Q) {/* À̺¥Æ® ºí·Ï ŸÀÔÀ» È®ÀÎ                            */
        OS_EXIT_CRITICAL();
        *err = OS_ERR_EVENT_TYPE;
        return ((void *)0);
    }
    pq = pevent->OSEventPtr;                     /* Å¥ ÄÁÆ®·Ñ ºí·ÏÀ» °¡¸®Å²´Ù                          */
    if (pq->OSQEntries != 0) {                   /* Å¥¿¡ ¸Þ½ÃÁö°¡ ÀÖ´ÂÁö È®ÀÎ                          */
        msg = *pq->OSQOut++;                     /* ¿¹, Å¥¿¡ °¡Àå ¸ÕÀú ÀúÀåÇÑ ¸Þ½ÃÁö¸¦ »©³½´Ù          */
        pq->OSQEntries--;                        /* Å¥ÀÇ ¸Þ½ÃÁö Ä«¿îÅÍ °»½Å                            */
        if (pq->OSQOut == pq->OSQEnd) {          /* Å¥ÀÇ ¸¶Áö¸·À» °¡¸®Å°°í ÀÖ´Ù¸é ½ÃÀÛÀ» °¡¸®Å²´Ù      */
            pq->OSQOut = pq->OSQStart;
        }
        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_Q;     /* ¸Þ½ÃÁö°¡ µµÂøÇÒ ¶§±îÁö ŽºÅ©¸¦ ´ë±â »óÅ·ΠÇÑ´Ù   */
        OSTCBCur->OSTCBDly      = timeout;       /* TCB¿¡ ŸÀӾƿô °ªÀ» ÀúÀå                           */
        OSEventTaskWait(pevent);                 /* À̺¥Æ®³ª ŸÀӾƿôÀÌ ¹ß»ýÇÒ ¶§±îÁö ŽºÅ© ´ë±â      */
        OS_EXIT_CRITICAL();
        OSSched();                               /* ´ÙÀ½ ½ÇÇà Áغñ»óŰ¡ µÈ ¿ì¼±¼øÀ§ °áÁ¤              */
        OS_ENTER_CRITICAL();
        if ((msg = OSTCBCur->OSTCBMsg) != (void *)0) {/* ¸Þ½ÃÁö¸¦ ¾ò¾ú´Â°¡?                            */
            OSTCBCur->OSTCBMsg      = (void *)0;      /* TCB¿¡¼­ ¸Þ½ÃÁö¸¦ Á¦°Å(Put there by QPost)     */
            OSTCBCur->OSTCBStat     = OS_STAT_RDY;
            OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;  /* ´õ ÀÌ»ó À̺¥Æ®¸¦ ±â´Ù¸®Áö ¾Ê´Â´Ù              */
            OS_EXIT_CRITICAL();
            *err                    = OS_NO_ERR;
        } else if (OSTCBCur->OSTCBStat & OS_STAT_Q) { /* Å¥¿¡ ´ë±â ÁßÀÎ »óÅ¸é ŸÀӾƿôÀÌ ¹ß»ýÇÑ °ÍÀÓ  */
            OSEventTO(pevent);
            OS_EXIT_CRITICAL();
            msg                     = (void *)0;      /* ¸Þ½ÃÁö ¾øÀ½                                   */
            *err                    = OS_TIMEOUT;     /* ŸÀӾƿôÀ» ¾Ë·ÁÁÜ                             */
        } else {
            msg = *pq->OSQOut++;                      /* Å¥¿¡¼­ ¸Þ½ÃÁö¸¦ »©³¿                          */
            pq->OSQEntries--;                         /* Å¥ÀÇ ¸Þ½ÃÁö °³¼ö¸¦ °»½Å                       */
            if (pq->OSQOut == pq->OSQEnd) {           /* Æ÷ÀÎÅͰ¡ ÀúÀ念¿ª ³¡À» °¡¸®Å°¸é óÀ½À¸·Î º¯°æ */
                pq->OSQOut = pq->OSQStart;
            }
            OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
            OS_EXIT_CRITICAL();
            *err = OS_NO_ERR;
        }
    }                                                 
    return (msg);                                     /* ¸Þ½ÃÁö ¶Ç´Â NULLÀ» ¸®ÅÏ                       */
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                   FIFO ¹æ½Ä ¸Þ½ÃÁö Å¥¿¡ ¸Þ½ÃÁö º¸³»±â
*
* ¼³¸í       : ÀÌ ÇÔ¼ö´Â ¸Þ½ÃÁö¸¦ Å¥·Î º¸³½´Ù.
*
* Àü´ÞÀÎÀÚ   : pevent        ÇØ´ç Å¥ÀÇ À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀ» °¡¸®Å°´Â Æ÷ÀÎÅÍ.
*
*              msg           Àü¼ÛÇÒ ¸Þ½ÃÁö¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ. NULLÀ» ÁöÁ¤ÇÏ¸é ¾ÈµÈ´Ù.
*
* ¸®Åϰª     : OS_NO_ERR          È£ÃâÀÌ ¼º°øÇؼ­ ¸Þ½ÃÁö¸¦ ¼ÛºÎÇßÀ½.
*              OS_Q_FULL          Å¥°¡ ²Ë Â÷¼­ ¸Þ½ÃÁö¸¦ ¹ÞÀ» ¼ö ¾øÀ½.
*              OS_ERR_EVENT_TYPE  Å¥¿¡ ´ëÇÑ Æ÷ÀÎÅ͸¦ ÁöÁ¤ÇÏÁö ¾Ê¾ÒÀ½.
*********************************************************************************************************
*/

INT8U OSQPost (OS_EVENT *pevent, void *msg)
{
    OS_Q   *pq;


    OS_ENTER_CRITICAL();
    if (pevent->OSEventType != OS_EVENT_TYPE_Q) {     /* À̺¥Æ® ºí·Ï ŸÀÔ È®ÀÎ                         */
        OS_EXIT_CRITICAL();
        return (OS_ERR_EVENT_TYPE);
    }
    if (pevent->OSEventGrp) {                         /* ¾Æ¹« ŽºÅ©³ª Å¥¿¡¼­ ´ë±â ÁßÀÎÁö È®ÀÎ         */
        OSEventTaskRdy(pevent, msg, OS_STAT_Q);       /* ´ë±â ÁßÀÎ ÃÖ¿ì¼±¼øÀ§ ŽºÅ©¸¦ Áغñ»óÅ·ΠÇÔ   */
        OS_EXIT_CRITICAL();
        OSSched();                                    /* ½ÇÇà Áغñ»óŠŽºÅ© Áß ÃÖ»óÀ§ ¿ì¼±¼øÀ§ °áÁ¤  */
        return (OS_NO_ERR);
    } else {
        pq = pevent->OSEventPtr;                      /* Å¥ ÄÁÆ®·Ñ ºí·ÏÀ» °¡¸®Å´                       */
        if (pq->OSQEntries >= pq->OSQSize) {          /* Å¥°¡ ²Ë Â÷Áö ¾Ê¾Ò´ÂÁö È®ÀÎ                    */
            OS_EXIT_CRITICAL();
            return (OS_Q_FULL);
        } else {
            *pq->OSQIn++ = msg;                       /* ¸Þ½ÃÁö¸¦ Å¥¿¡ »ðÀÔ                            */
            pq->OSQEntries++;                         /* Å¥ÀÇ ¸Þ½ÃÁö Ä«¿îÅ͸¦ Áõ°¡                     */
            if (pq->OSQIn == pq->OSQEnd) {            /* Æ÷ÀÎÅͰ¡ ³¡À» °¡¸®Å°¸é ½ÃÀÛÀ¸·Î µÇµ¹¸²        */
                pq->OSQIn = pq->OSQStart;
            }
            OS_EXIT_CRITICAL();
        }
        return (OS_NO_ERR);
    }
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                  LIFO ¹æ½ÄÀ¸·Î ¸Þ½ÃÁö Å¥¿¡ ¸Þ½ÃÁö º¸³»±â
*
* ¼³¸í       : ÀÌ ÇÔ¼öµµ Å¥¿¡ ¸Þ½ÃÁö¸¦ º¸³½´Ù. OSQPost()¿Í ´Ù¸¥ Á¡Àº Å¥ÀÇ ÈĹ̰¡ ¾Æ´Ï°í ¼±µÎ¿¡ ¸Þ½ÃÁö¸¦
*              ÀúÀåÇÑ´Ù´Â Á¡ÀÌ´Ù.
*              µû¶ó¼­ OSQPostFront()¸¦ »ç¿ëÇÏ¸é ±ä±Þ ¸Þ½ÃÁö¸¦ Àü¼ÛÇÒ ¼ö ÀÖ´Ù.
*
* Àü´ÞÀÎÀÚ   : pevent        ÇØ´ç Å¥ÀÇ À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀ» °¡¸®Å°´Â Æ÷ÀÎÅÍ.
*
*              msg           Àü¼ÛÇÒ ¸Þ½ÃÁö¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ. NULLÀ» ÁöÁ¤ÇÏ¸é ¾ÈµÈ´Ù.
*
* ¸®Åϰª     : OS_NO_ERR          È£ÃâÀÌ ¼º°øÇؼ­ ¸Þ½ÃÁö¸¦ ¼ÛºÎÇßÀ½.
*              OS_Q_FULL          Å¥°¡ ²Ë Â÷¼­ ¸Þ½ÃÁö¸¦ ¹ÞÀ» ¼ö ¾øÀ½.
*              OS_ERR_EVENT_TYPE  Å¥¿¡ ´ëÇÑ Æ÷ÀÎÅ͸¦ ÁöÁ¤ÇÏÁö ¾Ê¾ÒÀ½.
*********************************************************************************************************
*/

INT8U OSQPostFront (OS_EVENT *pevent, void *msg)
{
    OS_Q   *pq;


    OS_ENTER_CRITICAL();
    if (pevent->OSEventType != OS_EVENT_TYPE_Q) {     /* À̺¥Æ® ºí·Ï ŸÀÔ È®ÀÎ                         */
        OS_EXIT_CRITICAL();
        return (OS_ERR_EVENT_TYPE);
    }
    if (pevent->OSEventGrp) {                         /* ¾Æ¹« ŽºÅ©³ª Å¥¿¡¼­ ´ë±â ÁßÀÎÁö È®ÀÎ         */
        OSEventTaskRdy(pevent, msg, OS_STAT_Q);       /* ´ë±â ÁßÀÎ ÃÖ¿ì¼±¼øÀ§ ŽºÅ©¸¦ Áغñ»óÅ·ΠÇÔ   */
        OS_EXIT_CRITICAL();
        OSSched();                                    /* ½ÇÇà Áغñ»óŠŽºÅ© Áß ÃÖ»óÀ§ ¿ì¼±¼øÀ§ °áÁ¤  */
        return (OS_NO_ERR);
    } else {
        pq = pevent->OSEventPtr;                      /* Å¥ ÄÁÆ®·Ñ ºí·ÏÀ» °¡¸®Å´                       */
        if (pq->OSQEntries >= pq->OSQSize) {          /* Å¥°¡ ²Ë Â÷Áö ¾Ê¾Ò´ÂÁö È®ÀÎ                    */
            OS_EXIT_CRITICAL();
            return (OS_Q_FULL);
        } else {
            if (pq->OSQOut == pq->OSQStart) {         /* Æ÷ÀÎÅͰ¡ ½ÃÀÛÀ» °¡¸®Å°¸é ³¡À¸·Î µÇµ¹¸²        */
                pq->OSQOut = pq->OSQEnd;
            }
            pq->OSQOut--;
            *pq->OSQOut = msg;                        /* ¸Þ½ÃÁö¸¦ Å¥¿¡ »ðÀÔ                            */
            pq->OSQEntries++;                         /* Å¥ÀÇ ¸Þ½ÃÁö Ä«¿îÅ͸¦ Áõ°¡                     */
            OS_EXIT_CRITICAL();
        }
        return (OS_NO_ERR);
    }
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                         ¸Þ½ÃÁö Å¥ÀÇ »óÅ ¾ò±â
*
* ¼³¸í       : ÀÌ ÇÔ¼ö´Â ¸ÞÁöÁö Å¥¿¡ ´ëÇÑ Á¤º¸¸¦ ¾ò´Â´Ù.
*
* Àü´ÞÀÎÀÚ   : pevent        ÇØ´ç Å¥ÀÇ À̺¥Æ® ÄÁÆ®·Ñ ºí·ÏÀ» °¡¸®Å°´Â Æ÷ÀÎÅÍ.
*
*              pdata         ¸Þ½ÃÁö Å¥¿¡ ´ëÇÑ Á¤º¸¸¦ ÀúÀåÇÒ ±¸Á¶Ã¼¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ.
*
*
* ¸®Åϰª     : OS_NO_ERR          È£Ãâ ¼º°ø.
*              OS_ERR_EVENT_TYPE  Å¥¿¡ ´ëÇÑ Æ÷ÀÎÅ͸¦ ÁöÁ¤ÇÏÁö ¾Ê¾ÒÀ½.
*********************************************************************************************************
*/

INT8U OSQQuery (OS_EVENT *pevent, OS_Q_DATA *pdata)
{
    OS_Q   *pq;
    INT8U   i;
    INT8U  *psrc;
    INT8U  *pdest;
    
    
    OS_ENTER_CRITICAL();
    if (pevent->OSEventType != OS_EVENT_TYPE_Q) {          /* À̺¥Æ® ºí·Ï ŸÀÔ È®ÀÎ                    */
        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++;   
    }
    pq = (OS_Q *)pevent->OSEventPtr;
    if (pq->OSQEntries > 0) {
        pdata->OSMsg = pq->OSQOut;                         /* ´ÙÀ½ ¸Þ½ÃÁö°¡ ÀÖÀ¸¸é ±× ¸Þ½ÃÁö¸¦ ¾ò´Â´Ù  */
    } else {
        pdata->OSMsg = (void *)0;
    }
    pdata->OSNMsgs = pq->OSQEntries;
    pdata->OSQSize = pq->OSQSize;
    OS_EXIT_CRITICAL();
    return (OS_NO_ERR);
}
#endif