⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ucos.c

📁 ppc860平台上移植uc OS的实例
💻 C
📖 第 1 页 / 共 5 页
字号:
    OS_TCB *ptcb;
    UBYTE   x;
    UBYTE   y;
    UBYTE   bitx;
    UBYTE   bity;
    UBYTE   p;


    OS_ENTER_CRITICAL();
    if (pevent->OSEventGrp) {                         /* See if any task pending on mailbox            */
        y    = OSUnMapTbl[pevent->OSEventGrp];        /* Find highest prio. task waiting for message   */
        bity = OSMapTbl[y];
        x    = OSUnMapTbl[pevent->OSEventTbl[y]];
        bitx = OSMapTbl[x];
        p    = (y << 3) + x;                          /* Find the priority of the task                 */
        if ((pevent->OSEventTbl[y] &= ~bitx) == 0) {  /* Remove this task from the waiting list        */
            pevent->OSEventGrp &= ~bity;
        }
        ptcb                 =  OSTCBPrioTbl[p];      /* Point to this task's OS_TCB                   */
        ptcb->OSTCBDly       =  0;                    /* Prevent OSTimeTick() from readying task       */
        ptcb->OSTCBEventPtr  = (OS_EVENT *)0;         /* Unlink ECB from this task                     */
        ptcb->OSTCBMsg       =  msg;                  /* Send message directly to waiting task         */
        ptcb->OSTCBStat     &= ~OS_STAT_MBOX;         /* Clear bit associated with event type          */
        if (ptcb->OSTCBStat == OS_STAT_RDY) {         /* See if task is ready (could be suspended)     */
            OSRdyGrp        |=  bity;                 /* Put task in the ready to run list             */
            OSRdyTbl[y]     |=  bitx;
        }
        OS_EXIT_CRITICAL();
        OSSched();                                    /* Find highest priority task ready to run       */
        return (OS_NO_ERR);
    } else {
        if (pevent->OSEventPtr != (void *)0) {        /* Make sure mailbox doesn't already have a msg  */
            OS_EXIT_CRITICAL();
            return (OS_MBOX_FULL);
        } else {
            pevent->OSEventPtr = msg;                 /* Place message in mailbox                      */
            OS_EXIT_CRITICAL();
            return (OS_NO_ERR);
        }
    }
}
#endif
/*$PAGE*/
#if OS_Q_EN && (OS_MAX_QS > 0)
/*
*********************************************************************************************************
*                                       INITIALIZE MESSAGE QUEUE
*********************************************************************************************************
*/

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


    OS_ENTER_CRITICAL();
    pevent = OSEventFreeList;                    /* Get next free event control block                  */
    if (OSEventFreeList != (OS_EVENT *)0) {      /* See if pool of free ECB pool was empty             */
        OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
    }
    OS_EXIT_CRITICAL();
    if (pevent != (OS_EVENT *)0) {               /* See if we have an event control block              */
        OS_ENTER_CRITICAL();                     /* Get a free queue control block                     */
        pq = OSQFreeList;
        if (OSQFreeList != (OS_Q *)0) {
            OSQFreeList = OSQFreeList->OSQPtr;
        }
        OS_EXIT_CRITICAL();
        if (pq != (OS_Q *)0) {                   /* See if we were able to get a queue control block   */
            pq->OSQStart          = start;       /* Yes, initialize the queue                          */
            pq->OSQEnd            = &start[size];
            pq->OSQIn             = start;
            pq->OSQOut            = start;
            pq->OSQSize           = size;
            pq->OSQEntries        = 0;
            pevent->OSEventPtr    = pq;
            pevent->OSEventGrp    = 0x00;        /* Initialize rest of event control block             */
            pevent->OSEventTbl[0] = 0x00;
            pevent->OSEventTbl[1] = 0x00;
            pevent->OSEventTbl[2] = 0x00;
            pevent->OSEventTbl[3] = 0x00;
            pevent->OSEventTbl[4] = 0x00;
            pevent->OSEventTbl[5] = 0x00;
            pevent->OSEventTbl[6] = 0x00;
            pevent->OSEventTbl[7] = 0x00;
        } else {                                 /* No,  since we couldn't get a queue control block   */
            OS_ENTER_CRITICAL();                 /* Return event control block on error                */
            pevent->OSEventPtr = (void *)OSEventFreeList;
            OSEventFreeList    = pevent;
            OS_EXIT_CRITICAL();
            pevent = (OS_EVENT *)0;
        }
    }
    return (pevent);
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                      ACCEPT MESSAGE FROM QUEUE
*
* Description: This function checks the queue to see if a message is available.  Unlike OSQPend(),
*              OSQAccept() does not suspend the calling task if a message is not available.
* Arguments  : 'pevent'      is a pointer to the event control block
* Returns    : != (void *)0  is the message in the queue if one is available.  The message is removed
*                            from the so the next time OSQAccept() is called, the queue will contain
*                            one less entry.
*              == (void *)0  if the queue is empty
*********************************************************************************************************
*/

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


    OS_ENTER_CRITICAL();
    pq = pevent->OSEventPtr;                     /* Point at queue control block                       */
    if (pq->OSQEntries != 0) {                   /* See if any messages in the queue                   */
        msg = *pq->OSQOut++;                     /* Yes, extract oldest message from the queue         */
        pq->OSQEntries--;                        /* Update the number of entries in the queue          */
        if (pq->OSQOut == pq->OSQEnd) {          /* Wrap OUT pointer if we are at the end of the queue */
            pq->OSQOut = pq->OSQStart;
        }
    } else {
        msg = (void *)0;                         /* Queue is empty                                     */
    }
    OS_EXIT_CRITICAL();
    return (msg);                                /* Return message received (or NULL)                  */
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                     PEND ON A QUEUE FOR A MESSAGE
*********************************************************************************************************
*/

