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

📄 os_flag.c

📁 avr ucos 代码 测试环境:source insight WINAVR 4个进程
💻 C
📖 第 1 页 / 共 5 页
字号:
                                                置位或清0事件标志组中的事件标志
描述:此函数设置或清除事件标志组中的一些位,通过设置掩码来完成。
参数:pgrp:目标事件标志组指针
                flags:如果opt是OS_FLAG_SET,flags中的每一位将设置事件标志组中的对应位。
                如:要设置0、4、5位,那么flags为0x31。如果'opt' (see below) 是 OS_FLAG_CLR,那么
                flags中的每一位置位将清除事件标志组中的对应位。
                如:清除0、4、5位,那么flags为0x31。
*              opt          显示flags是否为:
*                                set     (OS_FLAG_SET) 或者
*                                cleared (OS_FLAG_CLR)
*
*              err           is a pointer to an error code and can be:
*                            OS_NO_ERR              成功
*                            OS_FLAG_INVALID_PGRP   你传递了空指针
*                            OS_ERR_EVENT_TYPE     没有指向事件标志组
*                            OS_FLAG_INVALID_OPT    有错误选项
*********************************************************************************************************
*/
OS_FLAGS  OSFlagPost (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U opt, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3                          /* Allocate storage for CPU status register       */
    OS_CPU_SR     cpu_sr;
#endif
    OS_FLAG_NODE *pnode;
    BOOLEAN       sched;
    OS_FLAGS      flags_cur;
    OS_FLAGS      flags_rdy;


#if OS_ARG_CHK_EN > 0
    if (pgrp == (OS_FLAG_GRP *)0) {                  /* Validate 'pgrp'                                */
        *err = OS_FLAG_INVALID_PGRP;
        return ((OS_FLAGS)0);//pgrp是否合理
    }
    if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) {    /* Make sure we are pointing to an event flag grp */
        *err = OS_ERR_EVENT_TYPE;
        return ((OS_FLAGS)0);//保证是指向事件标志组
    }
#endif
/*$PAGE*/
    OS_ENTER_CRITICAL();
    switch (opt) {
        case OS_FLAG_CLR://如果是负反馈,设置相反项
             pgrp->OSFlagFlags &= ~flags;            /* Clear the flags specified in the group         */
             break;

        case OS_FLAG_SET://如果是正反馈,设置相同项
             pgrp->OSFlagFlags |=  flags;            /* Set   the flags specified in the group         */
             break;

        default://有异常现象
             OS_EXIT_CRITICAL();                     /* INVALID option                                 */
             *err = OS_FLAG_INVALID_OPT;
             return ((OS_FLAGS)0);
    }
    sched = FALSE;                                   /* Indicate that we don't need rescheduling       */
	//初始化假设不会导致更高优先级任务进入就绪态,所以不需要调度
    pnode = (OS_FLAG_NODE *)pgrp->OSFlagWaitList;//取出等待列表中的第一个结点
    while (pnode != (OS_FLAG_NODE *)0) {             /* Go through all tasks waiting on event flag(s)  */
		//如果有任务等待,遍历事件标志中所有任务
        switch (pnode->OSFlagNodeWaitType) {//等待的类型是什么
            case OS_FLAG_WAIT_SET_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   */
            //并不是每检查一个OSFLAG_NODE就进行一次任务调度,而是在遍历完全部等待任务后
            //进行一次总的任务调度。
                     }
                 }
                 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; /* Point to next task waiting for event flag(s) */
		//通过双向链表得到下一个OSFlagNode

    }
    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*/
