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

📄 os_flag.c

📁 ucos_ii在S3C2410上的移植
💻 C
📖 第 1 页 / 共 3 页
字号:
        switch (pnode->OSFlagNodeWaitType)    /* 看当前节点是否设置了所有需要的位? */
        {
            case OS_FLAG_WAIT_SET_ALL:               
                 flags_rdy = pgrp->OSFlagFlags & pnode->OSFlagNodeFlags;
                 if (flags_rdy == pnode->OSFlagNodeFlags) 
                 {
                     if (OS_FlagTaskRdy(pnode, flags_rdy) == TRUE) 
                     {                                              /* Make task RTR, event(s) Rx'd   */
                         sched = TRUE;                               /* When done we will reschedule   */
                     }
                 }
                 break;

            case OS_FLAG_WAIT_SET_ANY:                          /* See if any flag set    */
                 flags_rdy = pgrp->OSFlagFlags & pnode->OSFlagNodeFlags;
                 if (flags_rdy != (OS_FLAGS)0)
                  {
                     if (OS_FlagTaskRdy(pnode, flags_rdy) == TRUE) 
                     {                                                 /* Make task RTR, event(s) Rx'd   */
                         sched = TRUE;                               /* When done we will reschedule   */
                     }
                 }
                 break;

#if OS_FLAG_WAIT_CLR_EN > 0
            case OS_FLAG_WAIT_CLR_ALL:               /* See if all req. flags are set for current node */
                 flags_rdy = ~pgrp->OSFlagFlags & pnode->OSFlagNodeFlags;
                 if (flags_rdy == pnode->OSFlagNodeFlags) 
                 {
                     if (OS_FlagTaskRdy(pnode, flags_rdy) == TRUE) 
                     {                                               /* Make task RTR, event(s) Rx'd   */
                         sched = TRUE;                               /* When done we will reschedule   */
                     }
                 }
                 break;

            case OS_FLAG_WAIT_CLR_ANY:                                        /* See if any flag set    */
                 flags_rdy = ~pgrp->OSFlagFlags & pnode->OSFlagNodeFlags;
                 if (flags_rdy != (OS_FLAGS)0) 
                 {
                     if (OS_FlagTaskRdy(pnode, flags_rdy) == TRUE) 
                     {                                               /* Make task RTR, event(s) Rx'd   */
                         sched = TRUE;                               /* When done we will reschedule   */
                     }
                 }
                 break;
#endif
        }
        pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext; /* 指向下一个等待事件标志的任务节点 */
    }
    OS_EXIT_CRITICAL();
    if (sched == TRUE) 
    {
        OS_Sched();
    }
    OS_ENTER_CRITICAL();
    flags_cur = pgrp->OSFlagFlags;
    OS_EXIT_CRITICAL();
    *err      = OS_NO_ERR;
    return (flags_cur);
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                           查询事件标志组的状态
*
* 函数描述: 该函数用于查询事件标志组的状态
*
* 输入参数  : pgrp         指向期望的事件标志组的指针
*
*              err           指向出错代码:
*                            OS_NO_ERR              调用成功
*                            OS_FLAG_INVALID_PGRP   传递的是空指针
*                            OS_ERR_EVENT_TYPE      指向的类型不是事件标志组
*
* 返回值    : 当前的事件标志组值
*
* 从任务或ISR中调用
*********************************************************************************************************
*/

#if OS_FLAG_QUERY_EN > 0
OS_FLAGS  OSFlagQuery (OS_FLAG_GRP *pgrp, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3                       /* 为CPU状态寄存器分配存储变量            */
    OS_CPU_SR  cpu_sr;
#endif
    OS_FLAGS   flags;


#if OS_ARG_CHK_EN > 0
    if (pgrp == (OS_FLAG_GRP *)0) 
    {                                                   /* 无效的 'pgrp'                 */
        *err = OS_FLAG_INVALID_PGRP;
        return ((OS_FLAGS)0);
    }
    if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) 
    {                                                 /* 无效的事件标志类型   */
        *err = OS_ERR_EVENT_TYPE;
        return ((OS_FLAGS)0);
    }
#endif
    OS_ENTER_CRITICAL();
    flags = pgrp->OSFlagFlags;
    OS_EXIT_CRITICAL();
    *err = OS_NO_ERR;
    return (flags);                               /* 返回当前的事件标志值      */
}
#endif