void *OSQPend(OS_EVENT *pevent, UWORD timeout, UBYTE *err)
{
    void  *msg;
    OS_Q  *pq;


    OS_ENTER_CRITICAL();
    pq = pevent->OSEventPtr;                     /* Point at queue control block                       */
    if (pq->OSQEntries != 0) {                   /* See if any messages in the queue                   */
        msg = *pq->OSQOut++;                     /* Yes, extract oldest message from the queue         */
        pq->OSQEntries--;                        /* Update the number of entries in the queue          */
        if (pq->OSQOut == pq->OSQEnd) {          /* Wrap OUT pointer if we are at the end of the queue */
            pq->OSQOut = pq->OSQStart;
        }
        OS_EXIT_CRITICAL();
        *err = OS_NO_ERR;
    } else {
        OSTCBCur->OSTCBStat    |= OS_STAT_Q;     /* Task will have to pend for a message to be posted  */
        OSTCBCur->OSTCBDly      = timeout;       /* Load timeout into TCB                              */
        OSTCBCur->OSTCBEventPtr = pevent;        /* Store pointer to event control block in TCB        */
        if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) {  /* Task no longer ready      */
            OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
        }
        pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX;      /* Put task in waiting list  */
        pevent->OSEventGrp                   |= OSTCBCur->OSTCBBitY;
        OS_EXIT_CRITICAL();
        OSSched();                               /* Find next highest priority task ready to run       */
        OS_ENTER_CRITICAL();
        if ((msg = OSTCBCur->OSTCBMsg) != (void *)0) {/* Did we get a message?                         */
            OSTCBCur->OSTCBMsg      = (void *)0;      /* Extract message from TCB (Put there by QPost) */
            OSTCBCur->OSTCBStat     = OS_STAT_RDY;
            OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;  /* No longer waiting for event                   */
            OS_EXIT_CRITICAL();
            *err                    = OS_NO_ERR;
        } else if (OSTCBCur->OSTCBStat & OS_STAT_Q) { /* Timed out if status indicates pending on Q    */
            if ((pevent->OSEventTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) {
                pevent->OSEventGrp &= ~OSTCBCur->OSTCBBitY;
            }
            OSTCBCur->OSTCBStat     = OS_STAT_RDY;    /* Set status to ready                           */
            OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;  /* No longer waiting for event                   */
            OS_EXIT_CRITICAL();
            msg                     = (void *)0;      /* No message received                           */
            *err                    = OS_TIMEOUT;     /* Indicate a timeout occured                    */
        } else {
            msg = *pq->OSQOut++;                      /* Extract message from queue                    */
            pq->OSQEntries--;                         /* Update the number of entries in the queue     */
            if (pq->OSQOut == pq->OSQEnd) {           /* Wrap OUT pointer if we are at the end of Q    */
                pq->OSQOut = pq->OSQStart;
            }
            OS_EXIT_CRITICAL();
            *err = OS_NO_ERR;
        }
    }                                                 /* Return message received (or NULL)              */
    return (msg);
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                        POST MESSAGE TO A QUEUE
*********************************************************************************************************
*/

UBYTE OSQPost(OS_EVENT *pevent, void *msg)
{
    OS_Q   *pq;
    OS_TCB *ptcb;
    UBYTE   x;
    UBYTE   y;
    UBYTE   bitx;
    UBYTE   bity;
    UBYTE   p;


    OS_ENTER_CRITICAL();
    if (pevent->OSEventGrp) {                         /* See if any task pending on queue              */
        y    = OSUnMapTbl[pevent->OSEventGrp];        /* Find highest prio. task waiting for message   */
        bity = OSMapTbl[y];
        x    = OSUnMapTbl[pevent->OSEventTbl[y]];
        bitx = OSMapTbl[x];
        p    = (y << 3) + x;                          /* Find priority of task getting the msg         */
        if ((pevent->OSEventTbl[y] &= ~bitx) == 0) {  /* Remove this task from the waiting list        */
            pevent->OSEventGrp &= ~bity;
        }
        ptcb                 =  OSTCBPrioTbl[p];      /* Point to this task's OS_TCB                   */
        ptcb->OSTCBDly       =  0;                    /* Prevent OSTimeTick() from readying task       */
        ptcb->OSTCBEventPtr  = (OS_EVENT *)0;         /* Unlink ECB from this task                     */
        ptcb->OSTCBMsg       = msg;                   /* Send message directly to waiting task         */
        ptcb->OSTCBStat     &= ~OS_STAT_Q;            /* Clear bit associated with event type          */
        if (ptcb->OSTCBStat == OS_STAT_RDY) {         /* See if task is ready (could be susp'd)        */
            OSRdyGrp        |=  bity;                 /* Put task in the ready to run list             */
            OSRdyTbl[y]     |=  bitx;
        }
        OS_EXIT_CRITICAL();
        OSSched();                                    /* Find highest priority task ready to run       */
        return (OS_NO_ERR);
    } else {
        pq = pevent->OSEventPtr;                      /* Point to queue control block                  */
        if (pq->OSQEntries >= pq->OSQSize) {          /* Make sure queue is not full                   */
            OS_EXIT_CRITICAL();
            return (OS_Q_FULL);
        } else {
            *pq->OSQIn++ = msg;                       /* Insert message into queue                     */
            pq->OSQEntries++;                         /* Update the nbr of entries in the queue        */
            if (pq->OSQIn == pq->OSQEnd) {            /* Wrap IN ptr if we are at end of queue         */
                pq->OSQIn = pq->OSQStart;
            }
            OS_EXIT_CRITICAL();
        }
        return (OS_NO_ERR);
    }
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
*                                            DUMMY FUNCTION
*********************************************************************************************************
*/

static void  OSDummy(void)
{
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -