os_task.c

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
};


.PendOn
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

.PendStatus(OS***Pend()任务被唤醒后查看状态)
OS_STATUS_PEND_OK
OS_STATUS_PEND_ABORT
OS_STATUS_PEND_DEL
OS_STATUS_PEND_TIMEOUT

.TaskState
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  OSTaskDe(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为默认值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值