* Version : V3.00.4
os.h中
struct os_tcb {
CPU_STK *StkPtr; /* Pointer to current top of stack */
void *ExtPtr; /* Pointer to user definable data for TCB extension */
CPU_STK *StkLimitPtr; /* Pointer used to set stack 'watermark' limit */
OS_TCB *NextPtr; /* Pointer to next TCB in the TCB list */
OS_TCB *PrevPtr; /* Pointer to previous TCB in the TCB list */
OS_TCB *TickNextPtr;
OS_TCB *TickPrevPtr;
OS_TICK_SPOKE *TickSpokePtr; /* Pointer to tick spoke if task is in the tick list */
CPU_CHAR *NamePtr; /* Pointer to task name */
CPU_STK *StkBasePtr; /* Pointer to base address of stack */
OS_TASK_PTR TaskEntryAddr; /* Pointer to task entry point address */
void *TaskEntryArg; /* Argument passed to task when it was created */
OS_PEND_DATA *PendDataTblPtr; /* Pointer to list containing objects pended on */
OS_STATE PendOn; /* Indicates what task is pending on */
OS_STATUS PendStatus; /* Pend status */
OS_STATE TaskState; /* See OS_TASK_STATE_xxx */
OS_PRIO Prio; /* Task priority (0 == highest) */
CPU_STK_SIZE StkSize; /* Size of task stack (in number of stack elements) */
OS_OPT Opt; /* Task options as passed by OSTaskCreate() */
OS_OBJ_QTY PendDataTblEntries; /* Size of array of objects to pend on */
CPU_TS TS; /* Timestamp */
OS_SEM_CTR SemCtr; /* Task specific semaphore counter */
/* DELAY / TIMEOUT */
OS_TICK TickCtrPrev; /* Previous time when task was ready */
OS_TICK TickCtrMatch; /* Absolute time when task is going to be ready */
OS_TICK TickRemain; /* Number of ticks remaining for a match (updated at ... */
/* ... run-time by OS_StatTask() */
OS_TICK TimeQuanta;
OS_TICK TimeQuantaCtr;
#if OS_MSG_EN > 0u
void *MsgPtr; /* Message received */
OS_MSG_SIZE MsgSize;
#endif
#if OS_CFG_TASK_Q_EN > 0u
OS_MSG_Q MsgQ; /* Message queue associated with task */
#if OS_CFG_TASK_PROFILE_EN > 0u
CPU_TS MsgQPendTime; /* Time it took for signal to be received */
CPU_TS MsgQPendTimeMax; /* Max amount of time it took for signal to be received */
#endif
#endif
#if OS_CFG_TASK_REG_TBL_SIZE > 0u
OS_REG RegTbl[OS_CFG_TASK_REG_TBL_SIZE]; /* Task specific registers */
#endif
#if OS_CFG_FLAG_EN > 0u
OS_FLAGS FlagsPend; /* Event flag(s) to wait on */
OS_FLAGS FlagsRdy; /* Event flags that made task ready to run */
OS_OPT FlagsOpt; /* Options (See OS_OPT_FLAG_xxx) */
#endif
#if OS_CFG_TASK_SUSPEND_EN > 0u
OS_NESTING_CTR SuspendCtr; /* Nesting counter for OSTaskSuspend() */
#endif
#if OS_CFG_TASK_PROFILE_EN > 0u
OS_CPU_USAGE CPUUsage; /* CPU Usage of task (0-100%) */
OS_CTX_SW_CTR CtxSwCtr; /* Number of time the task was switched in */
CPU_TS CyclesDelta; /* value of OS_TS_GET() - .CyclesStart */
CPU_TS CyclesStart; /* Snapshot of cycle counter at start of task resumption */
OS_CYCLES CyclesTotal; /* Total number of # of cycles the task has been running */
OS_CYCLES CyclesTotalPrev; /* Snapshot of previous # of cycles */
CPU_TS SemPendTime; /* Time it took for signal to be received */
CPU_TS SemPendTimeMax; /* Max amount of time it took for signal to be received */
#endif
#if OS_CFG_STAT_TASK_STK_CHK_EN > 0u
CPU_STK_SIZE StkUsed; /* Number of stack elements used from the stack */
CPU_STK_SIZE StkFree; /* Number of stack elements free on the stack */
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN
CPU_TS IntDisTimeMax; /* Maximum interrupt disable time */
#endif
#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u
CPU_TS SchedLockTimeMax; /* Maximum scheduler lock time */
#endif
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
os.h
struct os_q {
OS_OBJ_TYPE Type; /* Message Queue */
CPU_CHAR *NamePtr; /* Should be set to OS_OBJ_TYPE_Q */
OS_PEND_LIST PendList; /* Pointer to Message Queue (NUL terminated ASCII) */
#if OS_CFG_DBG_EN > 0u
OS_Q *DbgPrevPtr;
OS_Q *DbgNextPtr;
CPU_CHAR *DbgNamePtr;
#endif
OS_MSG_Q MsgQ; /* List of tasks waiting on event flag group */
};
typedef struct os_msg_q OS_MSG_Q;
struct os_msg_q { /* OS_MSG_Q */
OS_MSG *InPtr; /* Pointer to next OS_MSG to be inserted in the queue */
OS_MSG *OutPtr; /* Pointer to next OS_MSG to be extracted from the queue */
OS_MSG_QTY NbrEntriesSize; /* Maximum allowable number of entries in the queue */
OS_MSG_QTY NbrEntries; /* Current number of entries in the queue */
OS_MSG_QTY NbrEntriesMax; /* Peak number of entries in the queue */
};
typedef struct os_msg OS_MSG;
struct os_msg { /* MESSAGE CONTROL BLOCK */
OS_MSG *NextPtr; /* Pointer to next message */
void *MsgPtr; /* Actual message */
OS_MSG_SIZE MsgSize; /* Size of the message (in # bytes) */
CPU_TS MsgTS; /* Time stamp of when message was sent */
};
struct os_msg_pool { /* OS_MSG POOL */
OS_MSG *NextPtr; /* Pointer to next message */
OS_MSG_QTY NbrFree; /* Number of messages available from this pool */
OS_MSG_QTY NbrUsed; /* Number of messages used */
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#if OS_CFG_TASK_Q_EN > 0u
os_task.c
OS_MSG_QTY OSTaskQFlush (OS_TCB *p_tcb, OS_ERR *p_err)
{
OS_MSG_QTY entries;
CPU_SR_ALLOC();
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Can't flush a message queue from an ISR */
*p_err = OS_ERR_FLUSH_ISR;
return ((OS_MSG_QTY)0);
}
#endif
if (p_tcb == (OS_TCB *)0) { /* Flush message queue of calling task? */
CPU_CRITICAL_ENTER();
p_tcb = OSTCBCurPtr;
CPU_CRITICAL_EXIT();
}
OS_CRITICAL_ENTER();
entries = OS_MsgQFreeAll(&p_tcb->MsgQ); /* Return all OS_MSGs to the OS_MSG pool */
OS_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
return (entries);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
************************************************************************************************************************
* RELEASE ALL MESSAGE IN MESSAGE QUEUE
*
* Description: This function returns all the messages in a message queue to the free list.
*
* Arguments : p_msg_q is a pointer to the OS_MSG_Q structure containing messages to free.
* -------
*
* Returns : the number of OS_MSGs returned to the free list
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
os_msg.c
OS_MSG_QTY OS_MsgQFreeAll (OS_MSG_Q *p_msg_q)
{
OS_MSG *p_msg;
OS_MSG_QTY qty;
qty = p_msg_q->NbrEntries; /* Get the number of OS_MSGs being freed */
if (p_msg_q->NbrEntries > (OS_MSG_QTY)0) {
p_msg = p_msg_q->InPtr; /* Point to end of message chain */
p_msg->NextPtr = OSMsgPool.NextPtr;
OSMsgPool.NextPtr = p_msg_q->OutPtr; /* Point to beginning of message chain */
OSMsgPool.NbrUsed -= p_msg_q->NbrEntries; /* Update statistics for free list of messages */
OSMsgPool.NbrFree += p_msg_q->NbrEntries;
p_msg_q->NbrEntries = (OS_MSG_QTY)0; /* Flush the message queue */
p_msg_q->NbrEntriesMax = (OS_MSG_QTY)0;
p_msg_q->InPtr = (OS_MSG *)0;
p_msg_q->OutPtr = (OS_MSG *)0;
}
return (qty);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
************************************************************************************************************************
* POST MESSAGE TO A TASK
*
* Description: This function sends a message to a task
*
* Arguments : p_tcb is a pointer to the TCB of the task receiving a message. If you specify a NULL pointer then
* the message will be posted to the task's queue of the calling task. In other words, you'd be
* posting a message to yourself.
*
* p_void is a pointer to the message to send.
*
* msg_size is the size of the message sent (in #bytes)
*
* opt specifies whether the post will be FIFO or LIFO:
*
* OS_OPT_POST_FIFO Post at the end of the queue
* OS_OPT_POST_LIFO Post at the front of the queue
*
* OS_OPT_POST_NO_SCHED Do not run the scheduler after the post
*
* Note(s): 1) OS_OPT_POST_NO_SCHED can be added with one of the other options.
*
*
* p_err is a pointer to a variable that will hold the error code associated
* with the outcome of this call. Errors can be:
*
* OS_ERR_NONE The call was successful and the message was sent
* OS_ERR_Q_MAX If the queue is full
* OS_ERR_MSG_POOL_EMPTY If there are no more OS_MSGs available from the pool
*
* Returns : none
************************************************************************************************************************
os_task.c
void OSTaskQPost (OS_TCB *p_tcb,
void *p_void,
OS_MSG_SIZE msg_size,
OS_OPT opt,
OS_ERR *p_err)
{
CPU_TS ts;
#ifdef OS_SAFETY_CRITICAL_RELEASE
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
}
#endif
ts = OS_TS_GET(); /* Get timestamp */
#if OS_CFG_ISR_POST_DEFERRED_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) {
OS_IntQPost((OS_OBJ_TYPE)OS_OBJ_TYPE_TASK_MSG, /* Post to ISR queue */
(void *)p_tcb,
(void *)p_void,
(OS_MSG_SIZE)msg_size,
(OS_FLAGS )0,
(OS_OPT )opt,
(CPU_TS )ts,
(OS_ERR *)p_err);
return;
}
#endif
OS_TaskQPost(p_tcb,
p_void,
msg_size,
opt,
ts,
p_err);
}
//////////////////
#define OS_OBJ_TYPE_NONE (OS_OBJ_TYPE)(0x454E4F4Eu) /* "NONE" in ASCII. */
#define OS_OBJ_TYPE_SEM (OS_OBJ_TYPE)(0x414D4553u) /* "SEMA" in ASCII. */
#define OS_OBJ_TYPE_Q (OS_OBJ_TYPE)(0x55455551u) /* "QUEU" in ASCII. */
#define OS_OBJ_TYPE_MUTEX (OS_OBJ_TYPE)(0x5854554Du) /* "MUTX" in ASCII. */
#define OS_OBJ_TYPE_FLAG (OS_OBJ_TYPE)(0x47414C46u) /* "FLAG" in ASCII. */
#define OS_OBJ_TYPE_TMR (OS_OBJ_TYPE)(0x524D2054u) /* "TMR " in ASCII. */
#define OS_OBJ_TYPE_TASK_MSG (OS_OBJ_TYPE)(0x47534D54u) /* "TMSG" in ASCII. */
#define OS_OBJ_TYPE_TASK_SIGNAL (OS_OBJ_TYPE)(0x47495354u) /* "TSIG" in ASCII. */
#define OS_OBJ_TYPE_TICK (OS_OBJ_TYPE)(0x4B434954u) /* "TICK" in ASCII.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
os_int.c
/*
************************************************************************************************************************
* POST TO ISR QUEUE
*
* Description: This function places contents of posts into an intermediate queue to help defer processing of interrupts
* at the task level.
*
* Arguments : type is the type of kernel object the post is destined to:
*
* OS_OBJ_TYPE_SEM
* OS_OBJ_TYPE_Q
* OS_OBJ_TYPE_FLAG
* OS_OBJ_TYPE_TASK_MSG
* OS_OBJ_TYPE_TASK_SIGNAL
*
* p_obj is a pointer to the kernel object to post to. This can be a pointer to a semaphore,
* ----- a message queue or a task control clock.
*
* p_void is a pointer to a message that is being posted. This is used when posting to a message
* queue or directly to a task.
*
* msg_size is the size of the message being posted
*
* flags if the post is done to an event flag group then this corresponds to the falgs being
* posted
*
* ts is a timestamp as to when the post was done
*
* opt this corresponds to post options and applies to:
*
* OSFlagPost()
* OSSemPost()
* OSQPost()
* OSTaskQPost()
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE if the post to the ISR queue was successful
* OS_ERR_INT)Q_FULL if the ISR queue is full and cannot accepts any further posts. This
* generally indicates that you are receiving interrupts faster than you
* can process them or, that you didn't make the ISR queue large enough.
*
* Returns : none
*
* Note(s) : none
************************************************************************************************************************
*/
void OS_IntQPost (OS_OBJ_TYPE type,
void *p_obj,
void *p_void,
OS_MSG_SIZE msg_size,
OS_FLAGS flags,
OS_OPT opt,
CPU_TS ts,
OS_ERR *p_err)
{
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL_RELEASE
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
}
#endif
CPU_CRITICAL_ENTER();
if (OSIntQNbrEntries < OSCfg_IntQSize) { /* Make sure we haven't already filled the ISR queue */
OSIntQNbrEntries++;
OSIntQInPtr->Type = type;
OSIntQInPtr->ObjPtr = p_obj;
OSIntQInPtr->MsgPtr = p_void;
OSIntQInPtr->MsgSize = msg_size;
OSIntQInPtr->Flags = flags;
OSIntQInPtr->Opt = opt;
OSIntQInPtr->TS = ts;
OSIntQInPtr = OSIntQInPtr->NextPtr;
OSRdyList[0].NbrEntries = (OS_OBJ_QTY)1; /* Add to ready list */
OSRdyList[0].HeadPtr = &OSIntQTaskTCB;
OSRdyList[0].TailPtr = &OSIntQTaskTCB;
OS_PrioInsert(0u); /* Add task priority 0 in the priority table */
OSPrioSaved = OSPrioCur; /* Save current priority */
*p_err = OS_ERR_NONE;
} else {
OSIntQOvfCtr++; /* Count the number of ISR queue overflows */
*p_err = OS_ERR_INT_Q_FULL;
}
CPU_CRITICAL_EXIT();
}
////////////////////////
OS_EXT OS_INT_Q *OSIntQInPtr;
OS_EXT OS_INT_Q *OSIntQOutPtr;
OS_EXT OS_OBJ_QTY OSIntQNbrEntries;
OS_EXT OS_OBJ_QTY OSIntQOvfCtr;
OS_EXT OS_TCB OSIntQTaskTCB;
OS_EXT CPU_TS OSIntQTaskTimeMax;
struct os_int_q {
OS_OBJ_TYPE Type;
OS_INT_Q *NextPtr;
void *ObjPtr;
void *MsgPtr;
OS_MSG_SIZE MsgSize;
OS_FLAGS Flags;
OS_OPT Opt;
CPU_TS TS;
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
os_task.c
/*
************************************************************************************************************************
* POST MESSAGE TO A TASK
*
* Description: This function sends a message to a task
*
* Arguments : p_tcb is a pointer to the TCB of the task receiving a message. If you specify a NULL pointer then
* the message will be posted to the task's queue of the calling task. In other words, you'd be
* posting a message to yourself.
*
* p_void is a pointer to the message to send.
*
* msg_size is the size of the message sent (in #bytes)
*
* opt specifies whether the post will be FIFO or LIFO:
*
* OS_OPT_POST_FIFO Post at the end of the queue
* OS_OPT_POST_LIFO Post at the front of the queue
*
* OS_OPT_POST_NO_SCHED Do not run the scheduler after the post
*
* Note(s): 1) OS_OPT_POST_NO_SCHED can be added with one of the other options.
*
*
* ts is a timestamp indicating when the post occurred.
*
* p_err is a pointer to a variable that will hold the error code associated
* with the outcome of this call. Errors can be:
*
* OS_ERR_NONE The call was successful and the message was sent
* OS_ERR_MSG_POOL_EMPTY If there are no more OS_MSGs available from the pool
* OS_ERR_Q_MAX If the queue is full
* OS_ERR_STATE_INVALID If the task is in an invalid state. This should never happen
* and if it does, would be considered a system failure.
*
* Returns : none
*
* Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
#if OS_CFG_TASK_Q_EN > 0u
void OS_TaskQPost (OS_TCB *p_tcb,
void *p_void,
OS_MSG_SIZE msg_size,
OS_OPT opt,
CPU_TS ts,
OS_ERR *p_err)
{
CPU_SR_ALLOC();
OS_CRITICAL_ENTER();
if (p_tcb == (OS_TCB *)0) { /* Post msg to 'self'? */
p_tcb = OSTCBCurPtr;
}
*p_err = OS_ERR_NONE; /* Assume we won't have any errors */
switch (p_tcb->TaskState) {
case OS_TASK_STATE_RDY:
case OS_TASK_STATE_DLY:
case OS_TASK_STATE_SUSPENDED:
case OS_TASK_STATE_DLY_SUSPENDED:
OS_MsgQPut(&p_tcb->MsgQ, /* Deposit the message in the queue */
p_void,
msg_size,
opt,
ts,
p_err);
OS_CRITICAL_EXIT();
break;
case OS_TASK_STATE_PEND:
case OS_TASK_STATE_PEND_TIMEOUT:
case OS_TASK_STATE_PEND_SUSPENDED:
case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
if (p_tcb->PendOn == OS_TASK_PEND_ON_TASK_Q) { /* Is task waiting for a message to be sent to it? */
OS_Post((OS_PEND_OBJ *)0,
p_tcb,
p_void,
msg_size,
ts);
OS_CRITICAL_EXIT_NO_SCHED();
if ((opt & OS_OPT_POST_NO_SCHED) == (OS_OPT)0) {
OSSched(); /* Run the scheduler */
}
} else {
OS_MsgQPut(&p_tcb->MsgQ, /* No, Task is pending on something else ... */
p_void, /* ... Deposit the message in the task's queue */
msg_size,
opt,
ts,
p_err);
OS_CRITICAL_EXIT();
}
break;
default:
OS_CRITICAL_EXIT();
*p_err = OS_ERR_STATE_INVALID;
break;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
------------------------------------------------------------------------------------------------------------------------
* PEND DATA, PEND LIST and PEND OBJ
------------------------------------------------------------------------------------------------------------------------
*/
struct os_pend_data {
OS_PEND_DATA *PrevPtr;
OS_PEND_DATA *NextPtr;
OS_TCB *TCBPtr;
OS_PEND_OBJ *PendObjPtr;
OS_PEND_OBJ *RdyObjPtr;
void *RdyMsgPtr;
OS_MSG_SIZE RdyMsgSize;
CPU_TS RdyTS;
};
struct os_pend_list {
OS_PEND_DATA *HeadPtr;
OS_PEND_DATA *TailPtr;
OS_OBJ_QTY NbrEntries;
};
struct os_pend_obj {
OS_OBJ_TYPE Type;
CPU_CHAR *NamePtr;
OS_PEND_LIST PendList; /* List of tasks pending on object */
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
************************************************************************************************************************
* BLOCK A TASK PENDING ON EVENT
*
* Description: This function is called to place a task in the blocked state waiting for an event to occur. This function
* exist because it is common to a number of OSxxxPend() services.
*
* 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 object.
* p_obj is a pointer to the object to pend on. If there are no object used to pend on then
* ----- the caller must pass a NULL pointer.
*
* pending_on Specifies what the task will be pending on:
*
* OS_TASK_PEND_ON_FLAG
* OS_TASK_PEND_ON_TASK_Q <- No object (pending for a message sent to the task)
* OS_TASK_PEND_ON_MUTEX
* OS_TASK_PEND_ON_Q
* OS_TASK_PEND_ON_SEM
* OS_TASK_PEND_ON_TASK_SEM <- No object (pending on a signal sent to the task)
*
* timeout Is the amount of time the task will wait for the event to occur.
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
os_core.c
void OS_Pend (OS_PEND_DATA *p_pend_data,
OS_PEND_OBJ *p_obj,
OS_STATE pending_on,
OS_TICK timeout)
{
OS_PEND_LIST *p_pend_list;
OSTCBCurPtr->PendOn = pending_on; /* Resource not available, wait until it is */
OSTCBCurPtr->PendStatus = OS_STATUS_PEND_OK;
OS_TaskBlock(OSTCBCurPtr, /* Block the task and add it to the tick list if needed */
timeout);
if (p_obj != (OS_PEND_OBJ *)0) { /* Add the current task to the pend list ... */
p_pend_list = &p_obj->PendList; /* ... if there is an object to pend on */
p_pend_data->PendObjPtr = p_obj; /* Save the pointer to the object pending on */
OS_PendDataInit((OS_TCB *)OSTCBCurPtr, /* Initialize the remaining field */
(OS_PEND_DATA *)p_pend_data,
(OS_OBJ_QTY )1);
OS_PendListInsertPrio(p_pend_list, /* Insert in the pend list in priority order */
p_pend_data);
} else {
OSTCBCurPtr->PendDataTblEntries = (OS_OBJ_QTY )0; /* If no object being pended on the clear these fields */
OSTCBCurPtr->PendDataTblPtr = (OS_PEND_DATA *)0; /* ... in the TCB */
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
************************************************************************************************************************
* POST TO A TASK
*
* Description: This function is called to post to a task. This function exist because it is common to a number of
* OSxxxPost() services.
*
* Arguments : p_obj Is a pointer to the object being posted to or NULL pointer if there is no object
* -----
*
* p_tcb Is a pointer to the OS_TCB that will receive the 'post'
* -----
*
* p_void If we are posting a message to a task, this is the message that the task will receive
*
* msg_size If we are posting a message to a task, this is the size of the message
*
* ts The timestamp as to when the post occurred
*
* Returns : none
*
* Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
os_core.c
void OS_Post (OS_PEND_OBJ *p_obj,
OS_TCB *p_tcb,
void *p_void,
OS_MSG_SIZE msg_size,
CPU_TS ts)
{
switch (p_tcb->TaskState) {
case OS_TASK_STATE_RDY: /* Cannot Pend Abort a task that is ready */
case OS_TASK_STATE_DLY: /* Cannot Pend Abort a task that is delayed */
case OS_TASK_STATE_SUSPENDED: /* Cannot Post a suspended task */
case OS_TASK_STATE_DLY_SUSPENDED: /* Cannot Post a suspended task that was also dly'd */
break;
case OS_TASK_STATE_PEND:
case OS_TASK_STATE_PEND_TIMEOUT:
if (p_tcb->PendOn == OS_TASK_PEND_ON_MULTI) {
OS_Post1(p_obj, /* Indicate which object was posted to */
p_tcb,
p_void,
msg_size,
ts);
} else {
p_tcb->MsgPtr = p_void; /* Deposit message in OS_TCB of task waiting */
p_tcb->MsgSize = msg_size; /* ... assuming posting a message */
p_tcb->TS = ts;
}
if (p_obj != (OS_PEND_OBJ *)0) {
OS_PendListRemove(p_tcb); /* Remove task from wait list(s) */
}
OS_TaskRdy(p_tcb); /* Make task ready to run */
p_tcb->TaskState = OS_TASK_STATE_RDY;
p_tcb->PendStatus = OS_STATUS_PEND_OK; /* Clear pend status */
p_tcb->PendOn = OS_TASK_PEND_ON_NOTHING; /* Indicate no longer pending */
break;
case OS_TASK_STATE_PEND_SUSPENDED:
case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
if (p_tcb->PendOn == OS_TASK_PEND_ON_MULTI) {
OS_Post1(p_obj, /* Indicate which object was posted to */
p_tcb,
p_void,
msg_size,
ts);
} else {
p_tcb->MsgPtr = p_void; /* Deposit message in OS_TCB of task waiting */
p_tcb->MsgSize = msg_size; /* ... assuming posting a message */
p_tcb->TS = ts;
}
OS_TickListRemove(p_tcb); /* Cancel any timeout */
if (p_obj != (OS_PEND_OBJ *)0) {
OS_PendListRemove(p_tcb); /* Remove task from wait list(s) */
}
p_tcb->TaskState = OS_TASK_STATE_SUSPENDED;
p_tcb->PendStatus = OS_STATUS_PEND_OK; /* Clear pend status */
p_tcb->PendOn = OS_TASK_PEND_ON_NOTHING; /* Indicate no longer pending */
break;
default:
break;
}
}
阅读(2713) | 评论(0) | 转发(0) |