os_task.c
来自「UCOS-III」· C语言 代码 · 共 1,541 行 · 第 1/5 页
C
1,541 行
/*$PAGE*/
/*
************************************************************************************************************************
* GET THE CURRENT VALUE OF A TASK REGISTER
*
* Description: This function is called to obtain the current value of a task register. Task registers are application
* specific and can be used to store task specific values such as 'error numbers' (i.e. errno), statistics,
* etc.
*
* Arguments : p_tcb is a pointer to the OS_TCB of the task you want to read the register from. If 'p_tcb' is a
* NULL pointer then you will get the register of the current task.
*
* id is the 'id' of the desired task variable. Note that the 'id' must be less than
* OS_CFG_TASK_REG_TBL_SIZE
*
* p_err is a pointer to a variable that will hold an error code related to this call.
*
* OS_ERR_NONE if the call was successful
* OS_ERR_REG_ID_INVALID if the 'id' is not between 0 and OS_CFG_TASK_REG_TBL_SIZE-1
*
* Returns : The current value of the task's register or 0 if an error is detected.
************************************************************************************************************************
*/
#if OS_CFG_TASK_REG_TBL_SIZE > 0u
OS_REG OSTaskRegGet (OS_TCB *p_tcb,
OS_REG_ID id,
OS_ERR *p_err)
{
OS_REG value;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((OS_REG)0);
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (id >= OS_CFG_TASK_REG_TBL_SIZE) {
*p_err = OS_ERR_REG_ID_INVALID;
return ((OS_REG)0);
}
#endif
CPU_CRITICAL_ENTER();
if (p_tcb == (OS_TCB *)0) {
p_tcb = OSTCBCurPtr;
}
value = p_tcb->RegTbl[id];
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
return ((OS_REG)value);
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* SET THE CURRENT VALUE OF A TASK REGISTER
*
* Description: This function is called to change the current value of a task register. Task registers are application
* specific and can be used to store task specific values such as 'error numbers' (i.e. errno), statistics,
* etc.
*
* Arguments : p_tcb is a pointer to the OS_TCB of the task you want to set the register for. If 'p_tcb' is a NULL
* pointer then you will change the register of the current task.
*
* id is the 'id' of the desired task register. Note that the 'id' must be less than
* OS_CFG_TASK_REG_TBL_SIZE
*
* value is the desired value for the task register.
*
* p_err is a pointer to a variable that will hold an error code related to this call.
*
* OS_ERR_NONE if the call was successful
* OS_ERR_REG_ID_INVALID if the 'id' is not between 0 and OS_CFG_TASK_REG_TBL_SIZE-1
*
* Returns : none
************************************************************************************************************************
*/
#if OS_CFG_TASK_REG_TBL_SIZE > 0u
void OSTaskRegSet (OS_TCB *p_tcb,
OS_REG_ID id,
OS_REG value,
OS_ERR *p_err)
{
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (id >= OS_CFG_TASK_REG_TBL_SIZE) {
*p_err = OS_ERR_REG_ID_INVALID;
return;
}
#endif
CPU_CRITICAL_ENTER();
if (p_tcb == (OS_TCB *)0) {
p_tcb = OSTCBCurPtr;
}
p_tcb->RegTbl[id] = value;
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* RESUME A SUSPENDED TASK
*
* Description: This function is called to resume a previously suspended task. This is the only call that will remove an
* explicit task suspension.
*
* Arguments : p_tcb Is a pointer to the task's OS_TCB to resume
*
* p_err Is a pointer to a variable that will contain an error code returned by this function
*
* OS_ERR_NONE if the requested task is resumed
* OS_ERR_STATE_INVALID if the task is in an invalid state
* OS_ERR_TASK_RESUME_ISR if you called this function from an ISR
* OS_ERR_TASK_RESUME_SELF You cannot resume 'self'
* OS_ERR_TASK_NOT_SUSPENDED if the task to resume has not been suspended
*
* Returns : none
************************************************************************************************************************
*/
#if OS_CFG_TASK_SUSPEND_EN > 0u
void OSTaskResume (OS_TCB *p_tcb,
OS_ERR *p_err)
{
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#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_TASK_RESUME_ISR;
return;
}
#endif
CPU_CRITICAL_ENTER();
#if OS_CFG_ARG_CHK_EN > 0u
if ((p_tcb == (OS_TCB *)0) || /* We cannot resume 'self' */
(p_tcb == OSTCBCurPtr)) {
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_TASK_RESUME_SELF;
return;
}
#endif
*p_err = OS_ERR_NONE;
switch (p_tcb->TaskState) {
case OS_TASK_STATE_RDY:
case OS_TASK_STATE_DLY:
case OS_TASK_STATE_PEND:
case OS_TASK_STATE_PEND_TIMEOUT:
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_TASK_NOT_SUSPENDED;
break;
case OS_TASK_STATE_SUSPENDED:
OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT();
p_tcb->SuspendCtr--;
if (p_tcb->SuspendCtr == (OS_NESTING_CTR)0) {
p_tcb->TaskState = OS_TASK_STATE_RDY;
OS_TaskRdy(p_tcb);
}
OS_CRITICAL_EXIT_NO_SCHED();
break;
case OS_TASK_STATE_DLY_SUSPENDED:
p_tcb->SuspendCtr--;
if (p_tcb->SuspendCtr == (OS_NESTING_CTR)0) {
p_tcb->TaskState = OS_TASK_STATE_DLY;
}
CPU_CRITICAL_EXIT();
break;
case OS_TASK_STATE_PEND_SUSPENDED:
p_tcb->SuspendCtr--;
if (p_tcb->SuspendCtr == (OS_NESTING_CTR)0) {
p_tcb->TaskState = OS_TASK_STATE_PEND;
}
CPU_CRITICAL_EXIT();
break;
case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
p_tcb->SuspendCtr--;
if (p_tcb->SuspendCtr == (OS_NESTING_CTR)0) {
p_tcb->TaskState = OS_TASK_STATE_PEND_TIMEOUT;
}
CPU_CRITICAL_EXIT();
break;
default:
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_STATE_INVALID;
return;
}
OSSched();
}
#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 (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->SemPendTime > OSTCBCurPtr->SemPendTimeMax) {
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? */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?