📄 os_flag.c
字号:
置位或清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 + -