📄 os_flag.c
字号:
OS_ERR *p_err)
{
OS_PEND_LIST *p_pend_list;
OS_TCB *p_tcb;
CPU_TS ts;
OS_OBJ_QTY nbr_tasks;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((OS_OBJ_QTY)0u);
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0u) { /* Not allowed to Pend Abort from an ISR */
*p_err = OS_ERR_PEND_ABORT_ISR;
return ((OS_OBJ_QTY)0u);
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_grp == (OS_FLAG_GRP *)0) { /* Validate 'p_grp' */
*p_err = OS_ERR_OBJ_PTR_NULL;
return ((OS_OBJ_QTY)0u);
}
switch (opt) { /* Validate 'opt' */
case OS_OPT_PEND_ABORT_1:
case OS_OPT_PEND_ABORT_ALL:
case OS_OPT_PEND_ABORT_1 | OS_OPT_POST_NO_SCHED:
case OS_OPT_PEND_ABORT_ALL | OS_OPT_POST_NO_SCHED:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return ((OS_OBJ_QTY)0u);
}
#endif
#if OS_CFG_OBJ_TYPE_CHK_EN > 0u
if (p_grp->Type != OS_OBJ_TYPE_FLAG) { /* Make sure event flag group was created */
*p_err = OS_ERR_OBJ_TYPE;
return ((OS_OBJ_QTY)0u);
}
#endif
CPU_CRITICAL_ENTER();
p_pend_list = &p_grp->PendList;
if (p_pend_list->NbrEntries == (OS_OBJ_QTY)0u) { /* Any task waiting on flag group? */
CPU_CRITICAL_EXIT(); /* No */
*p_err = OS_ERR_PEND_ABORT_NONE;
return ((OS_OBJ_QTY)0u);
}
OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT();
nbr_tasks = 0u;
ts = OS_TS_GET(); /* Get local time stamp so all tasks get the same time */
while (p_pend_list->NbrEntries > (OS_OBJ_QTY)0u) {
p_tcb = p_pend_list->HeadPtr->TCBPtr;
OS_PendAbort((OS_PEND_OBJ *)((void *)p_grp),
p_tcb,
ts);
nbr_tasks++;
if (opt != OS_OPT_PEND_ABORT_ALL) { /* Pend abort all tasks waiting? */
break; /* No */
}
}
OS_CRITICAL_EXIT_NO_SCHED();
if ((opt & OS_OPT_POST_NO_SCHED) == (OS_OPT)0u) {
OSSched(); /* Run the scheduler */
}
*p_err = OS_ERR_NONE;
return (nbr_tasks);
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* GET FLAGS WHO CAUSED TASK TO BECOME READY
*
* Description: This function is called to obtain the flags that caused the task to become ready to run.
* In other words, this function allows you to tell "Who done it!".
*
* Arguments : p_err is a pointer to an error code
*
* OS_ERR_NONE if the call was successful
* OS_ERR_PEND_ISR if called from an ISR
*
* Returns : The flags that caused the task to be ready.
************************************************************************************************************************
*/
OS_FLAGS OSFlagPendGetFlagsRdy (OS_ERR *p_err)
{
OS_FLAGS flags;
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 get from an ISR */
return ((OS_FLAGS)0);
}
#endif
CPU_CRITICAL_ENTER();
flags = OSTCBCurPtr->FlagsRdy;
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
return (flags);
}
/*$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.
*
* 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 OSFlagPost (OS_FLAG_GRP *p_grp,
OS_FLAGS flags,
OS_OPT opt,
OS_ERR *p_err)
{
OS_FLAGS flags_cur;
CPU_TS ts;
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((OS_FLAGS)0);
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_grp == (OS_FLAG_GRP *)0) { /* Validate 'p_grp' */
*p_err = OS_ERR_OBJ_PTR_NULL;
return ((OS_FLAGS)0);
}
switch (opt) {
case OS_OPT_POST_FLAG_SET:
case OS_OPT_POST_FLAG_CLR:
case OS_OPT_POST_FLAG_SET | OS_OPT_POST_NO_SCHED:
case OS_OPT_POST_FLAG_CLR | OS_OPT_POST_NO_SCHED:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return ((OS_FLAGS)0);
}
#endif
#if OS_CFG_OBJ_TYPE_CHK_EN > 0u
if (p_grp->Type != OS_OBJ_TYPE_FLAG) { /* Make sure we are pointing to an event flag grp */
*p_err = OS_ERR_OBJ_TYPE;
return ((OS_FLAGS)0);
}
#endif
ts = OS_TS_GET(); /* Get timestamp */
#if OS_CFG_ISR_POST_DEFERRED_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* See if called from an ISR */
OS_IntQPost((OS_OBJ_TYPE)OS_OBJ_TYPE_FLAG, /* Post to ISR queue */
(void *)p_grp,
(void *)0,
(OS_MSG_SIZE)0,
(OS_FLAGS )flags,
(OS_OPT )opt,
(CPU_TS )ts,
(OS_ERR *)p_err);
return ((OS_FLAGS)0);
}
#endif
flags_cur = OS_FlagPost(p_grp,
flags,
opt,
ts,
p_err);
return (flags_cur);
}
/*$PAGE*/
/*
************************************************************************************************************************
* SUSPEND TASK UNTIL EVENT FLAG(s) RECEIVED OR TIMEOUT OCCURS
*
* Description: This function is internal to uC/OS-III and is used to put a task to sleep until the desired
* event flag bit(s) are set.
*
* Arguments : p_pend_data is a pointer to an object used to link the task being blocked to the list of task(s)
* ----------- pending on the desired event flag group.
*
* p_grp is a pointer to the desired event flag group.
* -----
*
* 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.
*
* opt 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_OPT_PEND_FLAG_CLR_ALL You will check ALL bits in 'mask' to be clear (0)
* OS_OPT_PEND_FLAG_CLR_ANY You will check ANY bit in 'mask' to be clear (0)
* OS_OPT_PEND_FLAG_SET_ALL You will check ALL bits in 'mask' to be set (1)
* OS_OPT_PEND_FLAG_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
*
* Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
void OS_FlagBlock (OS_PEND_DATA *p_pend_data,
OS_FLAG_GRP *p_grp,
OS_FLAGS flags,
OS_OPT opt,
OS_TICK timeout)
{
OSTCBCurPtr->FlagsPend = flags; /* Save the flags that we need to wait for */
OSTCBCurPtr->FlagsOpt = opt; /* Save the type of wait we are doing */
OSTCBCurPtr->FlagsRdy = (OS_FLAGS)0;
OS_Pend(p_pend_data,
(OS_PEND_OBJ *)((void *)p_grp),
OS_TASK_PEND_ON_FLAG,
timeout);
}
/*$PAGE*/
/*
************************************************************************************************************************
* CLEAR THE CONTENTS OF AN EVENT FLAG GROUP
*
* Description: This function is called by OSFlagDel() to clear the contents of an event flag group
*
* Argument(s): p_grp is a pointer to the event flag group to clear
* -----
*
* Returns : none
*
* Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
void OS_FlagClr (OS_FLAG_GRP *p_grp)
{
OS_PEND_LIST *p_pend_list;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -