📄 os_flag.c
字号:
p_grp->Type = OS_OBJ_TYPE_NONE;
p_grp->NamePtr = (CPU_CHAR *)((void *)"?FLAG"); /* Unknown name */
p_grp->Flags = (OS_FLAGS )0;
p_pend_list = &p_grp->PendList;
OS_PendListInit(p_pend_list);
}
/*$PAGE*/
/*
************************************************************************************************************************
* INITIALIZE THE EVENT FLAG MODULE
*
* Description: This function is called by uC/OS-III to initialize the event flag module. Your application MUST NOT call
* this function. In other words, this function is internal to uC/OS-III.
*
* Arguments : p_err is a pointer to an error code that can contain one of the following values:
*
* OS_ERR_NONE The call was successful.
*
* Returns : none
*
* Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
void OS_FlagInit (OS_ERR *p_err)
{
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_CFG_DBG_EN > 0u
OSFlagDbgListPtr = (OS_FLAG_GRP *)0;
#endif
OSFlagQty = (OS_OBJ_QTY )0;
*p_err = OS_ERR_NONE;
}
/*$PAGE*/
/*
************************************************************************************************************************
* ADD/REMOVE EVENT FLAG GROUP TO/FROM DEBUG LIST
*
* Description: These functions are called by uC/OS-III to add or remove an event flag group from the event flag debug
* list.
*
* Arguments : p_grp is a pointer to the event flag group to add/remove
*
* Returns : none
*
* Note(s) : These functions are INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
#if OS_CFG_DBG_EN > 0u
void OS_FlagDbgListAdd (OS_FLAG_GRP *p_grp)
{
p_grp->DbgNamePtr = (CPU_CHAR *)((void *)" ");
p_grp->DbgPrevPtr = (OS_FLAG_GRP *)0;
if (OSFlagDbgListPtr == (OS_FLAG_GRP *)0) {
p_grp->DbgNextPtr = (OS_FLAG_GRP *)0;
} else {
p_grp->DbgNextPtr = OSFlagDbgListPtr;
OSFlagDbgListPtr->DbgPrevPtr = p_grp;
}
OSFlagDbgListPtr = p_grp;
}
void OS_FlagDbgListRemove (OS_FLAG_GRP *p_grp)
{
OS_FLAG_GRP *p_grp_next;
OS_FLAG_GRP *p_grp_prev;
p_grp_prev = p_grp->DbgPrevPtr;
p_grp_next = p_grp->DbgNextPtr;
if (p_grp_prev == (OS_FLAG_GRP *)0) {
OSFlagDbgListPtr = p_grp_next;
if (p_grp_next != (OS_FLAG_GRP *)0) {
p_grp_next->DbgPrevPtr = (OS_FLAG_GRP *)0;
}
p_grp->DbgNextPtr = (OS_FLAG_GRP *)0;
} else if (p_grp_next == (OS_FLAG_GRP *)0) {
p_grp_prev->DbgNextPtr = (OS_FLAG_GRP *)0;
p_grp->DbgPrevPtr = (OS_FLAG_GRP *)0;
} else {
p_grp_prev->DbgNextPtr = p_grp_next;
p_grp_next->DbgPrevPtr = p_grp_prev;
p_grp->DbgNextPtr = (OS_FLAG_GRP *)0;
p_grp->DbgPrevPtr = (OS_FLAG_GRP *)0;
}
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* POST EVENT FLAG BIT(S)
*
* Description: This function is called to set or clear some bits in an event flag group. The bits to set or clear are
* specified by a 'bit mask'.
*
* Arguments : p_grp is a pointer to the desired event flag group.
*
* flags If 'opt' (see below) is OS_OPT_POST_FLAG_SET, each bit that is set in 'flags' will
* set the corresponding bit in the event flag group. e.g. to set bits 0, 4
* and 5 you would set 'flags' to:
*
* 0x31 (note, bit 0 is least significant bit)
*
* If 'opt' (see below) is OS_OPT_POST_FLAG_CLR, each bit that is set in 'flags' will
* CLEAR the corresponding bit in the event flag group. e.g. to clear bits 0,
* 4 and 5 you would specify 'flags' as:
*
* 0x31 (note, bit 0 is least significant bit)
*
* opt indicates whether the flags will be:
*
* OS_OPT_POST_FLAG_SET set
* OS_OPT_POST_FLAG_CLR cleared
*
* you can also 'add' OS_OPT_POST_NO_SCHED to prevent the scheduler from being called.
*
* ts is the timestamp of the post
*
* p_err is a pointer to an error code and can be:
*
* OS_ERR_NONE The call was successful
* OS_ERR_OBJ_PTR_NULL You passed a NULL pointer
* OS_ERR_OBJ_TYPE You are not pointing to an event flag group
* OS_ERR_OPT_INVALID You specified an invalid option
*
* Returns : the new value of the event flags bits that are still set.
*
* Note(s) : 1) The execution time of this function depends on the number of tasks waiting on the event flag group.
************************************************************************************************************************
*/
OS_FLAGS OS_FlagPost (OS_FLAG_GRP *p_grp,
OS_FLAGS flags,
OS_OPT opt,
CPU_TS ts,
OS_ERR *p_err)
{
OS_FLAGS flags_cur;
OS_FLAGS flags_rdy;
OS_OPT mode;
OS_PEND_DATA *p_pend_data;
OS_PEND_DATA *p_pend_data_next;
OS_PEND_LIST *p_pend_list;
OS_TCB *p_tcb;
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
switch (opt) {
case OS_OPT_POST_FLAG_SET:
case OS_OPT_POST_FLAG_SET | OS_OPT_POST_NO_SCHED:
p_grp->Flags |= flags; /* Set the flags specified in the group */
break;
case OS_OPT_POST_FLAG_CLR:
case OS_OPT_POST_FLAG_CLR | OS_OPT_POST_NO_SCHED:
p_grp->Flags &= ~flags; /* Clear the flags specified in the group */
break;
default:
CPU_CRITICAL_EXIT(); /* INVALID option */
*p_err = OS_ERR_OPT_INVALID;
return ((OS_FLAGS)0);
}
p_grp->TS = ts;
p_pend_list = &p_grp->PendList;
if (p_pend_list->NbrEntries == 0u) { /* Any task waiting on event flag group? */
CPU_CRITICAL_EXIT(); /* No */
*p_err = OS_ERR_NONE;
return (p_grp->Flags);
}
OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT();
p_pend_data = p_pend_list->HeadPtr;
p_tcb = p_pend_data->TCBPtr;
while (p_tcb != (OS_TCB *)0) { /* Go through all tasks waiting on event flag(s) */
p_pend_data_next = p_pend_data->NextPtr;
mode = p_tcb->FlagsOpt & OS_OPT_PEND_FLAG_MASK;
switch (mode) {
case OS_OPT_PEND_FLAG_SET_ALL: /* See if all req. flags are set for current node */
flags_rdy = (OS_FLAGS)(p_grp->Flags & p_tcb->FlagsPend);
if (flags_rdy == p_tcb->FlagsPend) {
OS_FlagTaskRdy(p_tcb, /* Make task RTR, event(s) Rx'd */
flags_rdy,
ts);
}
break;
case OS_OPT_PEND_FLAG_SET_ANY: /* See if any flag set */
flags_rdy = (OS_FLAGS)(p_grp->Flags & p_tcb->FlagsPend);
if (flags_rdy != (OS_FLAGS)0) {
OS_FlagTaskRdy(p_tcb, /* Make task RTR, event(s) Rx'd */
flags_rdy,
ts);
}
break;
#if OS_CFG_FLAG_MODE_CLR_EN > 0u
case OS_OPT_PEND_FLAG_CLR_ALL: /* See if all req. flags are set for current node */
flags_rdy = (OS_FLAGS)(~p_grp->Flags & p_tcb->FlagsPend);
if (flags_rdy == p_tcb->FlagsPend) {
OS_FlagTaskRdy(p_tcb, /* Make task RTR, event(s) Rx'd */
flags_rdy,
ts);
}
break;
case OS_OPT_PEND_FLAG_CLR_ANY: /* See if any flag set */
flags_rdy = (OS_FLAGS)(~p_grp->Flags & p_tcb->FlagsPend);
if (flags_rdy != (OS_FLAGS)0) {
OS_FlagTaskRdy(p_tcb, /* Make task RTR, event(s) Rx'd */
flags_rdy,
ts);
}
break;
#endif
default:
OS_CRITICAL_EXIT();
*p_err = OS_ERR_FLAG_PEND_OPT;
return ((OS_FLAGS)0);
}
p_pend_data = p_pend_data_next; /* Point to next task waiting for event flag(s) */
if (p_pend_data != (OS_PEND_DATA *)0) {
p_tcb = p_pend_data->TCBPtr;
} else {
p_tcb = (OS_TCB *)0;
}
}
OS_CRITICAL_EXIT_NO_SCHED();
if ((opt & OS_OPT_POST_NO_SCHED) == (OS_OPT)0) {
OSSched();
}
CPU_CRITICAL_ENTER();
flags_cur = p_grp->Flags;
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
return (flags_cur);
}
/*$PAGE*/
/*
************************************************************************************************************************
* MAKE TASK READY-TO-RUN, EVENT(s) OCCURRED
*
* Description: This function is internal to uC/OS-III and is used to make a task ready-to-run because the desired event
* flag bits have been set.
*
* Arguments : p_tcb is a pointer to the OS_TCB of the task to remove
* -----
*
* flags_rdy contains the bit pattern of the event flags that cause the task to become ready-to-run.
*
* ts is a timestamp associated with the post
*
* Returns : none
*
* Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
void OS_FlagTaskRdy (OS_TCB *p_tcb,
OS_FLAGS flags_rdy,
CPU_TS ts)
{
p_tcb->FlagsRdy = flags_rdy;
p_tcb->PendStatus = OS_STATUS_PEND_OK; /* Clear pend status */
p_tcb->PendOn = OS_TASK_PEND_ON_NOTHING; /* Indicate no longer pending */
p_tcb->TS = ts;
switch (p_tcb->TaskState) {
case OS_TASK_STATE_RDY:
case OS_TASK_STATE_DLY:
case OS_TASK_STATE_DLY_SUSPENDED:
case OS_TASK_STATE_SUSPENDED:
break;
case OS_TASK_STATE_PEND:
case OS_TASK_STATE_PEND_TIMEOUT:
OS_TaskRdy(p_tcb);
p_tcb->TaskState = OS_TASK_STATE_RDY;
break;
case OS_TASK_STATE_PEND_SUSPENDED:
case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
p_tcb->TaskState = OS_TASK_STATE_SUSPENDED;
break;
default:
break;
}
OS_PendListRemove(p_tcb);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -