您的位置:首页 > 其它

os_tick.c

2016-02-21 18:50 295 查看
typedef  struct  os_tick_spoke       OS_TICK_SPOKE;

struct  os_tick_spoke {
    OS_TCB              *FirstPtr;                          /* Pointer to list of tasks in tick spoke                 */
    OS_OBJ_QTY           NbrEntries;                        /* Current number of entries in the tick spoke            */
    OS_OBJ_QTY           NbrEntriesMax;                     /* Peak number of entries in the tick spoke               */
};



void  OS_TickTask (void  *p_arg):

    OS的内部任务,用于跟踪任务等待超时,有超时的内核对象。
    等待tick ISR信号(Sem,在OSTimeTick中发出),调用OS_TickListUpdate();

void  OS_TickTaskInit (OS_ERR  *p_err):

    OSInit() 调用。初始化OSTickCtr、OSTickTaskTimeMax()、OSCfg_TickWheel[],并创建OS_TickTask任务。



void  OS_TickListInit (void):

    将OSCfg_TickWheel[] 初始化成如上图所示。



void  OS_TickListInsert (OS_TCB   *p_tcb,
                         OS_TICK   time,
                         OS_OPT    opt,
                         OS_ERR   *p_err):

    将一个任务放入到Tick List中。
    当使用OS_OPT_TIME_MATCH模式时:如果(time-OSTickCtr-1) > OS_TICK_TH_RDY(4294901760
 0xFFFF0000),错误(这个地方不是太明白,应该是防止时间太长吧)
    设置p_tcb的TickCtrMatch、TickRemain,计算出要放入的p_spoke,将p_tcb插入到TickList中。p_tcb->TickSpokePtr = p_spoke;
    
    OS_OPT_TIME_DLY:直接将当前的OSTickCtr+dly,系统超载可能导致2次任务唤醒时的tick差>dly
    OS_OPT_TIME_PERIODIC:确保相邻2次唤醒时的tick的差相同。判断OSTCBCurPtr->TickCtrPrev+dly得到下一个唤醒时tick,如果这个tick还没有发生则使用这个,如果这个tick已经发生过了,使用OSTickCtr+dly重新开始。
    OS_OPT_TIME_MATCH:当系统启动后,在一个固定的时间点执行操作。
    如果CPU不超载的话,使用OS_OPT_TIME_DLY和OS_OPT_TIME_PERIODIC是相同的。如果超载的话,OS_OPT_TIME_DLY可能导致2次任务唤醒时的tick差>dly,OS_OPT_TIME_DLY可以在一定程度上避免这个情况(超载的时间超过了dly,则使用OSTickCtr + time重新开始)
    


    上图中,如果框内的任务由于系统超载,应该在1调用,直到2才调用,会使用OSTickCtr+dly重新开始,导致1任务与前一个任务的dly为8tick。
    

void  OS_TickListRemove (OS_TCB  *p_tcb):

    从TickList中删除p_tcb。
    如果p_tcb指向了p_spoke,则设置p_tcb的TickRemain、TickNextPtr、TickPrevPtr、TickSpokePtr、TickCtrMatch。

void  OS_TickListResetPeak (void):

    跟踪当前spoke最大的个数。在OSStatReset()中调用。

void  OS_TickListUpdate (void):

    当一个Tick发生时调用。OS_TickTask中调用。
    根据当前OSTickCtr获取p_spoke,遍历p_spoke指向的TickList。
    判断p_tcb->TaskState:
    如果OS_TASK_STATE_DLY:更新p_tcb->TickRemain,判断当前OSTickCtr==p_tcb->TickCtrMatch,更新p_tcb->TaskState,将p_tcb从TickList中删除,将p_tcb添加的ready_list中。否则跳出循环。
    如果OS_TASK_STATE_PEND_TIMEOUT:更新p_tcb->TickRemain,判断当前OSTickCtr==p_tcb->TickCtrMatch,更新p_tcb->TaskState、MsgPtr、MsgSize、TS、PendStatus、PendOn,将p_tcb从等待任务队列中删除,将p_tcb从TickList中删除,将p_tcb添加的ready_list中。否则跳出循环。

    如果OS_TASK_STATE_DLY_SUSPENDED:更新p_tcb->TickRemain,判断当前OSTickCtr==p_tcb->TickCtrMatch,更新p_tcb->TaskState,将p_tcb从TickList中删除。否则跳出循环。
    如果OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:更新p_tcb->TickRemain,判断当前OSTickCtr==p_tcb->TickCtrMatch,更新p_tcb->TaskState、MsgPtr、MsgSize、TS、PendStatus、PendOn,将p_tcb从等待任务队列中删除,将p_tcb从TickList中删除。否则跳出循环。
    最后更新OSTickTaskTimeMax(Tick Task的最大处理时间)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: