📄 os_task.c
字号:
}
#endif
OS_TaskResume(p_tcb, p_err);
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* WAIT FOR A TASK SEMAPHORE
*
* Description: This function is called to block the current task until a signal is sent by another task or ISR.
*
* Arguments : timeout is the amount of time you are will to wait for the signal
*
* opt determines whether the user wants to block if a semaphore post was not received:
*
* OS_OPT_PEND_BLOCKING
* OS_OPT_PEND_NON_BLOCKING
*
* p_ts is a pointer to a variable that will receive the timestamp of when the semaphore was posted
* or pend aborted. 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 that will be set by this function
*
* OS_ERR_NONE The call was successful and your task received a message.
* OS_ERR_PEND_ABORT
* OS_ERR_PEND_ISR If you called this function from an ISR and the result
* OS_ERR_PEND_WOULD_BLOCK If you specified non-blocking but no signal was received
* OS_ERR_SCHED_LOCKED If the scheduler is locked
* OS_ERR_STATUS_INVALID If the pend status is invalid
* OS_ERR_TIMEOUT A message was not received within the specified timeout
* would lead to a suspension.
*
* Returns : The current count of signals the task received, 0 if none.
************************************************************************************************************************
*/
OS_SEM_CTR OSTaskSemPend (OS_TICK timeout,
OS_OPT opt,
CPU_TS *p_ts,
OS_ERR *p_err)
{
OS_SEM_CTR ctr;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((OS_SEM_CTR)0);
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to call from an ISR */
*p_err = OS_ERR_PEND_ISR;
return ((OS_SEM_CTR)0);
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
switch (opt) { /* Validate 'opt' */
case OS_OPT_PEND_BLOCKING:
case OS_OPT_PEND_NON_BLOCKING:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return ((OS_SEM_CTR)0);
}
#endif
if (p_ts != (CPU_TS *)0) {
*p_ts = (CPU_TS )0; /* Initialize the returned timestamp */
}
CPU_CRITICAL_ENTER();
if (OSTCBCurPtr->SemCtr > (OS_SEM_CTR)0) { /* See if task already been signaled */
OSTCBCurPtr->SemCtr--;
ctr = OSTCBCurPtr->SemCtr;
if (p_ts != (CPU_TS *)0) {
*p_ts = OSTCBCurPtr->TS;
}
#if OS_CFG_TASK_PROFILE_EN > 0u
OSTCBCurPtr->SemPendTime = OS_TS_GET() - OSTCBCurPtr->TS;
if (OSTCBCurPtr->SemPendTimeMax < OSTCBCurPtr->SemPendTime) {
OSTCBCurPtr->SemPendTimeMax = OSTCBCurPtr->SemPendTime;
}
#endif
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
return (ctr);
}
if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) { /* Caller wants to block if not available? */
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_PEND_WOULD_BLOCK; /* No */
return ((OS_SEM_CTR)0);
} else { /* Yes */
if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* Can't pend when the scheduler is locked */
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_SCHED_LOCKED;
return ((OS_SEM_CTR)0);
}
}
/* Lock the scheduler/re-enable interrupts */
OS_CRITICAL_ENTER_CPU_EXIT();
OS_Pend((OS_PEND_DATA *)0, /* Block task pending on Signal */
(OS_PEND_OBJ *)0,
(OS_STATE )OS_TASK_PEND_ON_TASK_SEM,
(OS_TICK )timeout);
OS_CRITICAL_EXIT_NO_SCHED();
OSSched(); /* Find next highest priority task ready to run */
CPU_CRITICAL_ENTER();
switch (OSTCBCurPtr->PendStatus) { /* See if we timed-out or aborted */
case OS_STATUS_PEND_OK:
if (p_ts != (CPU_TS *)0) {
*p_ts = OSTCBCurPtr->TS;
#if OS_CFG_TASK_PROFILE_EN > 0u
OSTCBCurPtr->SemPendTime = OS_TS_GET() - OSTCBCurPtr->TS;
if (OSTCBCurPtr->SemPendTimeMax < OSTCBCurPtr->SemPendTime) {
OSTCBCurPtr->SemPendTimeMax = OSTCBCurPtr->SemPendTime;
}
#endif
}
*p_err = OS_ERR_NONE;
break;
case OS_STATUS_PEND_ABORT:
if (p_ts != (CPU_TS *)0) {
*p_ts = OSTCBCurPtr->TS;
}
*p_err = OS_ERR_PEND_ABORT; /* Indicate that we aborted */
break;
case OS_STATUS_PEND_TIMEOUT:
if (p_ts != (CPU_TS *)0) {
*p_ts = (CPU_TS )0;
}
*p_err = OS_ERR_TIMEOUT; /* Indicate that we didn't get event within TO */
break;
default:
*p_err = OS_ERR_STATUS_INVALID;
break;
}
ctr = OSTCBCurPtr->SemCtr;
CPU_CRITICAL_EXIT();
return (ctr);
}
/*$PAGE*/
/*
************************************************************************************************************************
* ABORT WAITING FOR A SIGNAL
*
* Description: This function aborts & readies the task specified. This function should be used to fault-abort the wait
* for a signal, rather than to normally post the signal to the task via OSTaskSemPost().
*
* Arguments : p_tcb is a pointer to the task to pend abort
*
* opt provides options for this function:
*
* OS_OPT_POST_NONE No option selected
* OS_OPT_POST_NO_SCHED Indicates that the scheduler will not be called.
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE If the task was readied and informed of the aborted wait
* OS_ERR_PEND_ABORT_ISR If you tried calling this function from an ISR
* OS_ERR_PEND_ABORT_NONE If the task was not waiting for a signal
* OS_ERR_PEND_ABORT_SELF If you attempted to pend abort the calling task. This is not
* possible since the calling task cannot be pending because it's
* running.
*
* Returns : == DEF_FALSE if task was not waiting for a message, or upon error.
* == DEF_TRUE if task was waiting for a message and was readied and informed.
************************************************************************************************************************
*/
#if OS_CFG_TASK_SEM_PEND_ABORT_EN > 0u
CPU_BOOLEAN OSTaskSemPendAbort (OS_TCB *p_tcb,
OS_OPT opt,
OS_ERR *p_err)
{
CPU_TS ts;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return (DEF_FALSE);
}
#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_ABORT_ISR; /* ... can't Pend Abort from an ISR */
return (DEF_FALSE);
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
switch (opt) { /* Validate 'opt' */
case OS_OPT_POST_NONE:
case OS_OPT_POST_NO_SCHED:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return (DEF_FALSE);
}
#endif
CPU_CRITICAL_ENTER();
if ((p_tcb == (OS_TCB *)0) || /* Pend abort self? */
(p_tcb == OSTCBCurPtr)) {
CPU_CRITICAL_EXIT(); /* ... doesn't make sense! */
*p_err = OS_ERR_PEND_ABORT_SELF;
return (DEF_FALSE);
}
if (p_tcb->PendOn != OS_TASK_PEND_ON_TASK_SEM) { /* Is task waiting for a signal? */
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_PEND_ABORT_NONE;
return (DEF_FALSE);
}
CPU_CRITICAL_EXIT();
OS_CRITICAL_ENTER();
ts = OS_TS_GET();
OS_PendAbort((OS_PEND_OBJ *)0,
p_tcb,
ts);
OS_CRITICAL_EXIT_NO_SCHED();
if ((opt & OS_OPT_POST_NO_SCHED) == (OS_OPT)0) {
OSSched(); /* Run the scheduler */
}
*p_err = OS_ERR_NONE;
return (DEF_TRUE);
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* SIGNAL A TASK
*
* Description: This function is called to signal a task waiting for a signal.
*
* Arguments : p_tcb is the pointer to the TCB of the task to signal. A NULL pointer indicates that you are sending
* a signal to yourself.
*
* opt determines the type of POST performed:
*
* OS_OPT_POST_NONE No option
* OS_OPT_POST_NO_SCHED Do not call the scheduler
*
* p_err is a pointer to an error code returned by this function:
*
* OS_ERR_NONE If the requested task is signaled
* OS_ERR_SEM_OVF If the post would cause the semaphore count to overflow.
*
* Returns : The current value of the task's signal counter or 0 if called from an ISR
************************************************************************************************************************
*/
OS_SEM_CTR OSTaskSemPost (OS_TCB *p_tcb,
OS_OPT opt,
OS_ERR *p_err)
{
OS_SEM_CTR ctr;
CPU_TS ts;
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((OS_SEM_CTR)0);
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
switch (opt) { /* Validate 'opt' */
case OS_OPT_POST_NONE:
case OS_OPT_POST_NO_SCHED:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return ((OS_SEM_CTR)0u);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -