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

📄 landzo

📁 【开源】线性CCD自适应性算法攻略
💻
📖 第 1 页 / 共 5 页
字号:
/*$PAGE*/
#if ((OS_EVENT_EN) && (OS_EVENT_MULTI_EN > 0u))
INT16U  OSEventPendMulti (OS_EVENT  **pevents_pend,
                          OS_EVENT  **pevents_rdy,
                          void      **pmsgs_rdy,
                          INT32U      timeout,
                          INT8U      *perr)
{
    OS_EVENT  **pevents;
    OS_EVENT   *pevent;
#if ((OS_Q_EN > 0u) && (OS_MAX_QS > 0u))
    OS_Q       *pq;
#endif
    BOOLEAN     events_rdy;
    INT16U      events_rdy_nbr;
    INT8U       events_stat;
#if (OS_CRITICAL_METHOD == 3u)                          /* Allocate storage for CPU status register    */
    OS_CPU_SR   cpu_sr = 0u;
#endif



#ifdef OS_SAFETY_CRITICAL
    if (perr == (INT8U *)0)
    {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return (0u);
    }
#endif

#if (OS_ARG_CHK_EN > 0u)
    if (pevents_pend == (OS_EVENT **)0)                 /* Validate 'pevents_pend'                     */
    {
        *perr =  OS_ERR_PEVENT_NULL;
        return (0u);
    }
    if (*pevents_pend  == (OS_EVENT *)0)                /* Validate 'pevents_pend'                     */
    {
        *perr =  OS_ERR_PEVENT_NULL;
        return (0u);
    }
    if (pevents_rdy  == (OS_EVENT **)0)                 /* Validate 'pevents_rdy'                      */
    {
        *perr =  OS_ERR_PEVENT_NULL;
        return (0u);
    }
    if (pmsgs_rdy == (void **)0)                        /* Validate 'pmsgs_rdy'                        */
    {
        *perr =  OS_ERR_PEVENT_NULL;
        return (0u);
    }
#endif

    *pevents_rdy = (OS_EVENT *)0;                        /* Init array to NULL in case of errors        */

    pevents     =  pevents_pend;
    pevent      = *pevents;
    while  (pevent != (OS_EVENT *)0)
    {
        switch (pevent->OSEventType)                    /* Validate event block types                  */
        {
#if (OS_SEM_EN  > 0u)
        case OS_EVENT_TYPE_SEM:
            break;
#endif
#if (OS_MBOX_EN > 0u)
        case OS_EVENT_TYPE_MBOX:
            break;
#endif
#if ((OS_Q_EN   > 0u) && (OS_MAX_QS > 0u))
        case OS_EVENT_TYPE_Q:
            break;
#endif

        case OS_EVENT_TYPE_MUTEX:
        case OS_EVENT_TYPE_FLAG:
        default:
            *perr = OS_ERR_EVENT_TYPE;
            return (0u);
        }
        pevents++;
        pevent = *pevents;
    }

    if (OSIntNesting  > 0u)                             /* See if called from ISR ...                  */
    {
        *perr =  OS_ERR_PEND_ISR;                        /* ... can't PEND from an ISR                  */
        return (0u);
    }
    if (OSLockNesting > 0u)                             /* See if called with scheduler locked ...     */
    {
        *perr =  OS_ERR_PEND_LOCKED;                     /* ... can't PEND when locked                  */
        return (0u);
    }

    /*$PAGE*/
    events_rdy     =  OS_FALSE;
    events_rdy_nbr =  0u;
    events_stat    =  OS_STAT_RDY;
    pevents        =  pevents_pend;
    pevent         = *pevents;
    OS_ENTER_CRITICAL();
    while (pevent != (OS_EVENT *)0)                     /* See if any events already available         */
    {
        switch (pevent->OSEventType)
        {
#if (OS_SEM_EN > 0u)
        case OS_EVENT_TYPE_SEM:
            if (pevent->OSEventCnt > 0u)           /* If semaphore count > 0, resource available; */
            {
                pevent->OSEventCnt--;              /* ... decrement semaphore,                ... */
                *pevents_rdy++ =  pevent;           /* ... and return available semaphore event    */
                events_rdy   =  OS_TRUE;
                *pmsgs_rdy++   = (void *)0;         /* NO message returned  for semaphores         */
                events_rdy_nbr++;

            }
            else
            {
                events_stat |=  OS_STAT_SEM;      /* Configure multi-pend for semaphore events   */
            }
            break;
#endif

#if (OS_MBOX_EN > 0u)
        case OS_EVENT_TYPE_MBOX:
            if (pevent->OSEventPtr != (void *)0)   /* If mailbox NOT empty;                   ... */
            {
                /* ... return available message,           ... */
                *pmsgs_rdy++         = (void *)pevent->OSEventPtr;
                pevent->OSEventPtr  = (void *)0;
                *pevents_rdy++       =  pevent;     /* ... and return available mailbox event      */
                events_rdy         =  OS_TRUE;
                events_rdy_nbr++;

            }
            else
            {
                events_stat |= OS_STAT_MBOX;      /* Configure multi-pend for mailbox events     */
            }
            break;
#endif

#if ((OS_Q_EN > 0u) && (OS_MAX_QS > 0u))
        case OS_EVENT_TYPE_Q:
            pq = (OS_Q *)pevent->OSEventPtr;
            if (pq->OSQEntries > 0u)               /* If queue NOT empty;                     ... */
            {
                /* ... return available message,           ... */
                *pmsgs_rdy++ = (void *) * pq->OSQOut++;
                if (pq->OSQOut == pq->OSQEnd)      /* If OUT ptr at queue end, ...                */
                {
                    pq->OSQOut  = pq->OSQStart;    /* ... wrap   to queue start                   */
                }
                pq->OSQEntries--;                  /* Update number of queue entries              */
                *pevents_rdy++ = pevent;            /* ... and return available queue event        */
                events_rdy   = OS_TRUE;
                events_rdy_nbr++;

            }
            else
            {
                events_stat |= OS_STAT_Q;         /* Configure multi-pend for queue events       */
            }
            break;
#endif

        case OS_EVENT_TYPE_MUTEX:
        case OS_EVENT_TYPE_FLAG:
        default:
            OS_EXIT_CRITICAL();
            *pevents_rdy = (OS_EVENT *)0;           /* NULL terminate return event array           */
            *perr        =  OS_ERR_EVENT_TYPE;
            return (events_rdy_nbr);
        }
        pevents++;
        pevent = *pevents;
    }

    if ( events_rdy == OS_TRUE)                         /* Return any events already available         */
    {
        *pevents_rdy = (OS_EVENT *)0;                    /* NULL terminate return event array           */
        OS_EXIT_CRITICAL();
        *perr        =  OS_ERR_NONE;
        return (events_rdy_nbr);
    }
    /*$PAGE*/
    /* Otherwise, must wait until any event occurs */
    OSTCBCur->OSTCBStat     |= events_stat  |           /* Resource not available, ...                 */
                               OS_STAT_MULTI;           /* ... pend on multiple events                 */
    OSTCBCur->OSTCBStatPend  = OS_STAT_PEND_OK;
    OSTCBCur->OSTCBDly       = timeout;                 /* Store pend timeout in TCB                   */
    OS_EventTaskWaitMulti(pevents_pend);                /* Suspend task until events or timeout occurs */

    OS_EXIT_CRITICAL();
    OS_Sched();                                         /* Find next highest priority task ready       */
    OS_ENTER_CRITICAL();

    switch (OSTCBCur->OSTCBStatPend)                    /* Handle event posted, aborted, or timed-out  */
    {
    case OS_STAT_PEND_OK:
    case OS_STAT_PEND_ABORT:
        pevent = OSTCBCur->OSTCBEventPtr;
        if (pevent != (OS_EVENT *)0)               /* If task event ptr != NULL, ...              */
        {
            *pevents_rdy++   =  pevent;             /* ... return available event ...              */
            *pevents_rdy     = (OS_EVENT *)0;       /* ... & NULL terminate return event array     */
            events_rdy_nbr =  1;

        }
        else                                       /* Else NO event available, handle as timeout  */
        {
            OSTCBCur->OSTCBStatPend = OS_STAT_PEND_TO;
            OS_EventTaskRemoveMulti(OSTCBCur, pevents_pend);
        }
        break;

    case OS_STAT_PEND_TO:                           /* If events timed out, ...                    */
    default:                                        /* ... remove task from events' wait lists     */
        OS_EventTaskRemoveMulti(OSTCBCur, pevents_pend);
        break;
    }

    switch (OSTCBCur->OSTCBStatPend)
    {
    case OS_STAT_PEND_OK:
        switch (pevent->OSEventType)               /* Return event's message                      */
        {
#if (OS_SEM_EN > 0u)
        case OS_EVENT_TYPE_SEM:
            *pmsgs_rdy++ = (void *)0;          /* NO message returned for semaphores          */
            break;
#endif

#if ((OS_MBOX_EN > 0u) ||                 \
    ((OS_Q_EN    > 0u) && (OS_MAX_QS > 0u)))
        case OS_EVENT_TYPE_MBOX:
        case OS_EVENT_TYPE_Q:
            *pmsgs_rdy++ = (void *)OSTCBCur->OSTCBMsg;     /* Return received message         */
            break;
#endif

        case OS_EVENT_TYPE_MUTEX:
        case OS_EVENT_TYPE_FLAG:
        default:
            OS_EXIT_CRITICAL();
            *pevents_rdy = (OS_EVENT *)0;      /* NULL terminate return event array           */
            *perr        =  OS_ERR_EVENT_TYPE;
            return (events_rdy_nbr);
        }
        *perr = OS_ERR_NONE;
        break;

    case OS_STAT_PEND_ABORT:
        *pmsgs_rdy++ = (void *)0;                   /* NO message returned for abort               */
        *perr        =  OS_ERR_PEND_ABORT;          /* Indicate that event  aborted                */
        break;

    case OS_STAT_PEND_TO:
    default:
        *pmsgs_rdy++ = (void *)0;                   /* NO message returned for timeout             */
        *perr        =  OS_ERR_TIMEOUT;             /* Indicate that events timed out              */
        break;
    }

    OSTCBCur->OSTCBStat          =  OS_STAT_RDY;        /* Set   task  status to ready                 */
    OSTCBCur->OSTCBStatPend      =  OS_STAT_PEND_OK;    /* Clear pend  status                          */
    OSTCBCur->OSTCBEventPtr      = (OS_EVENT *)0;       /* Clear event pointers                        */
    OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0;
