typedef struct os_tcb
OS_TCB;
struct os_tcb {
CPU_STK *StkPtr; /* Pointer to current top of stack */
任务栈顶
void *ExtPtr; /* Pointer to user definable data for TCB extension */
用户自定义扩展TCB
CPU_STK *StkLimitPtr; /* Pointer used to set stack 'watermark' limit */
OS_TCB *NextPtr; /* Pointer to next TCB in the TCB list */
Ready List
OS_TCB *PrevPtr; /* Pointer to previous TCB in the TCB list */
Ready List
OS_TCB *TickNextPtr; //
Tick List
OS_TCB *TickPrevPtr; //
Tick List
OS_TICK_SPOKE *TickSpokePtr; /* Pointer to tick spoke if task is in the tick list */
指回到TCB所在的spoke的地址
CPU_CHAR *NamePtr; /* Pointer to task name */
任务名称
CPU_STK *StkBasePtr; /* Pointer to base address of stack */
栈底
#if defined(OS_CFG_TLS_TBL_SIZE) && (OS_CFG_TLS_TBL_SIZE > 0u)
OS_TLS TLS_Tbl[OS_CFG_TLS_TBL_SIZE];
#endif
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 */
配合PendDataTblPtr,等待多少个对象
CPU_TS TS; /* Timestamp */
时间戳
OS_SEM_CTR SemCtr; /* Task specific semaphore counter */
任务自己的Sem
/* 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 */
任务接收到Msg的指针
OS_MSG_SIZE MsgSize;
#endif
#if OS_CFG_TASK_Q_EN > 0u
OS_MSG_Q MsgQ; /* Message queue associated with task */
任务内建的Queue
#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 //
任务内建的Flag
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.00-100.00%) */
OS_CPU_USAGE CPUUsageMax; /* CPU Usage of task (0.00-100.00%) - Peak */
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
#if OS_CFG_DBG_EN > 0u
OS_TCB *DbgPrevPtr;
OS_TCB *DbgNextPtr;
CPU_CHAR *DbgNamePtr;
#endif
};
OS_TASK_PEND_ON_NOTHING
OS_TASK_PEND_ON_FLAG
OS_TASK_PEND_ON_TASK_Q
OS_TASK_PEND_ON_MULTI
OS_TASK_PEND_ON_MUTEX
OS_TASK_PEND_ON_Q
OS_TASK_PEND_ON_SEM
OS_TASK_PEND_ON_TASK_SEM
OS_STATUS_PEND_OK
OS_STATUS_PEND_ABORT
OS_STATUS_PEND_DEL
OS_STATUS_PEND_TIMEOUT
OS_TASK_STATE_RDY
OS_TASK_STATE_DLY
OS_TASK_STATE_PEND
OS_TASK_STATE_PEND_TIMEOUT
OS_TASK_STATE_SUSPENDED
OS_TASK_STATE_DLY_SUSPENDED
OS_TASK_STATE_PEND_SUSPENDED
OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED
任务使用的
堆栈大小可以由(所有调用方法、局部变量、CPU上下文等等)计算出来,尽量大些(在这个地方吃过亏...)。
void OSTaskChangePrio (OS_TCB
*p_tcb,
OS_PRIO prio_new,
OS_ERR *p_err):
动态修改任务优先级。
判断
p_tcb->TaskState:
如果
OS_TASK_STATE_RDY,将任务从RdyList中移除,设置新的优先级,设置bitmap,重新插入到RdyList中。
如果
OS_TASK_STATE_DLY、
OS_TASK_STATE_SUSPENDED、
OS_TASK_STATE_DLY_SUSPENDED,直接设置新的优先级。
如果
OS_TASK_STATE_PEND、
OS_TASK_STATE_PEND_TIMEOUT、
OS_TASK_STATE_PEND_SUSPENDED、
OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED,根据p_tcb->PendOn设置新的优先级。
启动调度器。
void OSTaskCreate (OS_TCB
*p_tcb,
CPU_CHAR *p_name,
OS_TASK_PTR p_task,
void *p_arg,
OS_PRIO prio,
CPU_STK *p_stk_base,
CPU_STK_SIZE stk_limit,
CPU_STK_SIZE stk_size,
OS_MSG_QTY q_size,
OS_TICK time_quanta,
void *p_ext,
OS_OPT opt,
OS_ERR *p_err):
创建一个任务。
初始化清空TCB,清空任务堆栈,初始化堆栈格式,设置TCB的值,初始化任务Queue,呼叫钩子函数,将任务添加到RdyList中,如果系统启动则启动调度。
void OSTaskDel (OS_TCB
*p_tcb,
OS_ERR *p_err):
删除一个任务。
根据任务状态,将p_tcb从RdyList,TickList,PendList中删除,释放Queue中的所有OS_MSG,调用钩子函数,清空TCB,
p_tcb->TaskState = (OS_STATE)OS_TASK_STATE_DEL;,启动调度。
OS_MSG_QTY OSTaskQFlush (OS_TCB *p_
tcb,
OS_ERR *p_err):
释放p_tcb内建Queue中的所有OS_MSG回
OSMsgPool
。
这个函数调用的时候一定要注意(如果OS_MSG执行的是一个内存块,一定要释放的!!!),个人觉得还是不要调用的好。
void *OSTaskQPend (OS_TICK timeout,
OS_OPT opt,
OS_MSG_SIZE *p_msg_size,
CPU_TS *p_ts,
OS_ERR *p_err):
当前任务等待一个message。
从
OSTCBCurPtr->MsgQ中获取是否有message,如果有则返回message指针,否则调用OS_Pend(),启动调度器切换到别的任务执行,任务被再次唤醒时在此继续往下运行---->
---->判断
OSTCBCurPtr->PendStatus:
如果
OS_STATUS_PEND_OK,从
OSTCBCurPtr中获取MsgPtr、MsgSize。
如果
OS_STATUS_PEND_ABORT、
OS_STATUS_PEND_TIMEOUT
,设置
MsgPtr、MsgSize为空,并设置错误代码。
CPU_BOOLEAN OSTaskQPendAbort (OS_TCB *p_tcb,
OS_OPT opt,
OS_ERR *p_err):
终止任务Queue的等待。
调用
OS_PendAbort(),根据opt是否启动调度。
void OSTaskQPost (OS_TCB *p_tcb,
void *p_void,
OS_MSG_SIZE msg_size,
OS_OPT opt,
OS_ERR *p_err):
Post一个message到p_tcbQueue中。
如果
OS_CFG_ISR_POST_DEFERRED_EN>0&&
OSIntNestingCtr>0,调用
OS_IntQPost()(Post到ISR Queue~
OS_OBJ_TYPE_TASK_MSG
),否则调用
OS_TaskQPost()。
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):
Post一个message给p_tcb,OS内部函数。
判断
p_tcb->TaskState:
如果
OS_TASK_STATE_RDY、
OS_TASK_STATE_DLY、
OS_TASK_STATE_SUSPENDED、
OS_TASK_STATE_DLY_SUSPENDED,将message存到queue中。
如果
OS_TASK_STATE_PEND、
OS_TASK_STATE_PEND_TIMEOUT、
OS_TASK_STATE_PEND_SUSPENDED、
OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED,判断任务是否在等待
OS_TASK_PEND_ON_TASK_Q,是调用OS_Post(),根据是否挂起启动调度器,否任务在等待别的对象,将message存到queue中。
void OSTaskResume (OS_TCB *p_tcb,
OS_ERR *p_err):
恢复一个挂起的任务。
如果
OS_CFG_ISR_POST_DEFERRED_EN==0,不允许在中断中调用,调用OS_TaskResum();
如果OS_CFG_ISR_POST_DEFERRED_EN==1,可以在中断中调用,调用
OS_IntQPost(
) (Post到ISR Queue~OS_OBJ_TYPE_TASK_RESUME);
void OS_TaskResume (OS_TCB *p_tcb,
OS_ERR *p_err):
恢复一个挂起的任务,OS内部函数。
判断
p_tcb->TaskState:
如果
OS_TASK_STATE_RDY、
OS_TASK_STATE_DLY、OS_TASK_STATE_PEND、OS_TASK_STATE_PEND_TIMEOUT
,任务没有被挂起。
如果OS_TASK_STATE_SUSPENDED,
p_tcb->SuspendCtr--,如果
p_tcb->SuspendCtr==0,将任务放到RdyList中。
如果OS_TASK_STATE_DLY_SUSPENDED、OS_TASK_STATE_PEND_SUSPENDED、OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED
,p_tcb->SuspendCtr--,如果p_tcb->SuspendCtr==0,更新
p_tcb->TaskState。
OS_SEM_CTR OSTaskSemPend (OS_TICK timeout,
OS_OPT opt,
CPU_TS *p_ts,
OS_ERR *p_err):
当前任务等待一个Sem。
查看当前Sem是否已经被标志,是
OSTCBCurPtr->SemCtr--,任务继续执行,否调用OS_Pend(),启动调度器
切换到别的任务执行,任务被再次唤醒时在此继续往下运行---->
---->判断
OSTCBCurPtr->PendStatus:
如果
OS_STATUS_PEND_OK,
*p_err = OS_ERR_NONE,返回继续执行
。
如果
OS_STATUS_PEND_ABORT、
OS_STATUS_PEND_TIMEOUT,设置错误代码。
CPU_BOOLEAN OSTaskSemPendAbort (OS_TCB *p_tcb,
OS_OPT opt,
OS_ERR *p_err):
终止任务Sem的等待。
调用OS_PendAbort(),根据opt是否启动调度。
OS_SEM_CTR OSTaskSemPost (OS_TCB *p_tcb,
OS_OPT opt,
OS_ERR *p_err):
Post任务Sem。
如果OS_CFG_ISR_POST_DEFERRED_EN>0&&OSIntNestingCtr>0,调用OS_IntQPost()(Post到ISR Queue~
OS_OBJ_TYPE_TASK_SIGNAL
),否则调用
OS_TaskSemPost
()。
OS_SEM_CTR OS_TaskSemPost (OS_TCB *p_tcb,
OS_OPT opt,
CPU_TS ts,
OS_ERR *p_err):
Post任务Sem,OS内部函数。
判断
p_tcb->TaskState:
如果
OS_TASK_STATE_RDY、
OS_TASK_STATE_DLY、
OS_TASK_STATE_SUSPENDED、
OS_TASK_STATE_DLY_SUSPENDED,
p_tcb->SemCtr++
。
如果
OS_TASK_STATE_PEND、
OS_TASK_STATE_PEND_TIMEOUT、
OS_TASK_STATE_PEND_SUSPENDED、
OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED,判断任务是否在等待
OS_TASK_PEND_ON_TASK_SEM
,是调用OS_Post(),根据是否挂起启动调度器,否任务在等待别的对象,p_tcb->SemCtr++。
OS_SEM_CTR OSTaskSemSet (OS_TCB *p_tcb,
OS_SEM_CTR cnt,
OS_ERR *p_err):
设置Sem的值,系统未调用。
void OSTaskStkChk (OS_TCB *p_tcb,
CPU_STK_SIZE *p_free,
CPU_STK_SIZE *p_used,
OS_ERR *p_err):
检查p_tcb堆栈的使用量和剩余量,在
OS_StatTask()中调用。
void OSTaskSuspend (OS_TCB *p_tcb,
OS_ERR *p_err):
挂起一个任务。
如果
OS_CFG_ISR_POST_DEFERRED_EN==0,不允许在中断中调用,调用
OS_TaskSuspend
();
如果OS_CFG_ISR_POST_DEFERRED_EN==1,可以在中断中调用,调用
OS_IntQPost(
) (Post到ISR Queue~
OS_OBJ_TYPE_TASK_SUSPEND
);
void OS_TaskSuspend (OS_TCB *p_tcb,
OS_ERR *p_err):
挂起一个任务,OS内部函数。
判断p_tcb->TaskState:
如果
OS_TASK_STATE_RDY、
OS_TASK_STATE_DLY、OS_TASK_STATE_PEND、OS_TASK_STATE_PEND_TIMEOUT
,p_tcb->SuspendCtr=1,设置
p_tcb->TaskState
。
如果OS_TASK_STATE_SUSPENDED、OS_TASK_STATE_DLY_SUSPENDED、OS_TASK_STATE_PEND_SUSPENDED、OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED
,p_tcb->SuspendCtr++
。
void OSTaskTimeQuantaSet (OS_TCB *p_tcb,
OS_TICK time_quanta,
OS_ERR *p_err):
设置任务的时间片,系统未调用。
void OS_TaskInit (OS_ERR *p_err):
任务初始化,OSInit()调用,设置
OSTaskQty、
OSTaskCtxSwCtr。
void OS_TaskInitTCB (OS_TCB *p_tcb):
初始化任务TCB为默认值。