/*
*********************************************************************************************************
*                                           QUERY EVENT FLAG
*
* Description: This function is used to check the value of the event flag group.
*
* Arguments  : pgrp         is a pointer to the desired event flag group.
*
*              err           is a pointer to an error code returned to the called:
*                            OS_NO_ERR              The call was successfull
*                            OS_FLAG_INVALID_PGRP   You passed a NULL pointer
*                            OS_ERR_EVENT_TYPE      You are not pointing to an event flag group
*
* Returns    : The current value of the event flag group.
*
* Called From: Task or ISR
                                                         查询事件标志组的状态
描述:用于查询事件标志组的状态
参数: pgrp:指向目标事件标志组的状态
                  err:返回给调用函数的出错代码指针:
*                            OS_NO_ERR              调用成功
*                            OS_FLAG_INVALID_PGRP   你传递了空指针
*                            OS_ERR_EVENT_TYPE      你没有指向一个事件标志组                    
*********************************************************************************************************
*/

#if OS_FLAG_QUERY_EN > 0//包含 OSFlagQuery()代码
OS_FLAGS  OSFlagQuery (OS_FLAG_GRP *pgrp, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3                       /* Allocate storage for CPU status register          */
    OS_CPU_SR  cpu_sr;
#endif
    OS_FLAGS   flags;


#if OS_ARG_CHK_EN > 0
    if (pgrp == (OS_FLAG_GRP *)0) {               /* Validate 'pgrp'                                   */
        *err = OS_FLAG_INVALID_PGRP;
        return ((OS_FLAGS)0);//不合理的pgrp
    }
    if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Validate event block type                         */
        *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);      /* Return the current value of the event flags       */
	//返回状态标志给调用函数
}
#endif

/*$PAGE*/
/*
*********************************************************************************************************
*                         SUSPEND TASK UNTIL EVENT FLAG(s) RECEIVED OR TIMEOUT OCCURS
*
* Description: This function is internal to uC/OS-II and is used to put a task to sleep until the desired
*              event flag bit(s) are set.
*
* Arguments  : pgrp          is a pointer to the desired event flag group.
*
*              pnode         is a pointer to a structure which contains data about the task waiting for
*                            event flag bit(s) to be set.
*
*              flags         Is a bit pattern indicating which bit(s) (i.e. flags) you wish to check.
*                            The bits you want are specified by setting the corresponding bits in
*                            'flags'.  e.g. if your application wants to wait for bits 0 and 1 then
*                            'flags' would contain 0x03.
*
*              wait_type     specifies whether you want ALL bits to be set/cleared or ANY of the bits
*                            to be set/cleared.
*                            You can specify the following argument:
*
*                            OS_FLAG_WAIT_CLR_ALL   You will check ALL bits in 'mask' to be clear (0)
*                            OS_FLAG_WAIT_CLR_ANY   You will check ANY bit  in 'mask' to be clear (0)
*                            OS_FLAG_WAIT_SET_ALL   You will check ALL bits in 'mask' to be set   (1)
*                            OS_FLAG_WAIT_SET_ANY   You will check ANY bit  in 'mask' to be set   (1)
*
*              timeout       is the desired amount of time that the task will wait for the event flag
*                            bit(s) to be set.
*
* Returns    : none
*
* Called by  : OSFlagPend()  OS_FLAG.C
*
* Note(s)    : This function is INTERNAL to uC/OS-II and your application should not call it.
                                           挂起任务直到事件标志来到或者超时
描述:它是一个ucos内部函数,将一个任务睡眠直到目标标志位置位
参数:pgrp:指向目标事件控制块的指针
                 pnode:指向等待事件标志位置位的任务的数据的结构指针
                 flags:是一个位模式,包含想检验的位,通过设置flags中相应位来设置你想要
                             的位。比如:如果应用中想等待0和1位,那么flags就为0x03。
                 wait_type:标志你想所有位设置/清零还是任何位设置/清零
                 你可以设成以下参数:
*                            OS_FLAG_WAIT_CLR_ALL   You will check ALL bits in 'mask' to be clear (0)
*                            OS_FLAG_WAIT_CLR_ANY   You will check ANY bit  in 'mask' to be clear (0)
*                            OS_FLAG_WAIT_SET_ALL   You will check ALL bits in 'mask' to be set   (1)
*                            OS_FLAG_WAIT_SET_ANY   You will check ANY bit  in 'mask' to be set   (1)

⌨️ 快捷键说明

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