/*$PAGE*/
/*
*********************************************************************************************************
*                              挂起任务一直到接收到事件标志或延时发生为止
*
* 函数描述: 该函数是 uC/OS-II的内部函数,它用于把一个任务置为睡眠态,直到期望的事件标志位置位为止。
*
* 输入函数  : pgrp           指向期望的事件标志组的指针
*
*             pnode          指向一个包含任务等待事件标志位置位的数据的结构指针。
*
*             flags          显示那一个位期望要检测的位参数。
*                            在'flags'中通过设定对应位来指定期望的位。例如,应用程序
*                            期望等待位0和位1,那么,'flags'将包含0X03。
*
*             wait_type      指定是否所有位或是任一位去置位或清除。
*                            指定下列参数:
*                            
*                            OS_FLAG_WAIT_CLR_ALL   检测'mask'中所有位清零 (0)
*                            OS_FLAG_WAIT_SET_ALL   检测'mask'中所有位设置 (1)
*                            OS_FLAG_WAIT_CLR_ANY   检测'mask'中任一位清零 (0)
*                            OS_FLAG_WAIT_SET_ANY   检测'mask'中任一位设置 (1)
*
*
*             timeout        任务等待事件标志位置位的延时时间。
*
* 返回值    : 无
*
* 调用函数  : OSFlagPend()  OS_FLAG.C
*
* 注释    : 该函数为内部函数,应用程序不该调用
*********************************************************************************************************
*/

static  void  OS_FlagBlock (OS_FLAG_GRP *pgrp, OS_FLAG_NODE *pnode, OS_FLAGS flags, INT8U wait_type, INT16U timeout)
{
    OS_FLAG_NODE  *pnode_next;


    OSTCBCur->OSTCBStat      |= OS_STAT_FLAG;
    OSTCBCur->OSTCBDly        = timeout;              /* 存储任务 TCB 的延时数                  */
#if OS_TASK_DEL_EN > 0
    OSTCBCur->OSTCBFlagNode   = pnode;                /* 把节点链到TCB上                           */
#endif
    pnode->OSFlagNodeFlags    = flags;                /* 保存需要等待的标志                      */
    pnode->OSFlagNodeWaitType = wait_type;            /* 保存等待的类型                          */
    pnode->OSFlagNodeTCB      = (void *)OSTCBCur;     /* 任务的 TCB 链接到节点上                 */
    pnode->OSFlagNodeNext     = pgrp->OSFlagWaitList; /* 在事件标志等待列表的开头添加节点         */
    pnode->OSFlagNodePrev     = (void *)0;
    pnode->OSFlagNodeFlagGrp  = (void *)pgrp;         /* 链接事件标志组                     */
    pnode_next                = (OS_FLAG_NODE *)pgrp->OSFlagWaitList;
    if (pnode_next != (void *)0)
     {                                                /* 这是要插入的第一个节点吗?             */
        pnode_next->OSFlagNodePrev = pnode;           /* 不, 链接双链表                */
    }
    pgrp->OSFlagWaitList = (void *)pnode;
                                                      /* 挂起当前任务直到事件标志到   */
    if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) 
    {
        OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
    }
}

/*$PAGE*/
/*
*********************************************************************************************************
*                                    初始化事件标志组
*
* 函数描述: 该函数由uC/OS-II 调用初始化事件标志模块。换句话说,该函数是 uC/OS-II的内部函数。
*
* 输入参数  : 无
*
* 返回值    : 无
*
* 警告      : 在应用程序中,不必调用该函数。这是 uC/OS-II的内部函数。
*********************************************************************************************************
*/

void  OS_FlagInit (void)
{
#if OS_MAX_FLAGS == 1
    OSFlagFreeList                 = (OS_FLAG_GRP *)&OSFlagTbl[0];  /* 只有一个事件标志组!    */
    OSFlagFreeList->OSFlagType     = OS_EVENT_TYPE_UNUSED;
    OSFlagFreeList->OSFlagWaitList = (void *)0;
#endif

#if OS_MAX_FLAGS >= 2
    INT8U        i;
    OS_FLAG_GRP *pgrp1;
    OS_FLAG_GRP *pgrp2;


    pgrp1 = &OSFlagTbl[0];
    pgrp2 = &OSFlagTbl[1];
    for (i = 0; i < (OS_MAX_FLAGS - 1); i++) 
    {                                                                  /* 初始化空余事件标志  */
        pgrp1->OSFlagType     = OS_EVENT_TYPE_UNUSED;
        pgrp1->OSFlagWaitList = (void *)pgrp2;
        pgrp1++;
        pgrp2++;
    }
    pgrp1->OSFlagWaitList = (void *)0;
    OSFlagFreeList        = (OS_FLAG_GRP *)&OSFlagTbl[0];
#endif
}

/*$PAGE*/
/*
*********************************************************************************************************
*                              使等待事件标志的任务进入就绪态
*
* 函数描述: 该函数是 uC/OS-II 的内部函数,并且因为期望的事件标志已置位,所以任务就绪待运行。
*
* 输入参数  : pnode         指向包含等待事件标志位置位的任务的数据的指针。
*
*             flags_rdy     包含引起任务就绪的位模式。
*
* 返回值    : none
*
* 由函数 OSFlagsPost() OS_FLAG.C调用
*
* 注释    : 1) 该函数任务中断已关闭
*           2) 该函数是 uC/OS-II的内部函数,应用程序不必调用。
*********************************************************************************************************
*/

static  BOOLEAN  OS_FlagTaskRdy (OS_FLAG_NODE *pnode, OS_FLAGS flags_rdy)
{
    OS_TCB   *ptcb;
    BOOLEAN   sched;


    ptcb                = (OS_TCB *)pnode->OSFlagNodeTCB;           /* 指向等待任务的TCB            */
    ptcb->OSTCBDly      = 0;
    ptcb->OSTCBFlagsRdy = flags_rdy;
    ptcb->OSTCBStat    &= ~OS_STAT_FLAG;
    if (ptcb->OSTCBStat == OS_STAT_RDY) 
    {                                                                /* 把任务放到就绪列表中         */
        OSRdyGrp               |= ptcb->OSTCBBitY;
        OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
        sched                   = TRUE;
    } 
    else 
    {
        sched                   = FALSE;
    }
    OS_FlagUnlink(pnode);
    return (sched);
}

/*$PAGE*/
/*
*********************************************************************************************************
*                                  从等待列表中拆除事件标志节点
*
* 函数描述  : 该函数是 uC/OS-II 的内部函数,用于从等待事件标志任务列表中拆除事件标志节点。
*
* 输入参数  : pnode         指向包含等待事件标志位置位的任务的数据的指针。
*
* 返回值    : none
*
* 由         : OS_FlagTaskRdy() OS_FLAG.C
*              OSFlagPend()     OS_FLAG.C
*              OSTaskDel()      OS_TASK.C  调用
*
* 注释       : 1) 该函数任务中断已关闭
*              2) 该函数是 uC/OS-II的内部函数,应用程序不必调用
*********************************************************************************************************
*/

void  OS_FlagUnlink (OS_FLAG_NODE *pnode)
{
#if OS_TASK_DEL_EN > 0
    OS_TCB       *ptcb;
#endif
    OS_FLAG_GRP  *pgrp;
    OS_FLAG_NODE *pnode_prev;
    OS_FLAG_NODE *pnode_next;


    pnode_prev = (OS_FLAG_NODE *)pnode->OSFlagNodePrev;
    pnode_next = (OS_FLAG_NODE *)pnode->OSFlagNodeNext;
    if (pnode_prev == (OS_FLAG_NODE *)0)                      /* 该节点是等待列表中的第一个节点吗?    */
    {                                                                                             /*是 */
        pgrp                 = (OS_FLAG_GRP *)pnode->OSFlagNodeFlagGrp;
        pgrp->OSFlagWaitList = (void *)pnode_next;                      /*      为新的第一个节点更新   */
        if (pnode_next != (OS_FLAG_NODE *)0) 
        {
            pnode_next->OSFlagNodePrev = (OS_FLAG_NODE *)0;      /*     链接新的第一个节点的前指针为空 */
        }
    } 
    else 
    {                                                                       /* 不是,在列表中其他位置   */
        pnode_prev->OSFlagNodeNext = pnode_next;                                   /*     搭接其他节点 */
        if (pnode_next != (OS_FLAG_NODE *)0) 
        {                                                              /*      是最后的节点吗?        */
            pnode_next->OSFlagNodePrev = pnode_prev;                       /*      不是,搭接其他节点   */
        }
    }
#if OS_TASK_DEL_EN > 0
    ptcb                = (OS_TCB *)pnode->OSFlagNodeTCB;
    ptcb->OSTCBFlagNode = (OS_FLAG_NODE *)0;
#endif
}
#endif

⌨️ 快捷键说明

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