#if ((OS_MBOX_EN > 0u) ||                 \
    ((OS_Q_EN    > 0u) && (OS_MAX_QS > 0u)))
    OSTCBCur->OSTCBMsg           = (void *)0;           /* Clear task  message                         */
#endif
    OS_EXIT_CRITICAL();

    return (events_rdy_nbr);
}
#endif

/*$PAGE*/
/*
*********************************************************************************************************
*                                             INITIALIZATION
*
* Description: This function is used to initialize the internals of uC/OS-II and MUST be called prior to
*              creating any uC/OS-II object and, prior to calling OSStart().
*
* Arguments  : none
*
* Returns    : none
*********************************************************************************************************
*/

void  OSInit (void)
{
#if OS_TIME_TICK_HOOK_EN > 0u
    OSInitHookBegin();                                           /* Call port specific initialization code   */
#endif

    OS_InitMisc();                                               /* Initialize miscellaneous variables       */

    OS_InitRdyList();                                            /* Initialize the Ready List                */

    OS_InitTCBList();                                            /* Initialize the free list of OS_TCBs      */

    OS_InitEventList();                                          /* Initialize the free list of OS_EVENTs    */

#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u)
    OS_FlagInit();                                               /* Initialize the event flag structures     */
#endif

#if (OS_MEM_EN > 0u) && (OS_MAX_MEM_PART > 0u)
    OS_MemInit();                                                /* Initialize the memory manager            */
#endif

#if (OS_Q_EN > 0u) && (OS_MAX_QS > 0u)
    OS_QInit();                                                  /* Initialize the message queue structures  */
#endif

    OS_InitTaskIdle();                                           /* Create the Idle Task                     */

⌨️ 快捷键说明

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