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

📄 os_flag.c

📁 UCOS-III
💻 C
📖 第 1 页 / 共 4 页
字号:

OS_FLAGS  OSFlagPend (OS_FLAG_GRP *p_grp,
                      OS_FLAGS     flags,
                      OS_TICK      timeout,
                      OS_OPT       opt,
                      CPU_TS      *p_ts,
                      OS_ERR      *p_err)
{
    CPU_BOOLEAN   consume;
    OS_FLAGS      flags_rdy;
    OS_OPT        mode;
    OS_PEND_DATA  pend_data;
    CPU_SR_ALLOC();



#ifdef OS_SAFETY_CRITICAL
    if (p_err == (OS_ERR *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return ((OS_FLAGS)0);
    }
#endif

#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
    if (OSIntNestingCtr > (OS_NESTING_CTR)0) {              /* See if called from ISR ...                             */
       *p_err = OS_ERR_PEND_ISR;                            /* ... can't PEND from an ISR                             */
        return ((OS_FLAGS)0);
    }
#endif

#if OS_CFG_ARG_CHK_EN > 0u
    if (p_grp == (OS_FLAG_GRP *)0) {                        /* Validate arguments                                     */
        *p_err = OS_ERR_OBJ_PTR_NULL;
        return ((OS_FLAGS)0);
    }
#endif

#if OS_CFG_OBJ_TYPE_CHK_EN > 0u
    if (p_grp->Type != OS_OBJ_TYPE_FLAG) {                  /* Validate that we are pointing at an event flag         */
        *p_err = OS_ERR_OBJ_TYPE;
        return ((OS_FLAGS)0);
    }
#endif

    if ((opt & OS_OPT_PEND_FLAG_CONSUME) != (OS_OPT)0) {    /* See if we need to consume the flags                    */
        consume = DEF_TRUE;
    } else {
        consume = DEF_FALSE;
    }

    if (p_ts != (CPU_TS *)0) {
        *p_ts = (CPU_TS)0;                                  /* Initialize the returned timestamp                      */
    }

    mode = opt & OS_OPT_PEND_FLAG_MASK;
    CPU_CRITICAL_ENTER();
    switch (mode) {
        case OS_OPT_PEND_FLAG_SET_ALL:                      /* See if all required flags are set                      */
             flags_rdy = (OS_FLAGS)(p_grp->Flags & flags);  /* Extract only the bits we want                          */
             if (flags_rdy == flags) {                      /* Must match ALL the bits that we want                   */
                 if (consume == DEF_TRUE) {                 /* See if we need to consume the flags                    */
                     p_grp->Flags &= ~flags_rdy;            /* Clear ONLY the flags that we wanted                    */
                 }
                 OSTCBCurPtr->FlagsRdy = flags_rdy;         /* Save flags that were ready                             */
                 if (p_ts != (CPU_TS *)0) {
                    *p_ts  = p_grp->TS;
                 }
                 CPU_CRITICAL_EXIT();                       /* Yes, condition met, return to caller                   */
                 *p_err = OS_ERR_NONE;
                 return (flags_rdy);
             } else {                                       /* Block task until events occur or timeout               */
                 if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) {
                     CPU_CRITICAL_EXIT();
                     *p_err = OS_ERR_PEND_WOULD_BLOCK;      /* Specified non-blocking so task would block             */
                     return ((OS_FLAGS)0);
                 } else {                                   /* Specified blocking so check is scheduler is locked     */
                     if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* See if called with scheduler locked ...      */
                         CPU_CRITICAL_EXIT();
                         *p_err = OS_ERR_SCHED_LOCKED;                /* ... can't PEND when locked                   */
                         return ((OS_FLAGS)0);
                     }
                 }

                 OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT();     /* Lock the scheduler/re-enable interrupts                */
                 OS_FlagBlock(&pend_data,
                              p_grp,
                              flags,
                              opt,
                              timeout);
                 OS_CRITICAL_EXIT_NO_SCHED();
             }
             break;

        case OS_OPT_PEND_FLAG_SET_ANY:
             flags_rdy = (OS_FLAGS)(p_grp->Flags & flags);  /* Extract only the bits we want                          */
             if (flags_rdy != (OS_FLAGS)0) {                /* See if any flag set                                    */
                 if (consume == DEF_TRUE) {                 /* See if we need to consume the flags                    */
                     p_grp->Flags &= ~flags_rdy;            /* Clear ONLY the flags that we got                       */
                 }
                 OSTCBCurPtr->FlagsRdy = flags_rdy;         /* Save flags that were ready                             */
                 if (p_ts != (CPU_TS *)0) {
                    *p_ts  = p_grp->TS;
                 }
                 CPU_CRITICAL_EXIT();                       /* Yes, condition met, return to caller                   */
                 *p_err = OS_ERR_NONE;
                 return (flags_rdy);
             } else {                                       /* Block task until events occur or timeout               */
                 if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) {
                     CPU_CRITICAL_EXIT();
                     *p_err = OS_ERR_PEND_WOULD_BLOCK;      /* Specified non-blocking so task would block             */
                     return ((OS_FLAGS)0);
                 } else {                                   /* Specified blocking so check is scheduler is locked     */
                     if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* See if called with scheduler locked ...      */
                         CPU_CRITICAL_EXIT();
                         *p_err = OS_ERR_SCHED_LOCKED;                /* ... can't PEND when locked                   */
                         return ((OS_FLAGS)0);
                     }
                 }

                 OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT();     /* Lock the scheduler/re-enable interrupts                */
                 OS_FlagBlock(&pend_data,
                              p_grp,
                              flags,
                              opt,
                              timeout);
                 OS_CRITICAL_EXIT_NO_SCHED();
             }
             break;

#if OS_CFG_FLAG_MODE_CLR_EN > 0u
        case OS_OPT_PEND_FLAG_CLR_ALL:                      /* See if all required flags are cleared                  */
             flags_rdy = (OS_FLAGS)(~p_grp->Flags & flags); /* Extract only the bits we want                          */
             if (flags_rdy == flags) {                      /* Must match ALL the bits that we want                   */
                 if (consume == DEF_TRUE) {                 /* See if we need to consume the flags                    */
                     p_grp->Flags |= flags_rdy;             /* Set ONLY the flags that we wanted                      */
                 }
                 OSTCBCurPtr->FlagsRdy = flags_rdy;         /* Save flags that were ready                             */
                 if (p_ts != (CPU_TS *)0) {
                    *p_ts  = p_grp->TS;
                 }
                 CPU_CRITICAL_EXIT();                       /* Yes, condition met, return to caller                   */
                 *p_err = OS_ERR_NONE;
                 return (flags_rdy);
             } else {                                       /* Block task until events occur or timeout               */
                 if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) {
                     CPU_CRITICAL_EXIT();
                     *p_err = OS_ERR_PEND_WOULD_BLOCK;      /* Specified non-blocking so task would block             */
                     return ((OS_FLAGS)0);
                 } else {                                   /* Specified blocking so check is scheduler is locked     */
                     if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* See if called with scheduler locked ...      */
                         CPU_CRITICAL_EXIT();
                         *p_err = OS_ERR_SCHED_LOCKED;                /* ... can't PEND when locked                   */
                         return ((OS_FLAGS)0);
                     }
                 }

                 OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT();     /* Lock the scheduler/re-enable interrupts                */
                 OS_FlagBlock(&pend_data,
                              p_grp,
                              flags,
                              opt,
                              timeout);
                 OS_CRITICAL_EXIT_NO_SCHED();
             }
             break;

        case OS_OPT_PEND_FLAG_CLR_ANY:
             flags_rdy = (OS_FLAGS)(~p_grp->Flags & flags); /* Extract only the bits we want                          */
             if (flags_rdy != (OS_FLAGS)0) {                /* See if any flag cleared                                */
                 if (consume == DEF_TRUE) {                 /* See if we need to consume the flags                    */
                     p_grp->Flags |= flags_rdy;             /* Set ONLY the flags that we got                         */
                 }
                 OSTCBCurPtr->FlagsRdy = flags_rdy;         /* Save flags that were ready                             */
                 if (p_ts != (CPU_TS *)0) {
                    *p_ts  = p_grp->TS;
                 }
                 CPU_CRITICAL_EXIT();                       /* Yes, condition met, return to caller                   */
                 *p_err    = OS_ERR_NONE;
                 return (flags_rdy);
             } else {                                       /* Block task until events occur or timeout               */
                 if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) {
                     CPU_CRITICAL_EXIT();
                     *p_err = OS_ERR_PEND_WOULD_BLOCK;      /* Specified non-blocking so task would block             */
                     return ((OS_FLAGS)0);
                 } else {                                   /* Specified blocking so check is scheduler is locked     */
                     if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* See if called with scheduler locked ...      */
                         CPU_CRITICAL_EXIT();
                         *p_err = OS_ERR_SCHED_LOCKED;                /* ... can't PEND when locked                   */
                         return ((OS_FLAGS)0);
                     }
                 }

                 OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT();     /* Lock the scheduler/re-enable interrupts                */
                 OS_FlagBlock(&pend_data,
                              p_grp,
                              flags,
                              opt,
                              timeout);
                 OS_CRITICAL_EXIT_NO_SCHED();
             }
             break;
#endif

        default:
             CPU_CRITICAL_EXIT();
             *p_err = OS_ERR_OPT_INVALID;
             return ((OS_FLAGS)0);
    }

    OSSched();                                              /* Find next HPT ready to run                             */

    CPU_CRITICAL_ENTER();
    switch (OSTCBCurPtr->PendStatus) {
        case OS_STATUS_PEND_OK:                             /* We got the vent flags                                  */
             if (p_ts != (CPU_TS *)0) {
                *p_ts  = OSTCBCurPtr->TS;
             }
             *p_err = OS_ERR_NONE;
             break;

        case OS_STATUS_PEND_ABORT:                          /* Indicate that we aborted                               */
             if (p_ts != (CPU_TS *)0) {
                *p_ts  = OSTCBCurPtr->TS;
             }
             CPU_CRITICAL_EXIT();
             *p_err = OS_ERR_PEND_ABORT;
             return ((OS_FLAGS)0);

        case OS_STATUS_PEND_TIMEOUT:                        /* Indicate that we didn't get semaphore within timeout   */
             if (p_ts != (CPU_TS *)0) {
                *p_ts  = (CPU_TS  )0;
             }
             CPU_CRITICAL_EXIT();
             *p_err = OS_ERR_TIMEOUT;
             return ((OS_FLAGS)0);

        case OS_STATUS_PEND_DEL:                            /* Indicate that object pended on has been deleted        */
             if (p_ts != (CPU_TS *)0) {
                *p_ts  = OSTCBCurPtr->TS;
             }
             CPU_CRITICAL_EXIT();
             *p_err = OS_ERR_OBJ_DEL;
             return ((OS_FLAGS)0);

        default:
             CPU_CRITICAL_EXIT();
             *p_err = OS_ERR_STATUS_INVALID;
             return ((OS_FLAGS)0);
    }

    flags_rdy = OSTCBCurPtr->FlagsRdy;
    if (consume == DEF_TRUE) {                              /* See if we need to consume the flags                    */
        switch (mode) {
            case OS_OPT_PEND_FLAG_SET_ALL:
            case OS_OPT_PEND_FLAG_SET_ANY:                  /* Clear ONLY the flags we got                            */
                 p_grp->Flags &= ~flags_rdy;
                 break;

#if OS_CFG_FLAG_MODE_CLR_EN > 0u
            case OS_OPT_PEND_FLAG_CLR_ALL:
            case OS_OPT_PEND_FLAG_CLR_ANY:                  /* Set   ONLY the flags we got                            */
                 p_grp->Flags |=  flags_rdy;
                 break;
#endif
            default:
                 CPU_CRITICAL_EXIT();
                 *p_err = OS_ERR_OPT_INVALID;
                 return ((OS_FLAGS)0);
        }
    }
    CPU_CRITICAL_EXIT();
    *p_err = OS_ERR_NONE;                                   /* Event(s) must have occurred                            */
    return (flags_rdy);
}
/*$PAGE*/
/*
************************************************************************************************************************
*                                          ABORT WAITING ON AN EVENT FLAG GROUP
*
* Description: This function aborts & readies any tasks currently waiting on an event flag group.  This function should
*              be used to fault-abort the wait on the event flag group, rather than to normally post to the event flag
*              group OSFlagPost().
*
* Arguments  : p_grp     is a pointer to the event flag group
*
*              opt       determines the type of ABORT performed:
*
*                            OS_OPT_PEND_ABORT_1          ABORT wait for a single task (HPT) waiting on the event flag
*                            OS_OPT_PEND_ABORT_ALL        ABORT wait for ALL tasks that are  waiting on the event flag
*                            OS_OPT_POST_NO_SCHED         Do not call the scheduler
*
*              p_err     is a pointer to a variable that will contain an error code returned by this function.
*
*                            OS_ERR_NONE                  At least one task waiting on the event flag group and was
*                                                         readied and informed of the aborted wait; check return value
*                                                         for the number of tasks whose wait on the event flag group
*                                                         was aborted.
*                            OS_ERR_OBJ_PTR_NULL          If 'p_grp' is a NULL pointer.
*                            OS_ERR_OBJ_TYPE              If 'p_grp' is not pointing at an event flag group
*                            OS_ERR_OPT_INVALID           If you specified an invalid option
*                            OS_ERR_PEND_ABORT_ISR        If you called this function from an ISR
*                            OS_ERR_PEND_ABORT_NONE       No task were pending
*
* Returns    : == 0          if no tasks were waiting on the event flag group, or upon error.
*              >  0          if one or more tasks waiting on the event flag group are now readied and informed.
************************************************************************************************************************
*/

#if OS_CFG_FLAG_PEND_ABORT_EN > 0u
OS_OBJ_QTY  OSFlagPendAbort (OS_FLAG_GRP  *p_grp,
                             OS_OPT        opt,

⌨️ 快捷键说明

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