📄 os_flag.c
字号:
/*
************************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2009-2011; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* EVENT FLAG MANAGEMENT
*
* File : OS_FLAG.C
* By : JJL
* Version : V3.02.00
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
* product then, you need to contact Micrium to properly license uC/OS-III for its use in your
* application/product. We provide ALL the source code for your convenience and to help you
* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
* it commercially without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the embedded community with the finest software available.
* Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
************************************************************************************************************************
*/
#include <os.h>
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_flag__c = "$Id: $";
#endif
#if OS_CFG_FLAG_EN > 0u
/*$PAGE*/
/*
************************************************************************************************************************
* CREATE AN EVENT FLAG
*
* Description: This function is called to create an event flag group.
*
* Arguments : p_grp is a pointer to the event flag group to create
*
* p_name is the name of the event flag group
*
* flags contains the initial value to store in the event flag group (typically 0).
*
* p_err is a pointer to an error code which will be returned to your application:
*
* OS_ERR_NONE if the call was successful.
* OS_ERR_CREATE_ISR if you attempted to create an Event Flag from an ISR.
* OS_ERR_ILLEGAL_CREATE_RUN_TIME if you are trying to create the Event Flag after you
* called OSSafetyCriticalStart().
* OS_ERR_NAME if 'p_name' is a NULL pointer
* OS_ERR_OBJ_CREATED if the event flag group has already been created
* OS_ERR_OBJ_PTR_NULL if 'p_grp' is a NULL pointer
*
* Returns : none
************************************************************************************************************************
*/
void OSFlagCreate (OS_FLAG_GRP *p_grp,
CPU_CHAR *p_name,
OS_FLAGS flags,
OS_ERR *p_err)
{
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#ifdef OS_SAFETY_CRITICAL_IEC61508
if (OSSafetyCriticalStartFlag == DEF_TRUE) {
*p_err = OS_ERR_ILLEGAL_CREATE_RUN_TIME;
return;
}
#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_CREATE_ISR; /* ... can't CREATE from an ISR */
return;
}
#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;
}
#endif
OS_CRITICAL_ENTER();
p_grp->Type = OS_OBJ_TYPE_FLAG; /* Set to event flag group type */
p_grp->NamePtr = p_name;
p_grp->Flags = flags; /* Set to desired initial value */
p_grp->TS = (CPU_TS)0;
OS_PendListInit(&p_grp->PendList);
#if OS_CFG_DBG_EN > 0u
OS_FlagDbgListAdd(p_grp);
#endif
OSFlagQty++;
OS_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
}
/*$PAGE*/
/*
************************************************************************************************************************
* DELETE AN EVENT FLAG GROUP
*
* Description: This function deletes an event flag group and readies all tasks pending on the event flag group.
*
* Arguments : p_grp is a pointer to the desired event flag group.
*
* opt determines delete options as follows:
*
* OS_OPT_DEL_NO_PEND Deletes the event flag group ONLY if no task pending
* OS_OPT_DEL_ALWAYS Deletes the event flag group even if tasks are waiting.
* In this case, all the tasks pending will be readied.
*
* p_err is a pointer to an error code that can contain one of the following values:
*
* OS_ERR_NONE The call was successful and the event flag group was deleted
* OS_ERR_DEL_ISR If you attempted to delete the event flag group from an ISR
* OS_ERR_OBJ_PTR_NULL If 'p_grp' is a NULL pointer.
* OS_ERR_OBJ_TYPE If you didn't pass a pointer to an event flag group
* OS_ERR_OPT_INVALID An invalid option was specified
* OS_ERR_TASK_WAITING One or more tasks were waiting on the event flag group.
*
* Returns : == 0 if no tasks were waiting on the event flag group, or upon error.
* > 0 if one or more tasks waiting on the event flag group are now readied and informed.
*
* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of the event flag
* group MUST check the return code of OSFlagPost and OSFlagPend().
************************************************************************************************************************
*/
#if OS_CFG_FLAG_DEL_EN > 0u
OS_OBJ_QTY OSFlagDel (OS_FLAG_GRP *p_grp,
OS_OPT opt,
OS_ERR *p_err)
{
OS_OBJ_QTY cnt;
OS_OBJ_QTY nbr_tasks;
OS_PEND_DATA *p_pend_data;
OS_PEND_LIST *p_pend_list;
OS_TCB *p_tcb;
CPU_TS ts;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((OS_OBJ_QTY)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_DEL_ISR; /* ... can't DELETE from an ISR */
return ((OS_OBJ_QTY)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_OBJ_QTY)0);
}
switch (opt) {
case OS_OPT_DEL_NO_PEND:
case OS_OPT_DEL_ALWAYS:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return ((OS_OBJ_QTY)0);
}
#endif
#if OS_CFG_OBJ_TYPE_CHK_EN > 0u
if (p_grp->Type != OS_OBJ_TYPE_FLAG) { /* Validate event group object */
*p_err = OS_ERR_OBJ_TYPE;
return ((OS_OBJ_QTY)0);
}
#endif
OS_CRITICAL_ENTER();
p_pend_list = &p_grp->PendList;
cnt = p_pend_list->NbrEntries;
nbr_tasks = cnt;
switch (opt) {
case OS_OPT_DEL_NO_PEND: /* Delete group if no task waiting */
if (nbr_tasks == (OS_OBJ_QTY)0) {
#if OS_CFG_DBG_EN > 0u
OS_FlagDbgListRemove(p_grp);
#endif
OSFlagQty--;
OS_FlagClr(p_grp);
OS_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
} else {
OS_CRITICAL_EXIT();
*p_err = OS_ERR_TASK_WAITING;
}
break;
case OS_OPT_DEL_ALWAYS: /* Always delete the event flag group */
ts = OS_TS_GET(); /* Get local time stamp so all tasks get the same time */
while (cnt > 0u) { /* Remove all tasks from the pend list */
p_pend_data = p_pend_list->HeadPtr;
p_tcb = p_pend_data->TCBPtr;
OS_PendObjDel((OS_PEND_OBJ *)((void *)p_grp),
p_tcb,
ts);
cnt--;
}
#if OS_CFG_DBG_EN > 0u
OS_FlagDbgListRemove(p_grp);
#endif
OSFlagQty--;
OS_FlagClr(p_grp);
OS_CRITICAL_EXIT_NO_SCHED();
OSSched(); /* Find highest priority task ready to run */
*p_err = OS_ERR_NONE;
break;
default:
OS_CRITICAL_EXIT();
*p_err = OS_ERR_OPT_INVALID;
break;
}
return (nbr_tasks);
}
#endif
/*
************************************************************************************************************************
* WAIT ON AN EVENT FLAG GROUP
*
* Description: This function is called to wait for a combination of bits to be set in an event flag group. Your
* application can wait for ANY bit to be set or ALL bits to be set.
*
* Arguments : 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 wait for.
* 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.
*
* timeout is an optional timeout (in clock ticks) that your task will wait for the
* desired bit combination. If you specify 0, however, your task will wait
* forever at the specified event flag group or, until a message arrives.
*
* opt specifies whether you want ALL bits to be set or ANY of the bits to be set.
* You can specify the 'ONE' of the following arguments:
*
* OS_OPT_PEND_FLAG_CLR_ALL You will wait for ALL bits in 'flags' to be clear (0)
* OS_OPT_PEND_FLAG_CLR_ANY You will wait for ANY bit in 'flags' to be clear (0)
* OS_OPT_PEND_FLAG_SET_ALL You will wait for ALL bits in 'flags' to be set (1)
* OS_OPT_PEND_FLAG_SET_ANY You will wait for ANY bit in 'flags' to be set (1)
*
* You can 'ADD' OS_OPT_PEND_FLAG_CONSUME if you want the event flag to be 'consumed' by
* the call. Example, to wait for any flag in a group AND then clear
* the flags that are present, set 'wait_opt' to:
*
* OS_OPT_PEND_FLAG_SET_ANY + OS_OPT_PEND_FLAG_CONSUME
*
* You can also 'ADD' the type of pend with 'ONE' of the two option:
*
* OS_OPT_PEND_NON_BLOCKING Task will NOT block if flags are not available
* OS_OPT_PEND_BLOCKING Task will block if flags are not available
*
* p_ts is a pointer to a variable that will receive the timestamp of when the event flag group was
* posted, aborted or the event flag group deleted. If you pass a NULL pointer (i.e. (CPU_TS *)0)
* then you will not get the timestamp. In other words, passing a NULL pointer is valid and
* indicates that you don't need the timestamp.
*
* p_err is a pointer to an error code and can be:
*
* OS_ERR_NONE The desired bits have been set within the specified 'timeout'
* OS_ERR_OBJ_PTR_NULL If 'p_grp' is a NULL pointer.
* OS_ERR_OBJ_TYPE You are not pointing to an event flag group
* OS_ERR_OPT_INVALID You didn't specify a proper 'opt' argument.
* OS_ERR_PEND_ABORT The wait on the flag was aborted.
* OS_ERR_PEND_ISR If you tried to PEND from an ISR
* OS_ERR_PEND_WOULD_BLOCK If you specified non-blocking but the flags were not
* available.
* OS_ERR_SCHED_LOCKED If you called this function when the scheduler is locked
* OS_ERR_TIMEOUT The bit(s) have not been set in the specified 'timeout'.
*
* Returns : The flags in the event flag group that made the task ready or, 0 if a timeout or an error
* occurred.
************************************************************************************************************************
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -