【 uC/OS II 】uC/OS II 源代码阅读(os_tmr.c)定时器管理

前言

这个关于定时器的,我感觉也没啥,核心就是它的轮子罢了,然后核心结构体,如下:

typedef  struct  os_tmr {
    INT8U            OSTmrType;             /* Should be set to OS_TMR_TYPE                            */
    OS_TMR_CALLBACK  OSTmrCallback;         /* Function to call when timer expires                     */
    void            *OSTmrCallbackArg;      /* Argument to pass to function when timer expires         */
    void            *OSTmrNext;             /* Double link list pointers                               */
    void            *OSTmrPrev;
    INT32U           OSTmrMatch;            /* Timer expires when OSTmrTime == OSTmrMatch              */
    INT32U           OSTmrDly;              /* Delay time before periodic update starts                */
    INT32U           OSTmrPeriod;           /* Period to repeat timer                                  */
#if OS_TMR_CFG_NAME_EN > 0u
    INT8U           *OSTmrName;             /* Name to give the timer                                  */
#endif
    INT8U            OSTmrOpt;              /* Options (see OS_TMR_OPT_xxx)                            */
    INT8U            OSTmrState;            /* Indicates the state of the timer:                       */
                                            /*     OS_TMR_STATE_UNUSED                                 */
                                            /*     OS_TMR_STATE_RUNNING                                */
                                            /*     OS_TMR_STATE_STOPPED                                */
} OS_TMR;
/*定时器管理(已看完)
*********************************************************************************************************
*                                                uC/OS-II
*                                          The Real-Time Kernel
*                                            TIMER MANAGEMENT
*
*                           (c) Copyright 1992-2017; Micrium, Inc.; Weston; FL
*                                           All Rights Reserved
*
* File    : OS_TMR.C
* By      : Jean J. Labrosse
* Version : V2.92.13
*
* LICENSING TERMS:
* ---------------
*   uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
* If you plan on using  uC/OS-II  in a commercial product you need to contact Micrium to properly license
* its use in your product. We provide ALL the source code for your convenience and to help you experience
* uC/OS-II.   The fact that the  source is provided does  NOT  mean that you can use it without  paying a
* licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the embedded community with the finest software available.
* Your honesty is greatly appreciated.
*
* You can find our product's user manual, API reference, release notes and
* more information at https://doc.micrium.com.
* You can contact us at www.micrium.com.
*********************************************************************************************************
*/

#define  MICRIUM_SOURCE

#ifndef  OS_MASTER_FILE
#include <ucos_ii.h>//引入头文件
#endif

/*
*********************************************************************************************************
*                                                        NOTES(注意)
*
* 1) Your application MUST define the following #define constants:
*你的应用程序必须定义下面两种宏定义常量
*    OS_TASK_TMR_PRIO          The priority of the Timer management task
*                               定时器管理任务的优先级
*    OS_TASK_TMR_STK_SIZE      The size of the Timer management task's stack
*                               定时器管理任务的堆栈的大小
* 2) You must call OSTmrSignal() to notify the Timer management task that it's time to update the timers.
您必须调用OSTmrSignal()来通知计时器管理任务该更新计时器了。
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                              CONSTANTS(常量)
*********************************************************************************************************
*/

//宏定义常量
#define  OS_TMR_LINK_DLY       0u
#define  OS_TMR_LINK_PERIODIC  1u

/*
*********************************************************************************************************
*                                          LOCAL PROTOTYPES(本地的原型声明)
*********************************************************************************************************
*/

//是否允许定时器
#if OS_TMR_EN > 0u
//定义本地函数
static  OS_TMR  *OSTmr_Alloc         (void);
static  void     OSTmr_Free          (OS_TMR *ptmr);
static  void     OSTmr_InitTask      (void);
static  void     OSTmr_Link          (OS_TMR *ptmr, INT8U type);
static  void     OSTmr_Unlink        (OS_TMR *ptmr);
static  void     OSTmr_Task          (void   *p_arg);
#endif


/*
*********************************************************************************************************
*                                           CREATE A TIMER(创建一个定时器)
*
* Description: This function is called by your application code to create a timer.
*你的应用程序调用此函数来创建一个定时器
* Arguments  : dly           Initial delay.初始化的延迟时间
*                            If the timer is configured for ONE-SHOT mode, this is the timeout used.
*                            If the timer is configured for PERIODIC mode, this is the first timeout to
*                               wait for before the timer starts entering periodic mode.
*                           如果定时器配置为一次性模式,这是使用的超时。如果定时器配置为周期模式,这是在定时器开始进入周期模式之前等待的第一个超时。
*
*              period        The 'period' being repeated for the timer.
*                               If you specified 'OS_TMR_OPT_PERIODIC' as an option, when the timer
*                               expires, it will automatically restart with the same period.
*                           定时器重复的周期时长,如果你配置了OS_TMR_OPT_PERIODIC,当这个定时器失效的时候,会自动重启相同的周期
*
*              opt           Specifies either://选择定时器模式
*                               OS_TMR_OPT_ONE_SHOT       The timer counts down only once 定时器仅仅进行一次定时
*                               OS_TMR_OPT_PERIODIC       The timer counts down and then reloads itself 定时器会循环进行
*
*              callback      Is a pointer to a callback function that will be called when the timer expires.
*                               The callback function must be declared as follows:
*                           指向回调函数的指针,这个回调函数会在定时器失效的时候被调用,这个回调函数必须按照如下形式声明:
*                               void MyCallback (OS_TMR *ptmr, void *p_arg);
*
*              callback_arg  Is an argument (a pointer) that is passed to the callback function when it is called.
*                           这是一个参数,当调用回调函数的时候传递的参数
*              pname         Is a pointer to an ASCII string that is used to name the timer.  Names are
*                               useful for debugging.
*                           指向字符串的指针,用来给定时器命名,名字在debug的时候仍然可用
*              perr          Is a pointer to an error code.  '*perr' will contain one of the following:
*                               OS_ERR_NONE                     the call was successful and the timer
*                                                               was created.
*                               OS_ERR_ILLEGAL_CREATE_RUN_TIME  if you tried to create a timer after
*                                                               safety critical operation started.
*                               OS_ERR_TMR_INVALID_DLY          you specified an invalid delay
*                               OS_ERR_TMR_INVALID_PERIOD       you specified an invalid period
*                               OS_ERR_TMR_INVALID_OPT          you specified an invalid option
*                               OS_ERR_TMR_ISR                  if the call was made from an ISR
*                               OS_ERR_TMR_NON_AVAIL            if there are no free timers from the timer pool
*
* Returns    : A pointer to an OS_TMR data structure.
*              This is the 'handle' that your application will use to reference the timer created.
*返回:返回指向定时器结构的指针,这个指针是应用程序用来访问创建的定时器的句柄
*********************************************************************************************************
*/

#if OS_TMR_EN > 0u
OS_TMR  *OSTmrCreate (INT32U           dly,
                      INT32U           period,
                      INT8U            opt,
                      OS_TMR_CALLBACK  callback,
                      void            *callback_arg,
                      INT8U           *pname,
                      INT8U           *perr)
{
    OS_TMR   *ptmr;


#ifdef OS_SAFETY_CRITICAL
    if (perr == (INT8U *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return ((OS_TMR *)0);
    }
#endif

#ifdef OS_SAFETY_CRITICAL_IEC61508
    if (OSSafetyCriticalStartFlag == OS_TRUE) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        *perr = OS_ERR_ILLEGAL_CREATE_RUN_TIME;
        return ((OS_TMR *)0);
    }
#endif

//参数检查
#if OS_ARG_CHK_EN > 0u
    //根据传入的opt进行参数检查
    switch (opt) {                                          /* Validate arguments                                     */
        //周期型定时器
        case OS_TMR_OPT_PERIODIC:
             if (period == 0u) {
                 *perr = OS_ERR_TMR_INVALID_PERIOD;
                 return ((OS_TMR *)0);
             }
             break;
        //一次性定时器
        case OS_TMR_OPT_ONE_SHOT:
             if (dly == 0u) {
                 *perr = OS_ERR_TMR_INVALID_DLY;
                 return ((OS_TMR *)0);
             }
             break;
        //无效opt参数
        default:
             *perr = OS_ERR_TMR_INVALID_OPT;
             return ((OS_TMR *)0);
    }
#endif
    if (OSIntNesting > 0u) {                                /* See if trying to call from an ISR                      */
        *perr  = OS_ERR_TMR_ISR;
        return ((OS_TMR *)0);
    }
    OSSchedLock();//调度器上锁,禁止进行任务调度
    //从timer pool中获得一个定时器控制块
    ptmr = OSTmr_Alloc();                                   /* Obtain a timer from the free pool                      */
    //检查是否正确获得
    if (ptmr == (OS_TMR *)0) {
        OSSchedUnlock();//调度器解锁
        *perr = OS_ERR_TMR_NON_AVAIL;
        //无有效控制块
        return ((OS_TMR *)0);
    }

    ptmr->OSTmrState       = OS_TMR_STATE_STOPPED;          /* Indicate that timer is not running yet                 */
    ptmr->OSTmrDly         = dly;
    ptmr->OSTmrPeriod      = period;
    ptmr->OSTmrOpt         = opt;
    ptmr->OSTmrCallback    = callback;
    ptmr->OSTmrCallbackArg = callback_arg;
#if OS_TMR_CFG_NAME_EN > 0u
    if (pname == (INT8U *)0) {                              /* Is 'pname' a NULL pointer?                             */
        ptmr->OSTmrName    = (INT8U *)(void *)"?";
    } else {
        ptmr->OSTmrName    = pname;
    }
#endif
    OSSchedUnlock();
    OS_TRACE_TMR_CREATE(ptmr, ptmr->OSTmrName);
    *perr = OS_ERR_NONE;
    return (ptmr);
}
#endif


/*
*********************************************************************************************************
*                                           DELETE A TIMER (删除一个定时器)
*
* Description: This function is called by your application code to delete a timer.
*这个函数被你的应用程序调用,用来删除一个定时器
* Arguments  : ptmr          Is a pointer to the timer to stop and delete.
*                           指向被删除或者停止的定时器的指针
*              perr          Is a pointer to an error code.  '*perr' will contain one of the following:
*                               OS_ERR_NONE                  the call was successful and the timer
*                                                            was deleted.
*                               OS_ERR_ILLEGAL_DEL_RUN_TIME  if you tried to delete a timer after safety
*                                                            critical operation started.
*                               OS_ERR_TMR_INVALID           'ptmr'  is a NULL pointer
*                               OS_ERR_TMR_INVALID_TYPE      'ptmr'  is not pointing to an OS_TMR
*                               OS_ERR_TMR_ISR               if the function was called from an ISR
*                               OS_ERR_TMR_INACTIVE          if the timer was not created
*                               OS_ERR_TMR_INVALID_STATE     the timer is in an invalid state
*
* Returns    : OS_TRUE       If the call was successful
*              OS_FALSE      If not
*********************************************************************************************************
*/

#if OS_TMR_EN > 0u
BOOLEAN  OSTmrDel (OS_TMR  *ptmr,
                   INT8U   *perr)
{
#ifdef OS_SAFETY_CRITICAL
    if (perr == (INT8U *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return (OS_FALSE);
    }
#endif

#ifdef OS_SAFETY_CRITICAL_IEC61508
    if (OSSafetyCriticalStartFlag == OS_TRUE) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        *perr = OS_ERR_ILLEGAL_DEL_RUN_TIME;
        return (OS_FALSE);
    }
#endif

//参数检查
#if OS_ARG_CHK_EN > 0u
    if (ptmr == (OS_TMR *)0) {
        *perr = OS_ERR_TMR_INVALID;
        return (OS_FALSE);
    }
#endif

    OS_TRACE_TMR_DEL_ENTER(ptmr);
    //检查传过来的指针是否指向定时器结构体
    if (ptmr->OSTmrType != OS_TMR_TYPE) {                   /* Validate timer structure                               */
        *perr = OS_ERR_TMR_INVALID_TYPE;
        OS_TRACE_TMR_DEL_EXIT(*perr);
        return (OS_FALSE);
    }
    //ISR中禁止调用此函数
    if (OSIntNesting > 0u) {                                /* See if trying to call from an ISR                      */
        *perr  = OS_ERR_TMR_ISR;
        OS_TRACE_TMR_DEL_EXIT(*perr);
        return (OS_FALSE);
    }
    OSSchedLock();//调度器上锁
    switch (ptmr->OSTmrState) {
        //当前定时器正处于运行状态
        case OS_TMR_STATE_RUNNING:
        //从轮子中摘除定时器
             OSTmr_Unlink(ptmr);                            /* Remove from current wheel spoke                        */
        //释放定时器的资源
             OSTmr_Free(ptmr);                              /* Return timer to free list of timers                    */
        //调度器解锁
             OSSchedUnlock();
             *perr = OS_ERR_NONE;
             OS_TRACE_TMR_DEL_EXIT(*perr);
             return (OS_TRUE);
        //当定时器处于停止状态,完成状态,直接释放资源
        case OS_TMR_STATE_STOPPED:                          /* Timer has not started or ...                           */
        case OS_TMR_STATE_COMPLETED:                        /* ... timer has completed the ONE-SHOT time              */
             OSTmr_Free(ptmr);                              /* Return timer to free list of timers                    */
             OSSchedUnlock();
             *perr = OS_ERR_NONE;
             OS_TRACE_TMR_DEL_EXIT(*perr);
             return (OS_TRUE);
        //当定时器处于未使用状态,即此时timer在timer pool中,不需要释放资源
        case OS_TMR_STATE_UNUSED:                           /* Already deleted                                        */
             OSSchedUnlock();
             *perr = OS_ERR_TMR_INACTIVE;
             OS_TRACE_TMR_DEL_EXIT(*perr);
             return (OS_FALSE);

        default:
             OSSchedUnlock();
             *perr = OS_ERR_TMR_INVALID_STATE;
             OS_TRACE_TMR_DEL_EXIT(*perr);
             return (OS_FALSE);
    }
}
#endif


/*
*********************************************************************************************************
*                                       GET THE NAME OF A TIMER (获取定时器的名字)
*
* Description: This function is called to obtain the name of a timer.
*这个函数用来获取定时器的名字
* Arguments  : ptmr          Is a pointer to the timer to obtain the name for
*指向定时器控制块的指针
*              pdest         Is a pointer to pointer to where the name of the timer will be placed.
*指向控制块名字需要存放的地址
*              perr          Is a pointer to an error code.  '*perr' will contain one of the following:
*                               OS_ERR_NONE               The call was successful
*                               OS_ERR_TMR_INVALID_DEST   'pdest' is a NULL pointer
*                               OS_ERR_TMR_INVALID        'ptmr'  is a NULL pointer
*                               OS_ERR_TMR_INVALID_TYPE   'ptmr'  is not pointing to an OS_TMR
*                               OS_ERR_NAME_GET_ISR       if the call was made from an ISR
*                               OS_ERR_TMR_INACTIVE       'ptmr'  points to a timer that is not active
*                               OS_ERR_TMR_INVALID_STATE  the timer is in an invalid state
*
* Returns    : The length of the string or 0 if the timer does not exist.
返回名字的长度
*********************************************************************************************************
*/

#if OS_TMR_EN > 0u && OS_TMR_CFG_NAME_EN > 0u
INT8U  OSTmrNameGet (OS_TMR   *ptmr,
                     INT8U   **pdest,
                     INT8U    *perr)
{
    INT8U  len;


#ifdef OS_SAFETY_CRITICAL
    if (perr == (INT8U *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return (0u);
    }
#endif

//参数检查
#if OS_ARG_CHK_EN > 0u
    if (pdest == (INT8U **)0) {
        *perr = OS_ERR_TMR_INVALID_DEST;
        return (0u);
    }
    if (ptmr == (OS_TMR *)0) {
        *perr = OS_ERR_TMR_INVALID;
        return (0u);
    }
#endif
    //检查是否为定时器类型
    if (ptmr->OSTmrType != OS_TMR_TYPE) {              /* Validate timer structure                                    */
        *perr = OS_ERR_TMR_INVALID_TYPE;
        return (0u);
    }
    if (OSIntNesting > 0u) {                           /* See if trying to call from an ISR                           */
        *perr = OS_ERR_NAME_GET_ISR;
        return (0u);
    }
    //调度器上锁
    OSSchedLock();
    switch (ptmr->OSTmrState) {
        //如果已经有了定时器实例,则直接获取
        case OS_TMR_STATE_RUNNING:
        case OS_TMR_STATE_STOPPED:
        case OS_TMR_STATE_COMPLETED:
             *pdest = ptmr->OSTmrName;
             len    = OS_StrLen(*pdest);
             OSSchedUnlock();
             *perr = OS_ERR_NONE;
             return (len);
        //定时器未被创建,无效
        case OS_TMR_STATE_UNUSED:                      /* Timer is not allocated                                      */
             OSSchedUnlock();
             *perr = OS_ERR_TMR_INACTIVE;
             return (0u);

        default:
             OSSchedUnlock();
             *perr = OS_ERR_TMR_INVALID_STATE;
             return (0u);
    }
}
#endif


/*
*********************************************************************************************************
*                          GET HOW MUCH TIME IS LEFT BEFORE A TIMER EXPIRES (获取定时器距离失效的剩余时间)
*
* Description: This function is called to get the number of ticks before a timer times out.
*这个函数用来获取定时器距离失效的时钟滴答数
* Arguments  : ptmr          Is a pointer to the timer to obtain the remaining time from.
*指向定时器的指针
*              perr          Is a pointer to an error code.  '*perr' will contain one of the following:
*                               OS_ERR_NONE
*                               OS_ERR_TMR_INVALID        'ptmr' is a NULL pointer
*                               OS_ERR_TMR_INVALID_TYPE   'ptmr'  is not pointing to an OS_TMR
*                               OS_ERR_TMR_ISR            if the call was made from an ISR
*                               OS_ERR_TMR_INACTIVE       'ptmr' points to a timer that is not active
*                               OS_ERR_TMR_INVALID_STATE  the timer is in an invalid state
*
* Returns    : The time remaining for the timer to expire.  The time represents 'timer' increments.
*              In other words, if OSTmr_Task() is signaled every 1/10 of a second then the returned
*              value represents the number of 1/10 of a second remaining before the timer expires.
计时器到期的剩余时间。这个time表示“计时器”增量。换句话说,如果OSTmr_Task()每隔1/10秒发出一次信号,那么返回值表示计时器到期前剩余的1/10秒的数量。
*********************************************************************************************************
*/

#if OS_TMR_EN > 0u
INT32U  OSTmrRemainGet (OS_TMR  *ptmr,
                        INT8U   *perr)
{
    INT32U  remain;


#ifdef OS_SAFETY_CRITICAL
    if (perr == (INT8U *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return (0u);
    }
#endif

//参数检查
#if OS_ARG_CHK_EN > 0u
    if (ptmr == (OS_TMR *)0) {
        *perr = OS_ERR_TMR_INVALID;
        return (0u);
    }
#endif
//检查定时器类型
    if (ptmr->OSTmrType != OS_TMR_TYPE) {              /* Validate timer structure                                    */
        *perr = OS_ERR_TMR_INVALID_TYPE;
        return (0u);
    }
    if (OSIntNesting > 0u) {                           /* See if trying to call from an ISR                           */
        *perr = OS_ERR_TMR_ISR;
        return (0u);
    }
    //调度器上锁
    OSSchedLock();
    switch (ptmr->OSTmrState) {
        case OS_TMR_STATE_RUNNING:
             remain = ptmr->OSTmrMatch - OSTmrTime;    /* Determine how much time is left to timeout                  */
             OSSchedUnlock();
             *perr  = OS_ERR_NONE;
             return (remain);

        case OS_TMR_STATE_STOPPED:                     /* It's assumed that the timer has not started yet             */
             switch (ptmr->OSTmrOpt) {
                 case OS_TMR_OPT_PERIODIC:
                 //如果定义的是周期性定时器,那么当延迟为0的时候,返回周期长度
                 //如果定义了延迟,那么返回延迟
                      if (ptmr->OSTmrDly == 0u) {
                          remain = ptmr->OSTmrPeriod;
                      } else {
                          remain = ptmr->OSTmrDly;
                      }
                      OSSchedUnlock();
                      *perr  = OS_ERR_NONE;
                      break;

                 case OS_TMR_OPT_ONE_SHOT:
                 default:
                      remain = ptmr->OSTmrDly;
                      OSSchedUnlock();
                      *perr  = OS_ERR_NONE;
                      break;
             }
             return (remain);

        case OS_TMR_STATE_COMPLETED:                   /* Only ONE-SHOT that timed out can be in this state           */
             OSSchedUnlock();
             *perr = OS_ERR_NONE;
             return (0u);

        case OS_TMR_STATE_UNUSED:
             OSSchedUnlock();
             *perr = OS_ERR_TMR_INACTIVE;
             return (0u);

        default:
             OSSchedUnlock();
             *perr = OS_ERR_TMR_INVALID_STATE;
             return (0u);
    }
}
#endif


/*
*********************************************************************************************************
*                                  FIND OUT WHAT STATE A TIMER IS IN (查找定时器当前所处状态)
*
* Description: This function is called to determine what state the timer is in:
*这个函数用来查找当前定时器处于那种状态
*                  OS_TMR_STATE_UNUSED     the timer has not been created 定时器未被创建
*                  OS_TMR_STATE_STOPPED    the timer has been created but has not been started or has been stopped
                                            定时器已被创建但是还没有开始计时,或者定时器被暂停了
*                  OS_TMR_STATE_COMPLETED  the timer is in ONE-SHOT mode and has completed it's timeout
                                            定时器处于一次性模式,并且已经完成了计时
*                  OS_TMR_STATE_RUNNING    the timer is currently running 定时器正在计时
*
* Arguments  : ptmr          Is a pointer to the desired timer
*指向定时器的指针
*              perr          Is a pointer to an error code.  '*perr' will contain one of the following:
*                               OS_ERR_NONE
*                               OS_ERR_TMR_INVALID        'ptmr' is a NULL pointer
*                               OS_ERR_TMR_INVALID_TYPE   'ptmr'  is not pointing to an OS_TMR
*                               OS_ERR_TMR_ISR            if the call was made from an ISR
*                               OS_ERR_TMR_INACTIVE       'ptmr' points to a timer that is not active
*                               OS_ERR_TMR_INVALID_STATE  if the timer is not in a valid state
*
* Returns    : The current state of the timer (see description).
*********************************************************************************************************
*/

#if OS_TMR_EN > 0u
INT8U  OSTmrStateGet (OS_TMR  *ptmr,
                      INT8U   *perr)
{
    INT8U  state;


#ifdef OS_SAFETY_CRITICAL
    if (perr == (INT8U *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return (0u);
    }
#endif

//参数检查
#if OS_ARG_CHK_EN > 0u
    if (ptmr == (OS_TMR *)0) {
        *perr = OS_ERR_TMR_INVALID;
        return (0u);
    }
#endif
//检查控制块类型
    if (ptmr->OSTmrType != OS_TMR_TYPE) {              /* Validate timer structure                                    */
        *perr = OS_ERR_TMR_INVALID_TYPE;
        return (0u);
    }
    if (OSIntNesting > 0u) {                           /* See if trying to call from an ISR                           */
        *perr = OS_ERR_TMR_ISR;
        return (0u);
    }
    //调度器上锁
    OSSchedLock();
    //获取当前控制块的状态
    state = ptmr->OSTmrState;
    switch (state) {
        case OS_TMR_STATE_UNUSED:
        case OS_TMR_STATE_STOPPED:
        case OS_TMR_STATE_COMPLETED:
        case OS_TMR_STATE_RUNNING:
             *perr = OS_ERR_NONE;
             break;
        //有效状态只有四种
        default:
             *perr = OS_ERR_TMR_INVALID_STATE;
             break;
    }
    OSSchedUnlock();//调度器解锁
    return (state);
}
#endif


/*
*********************************************************************************************************
*                                            START A TIMER (开始一个定时器)
*
* Description: This function is called by your application code to start a timer.
*这个函数被用来启动一个定时器
* Arguments  : ptmr          Is a pointer to an OS_TMR
*
*              perr          Is a pointer to an error code.  '*perr' will contain one of the following:
*                               OS_ERR_NONE
*                               OS_ERR_TMR_INVALID
*                               OS_ERR_TMR_INVALID_TYPE    'ptmr'  is not pointing to an OS_TMR
*                               OS_ERR_TMR_ISR             if the call was made from an ISR
*                               OS_ERR_TMR_INACTIVE        if the timer was not created
*                               OS_ERR_TMR_INVALID_STATE   the timer is in an invalid state
*
* Returns    : OS_TRUE    if the timer was started
*              OS_FALSE   if an error was detected
*********************************************************************************************************
*/

#if OS_TMR_EN > 0u
BOOLEAN  OSTmrStart (OS_TMR   *ptmr,
                     INT8U    *perr)
{
#ifdef OS_SAFETY_CRITICAL
    if (perr == (INT8U *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return (OS_FALSE);
    }
#endif

//参数检查
#if OS_ARG_CHK_EN > 0u
    if (ptmr == (OS_TMR *)0) {
        *perr = OS_ERR_TMR_INVALID;
        return (OS_FALSE);
    }
#endif

    OS_TRACE_TMR_START_ENTER(ptmr);
//检查控制块类型
    if (ptmr->OSTmrType != OS_TMR_TYPE) {                   /* Validate timer structure                               */
        *perr = OS_ERR_TMR_INVALID_TYPE;
        OS_TRACE_TMR_START_EXIT(*perr);
        return (OS_FALSE);
    }
    if (OSIntNesting > 0u) {                                /* See if trying to call from an ISR                      */
        *perr  = OS_ERR_TMR_ISR;
        OS_TRACE_TMR_START_EXIT(*perr);
        return (OS_FALSE);
    }
    //调度器上锁
    OSSchedLock();
    switch (ptmr->OSTmrState) {
        case OS_TMR_STATE_RUNNING:                          /* Restart the timer                                      */
             OSTmr_Unlink(ptmr);                            /* ... Stop the timer                                     */
             //将定时器插入到轮子中,重新计时,以前的match失效了
             OSTmr_Link(ptmr, OS_TMR_LINK_DLY);             /* ... Link timer to timer wheel                          */
             OSSchedUnlock();
             *perr = OS_ERR_NONE;
             OS_TRACE_TMR_START_EXIT(*perr);
             return (OS_TRUE);

        case OS_TMR_STATE_STOPPED:                          /* Start the timer                                        */
        case OS_TMR_STATE_COMPLETED:
             OSTmr_Link(ptmr, OS_TMR_LINK_DLY);             /* ... Link timer to timer wheel                          */
             OSSchedUnlock();
             *perr = OS_ERR_NONE;
             OS_TRACE_TMR_START_EXIT(*perr);
             return (OS_TRUE);

        case OS_TMR_STATE_UNUSED:                           /* Timer not created                                      */
             OSSchedUnlock();
             *perr = OS_ERR_TMR_INACTIVE;
             OS_TRACE_TMR_START_EXIT(*perr);
             return (OS_FALSE);

        default:
             OSSchedUnlock();
             *perr = OS_ERR_TMR_INVALID_STATE;
             OS_TRACE_TMR_START_EXIT(*perr);
             return (OS_FALSE);
    }
}
#endif


/*
*********************************************************************************************************
*                                            STOP A TIMER (停止一个定时器)
*
* Description: This function is called by your application code to stop a timer.
*这个函数用来停止一个定时器
* Arguments  : ptmr          Is a pointer to the timer to stop.
*指向定时器的指针
*              opt           Allows you to specify an option to this functions which can be:
*
*                               OS_TMR_OPT_NONE          Do nothing special but stop the timer 仅仅只是停止定时器
*                               OS_TMR_OPT_CALLBACK      Execute the callback function, pass it the
*                                                        callback argument specified when the timer
*                                                        was created. 执行回调函数,并传递创建的时候传递进的参数
*                               OS_TMR_OPT_CALLBACK_ARG  Execute the callback function, pass it the
*                                                        callback argument specified in THIS function call.
*                                                           执行回调函数,传递这个函数中所确定的参数
*              callback_arg  Is a pointer to a 'new' callback argument that can be passed to the callback
*                            function instead of the timer's callback argument.  In other words, use
*                            'callback_arg' passed in THIS function INSTEAD of ptmr->OSTmrCallbackArg.
*指向新的回调函数参数的指针,这个新的参数可以用来替代创建定时器时定义的参数。换句话说,这里的callback_arg可以替代       
                                                                                    ptmr->OSTmrCallbackArg
*              perr          Is a pointer to an error code.  '*perr' will contain one of the following:
*                               OS_ERR_NONE
*                               OS_ERR_TMR_INVALID         'ptmr' is a NULL pointer
*                               OS_ERR_TMR_INVALID_TYPE    'ptmr'  is not pointing to an OS_TMR
*                               OS_ERR_TMR_ISR             if the function was called from an ISR
*                               OS_ERR_TMR_INACTIVE        if the timer was not created
*                               OS_ERR_TMR_INVALID_OPT     if you specified an invalid option for 'opt'
*                               OS_ERR_TMR_STOPPED         if the timer was already stopped
*                               OS_ERR_TMR_INVALID_STATE   the timer is in an invalid state
*                               OS_ERR_TMR_NO_CALLBACK     if the timer does not have a callback function defined
*
* Returns    : OS_TRUE       If we stopped the timer (if the timer is already stopped, we also return OS_TRUE)
*              OS_FALSE      If not
*********************************************************************************************************
*/

#if OS_TMR_EN > 0u
BOOLEAN  OSTmrStop (OS_TMR  *ptmr,
                    INT8U    opt,
                    void    *callback_arg,
                    INT8U   *perr)
{
    OS_TMR_CALLBACK  pfnct;//定义指向回调函数的指针


#ifdef OS_SAFETY_CRITICAL
    if (perr == (INT8U *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return (OS_FALSE);
    }
#endif

//参数检查
#if OS_ARG_CHK_EN > 0u
    if (ptmr == (OS_TMR *)0) {
        *perr = OS_ERR_TMR_INVALID;
        return (OS_FALSE);
    }
#endif

    OS_TRACE_TMR_STOP_ENTER(ptmr);
//检查控制块类型
    if (ptmr->OSTmrType != OS_TMR_TYPE) {                         /* Validate timer structure                         */
        *perr = OS_ERR_TMR_INVALID_TYPE;
        OS_TRACE_TMR_STOP_EXIT(*perr);
        return (OS_FALSE);
    }
    if (OSIntNesting > 0u) {                                      /* See if trying to call from an ISR                */
        *perr  = OS_ERR_TMR_ISR;
        OS_TRACE_TMR_STOP_EXIT(*perr);
        return (OS_FALSE);
    }
    //调度器上锁
    OSSchedLock();
    switch (ptmr->OSTmrState) {
        //如果当前定时器正在运行
        case OS_TMR_STATE_RUNNING:
            //将定时器从轮子中摘除
             OSTmr_Unlink(ptmr);                                  /* Remove from current wheel spoke                  */
             *perr = OS_ERR_NONE;
             switch (opt) {
                 case OS_TMR_OPT_CALLBACK:
                 //获得函数指针
                      pfnct = ptmr->OSTmrCallback;                /* Execute callback function if available ...       */
                      if (pfnct != (OS_TMR_CALLBACK)0) {
                          //调用回调函数
                          (*pfnct)((void *)ptmr, ptmr->OSTmrCallbackArg);  /* Use callback arg when timer was created */
                      } else {
                          *perr = OS_ERR_TMR_NO_CALLBACK;
                      }
                      break;

                 case OS_TMR_OPT_CALLBACK_ARG:
                      pfnct = ptmr->OSTmrCallback;                /* Execute callback function if available ...       */
                      if (pfnct != (OS_TMR_CALLBACK)0) {
                          (*pfnct)((void *)ptmr, callback_arg);   /* ... using the 'callback_arg' provided in call    */
                      } else {
                          *perr = OS_ERR_TMR_NO_CALLBACK;
                      }
                      break;

                 case OS_TMR_OPT_NONE:
                      break;

                 default:
                     *perr = OS_ERR_TMR_INVALID_OPT;
                     break;
             }
             OSSchedUnlock();
             OS_TRACE_TMR_STOP_EXIT(*perr);
             return (OS_TRUE);
        //如果定时器本身就已经处于未运行状态,则不用调用回调函数
        case OS_TMR_STATE_COMPLETED:                              /* Timer has already completed the ONE-SHOT or ...  */
        case OS_TMR_STATE_STOPPED:                                /* ... timer has not started yet.                   */
             OSSchedUnlock();
             *perr = OS_ERR_TMR_STOPPED;
             OS_TRACE_TMR_STOP_EXIT(*perr);
             return (OS_TRUE);

        case OS_TMR_STATE_UNUSED:                                 /* Timer was not created                            */
             OSSchedUnlock();
             *perr = OS_ERR_TMR_INACTIVE;
             OS_TRACE_TMR_STOP_EXIT(*perr);
             return (OS_FALSE);

        default:
             OSSchedUnlock();
             *perr = OS_ERR_TMR_INVALID_STATE;
             OS_TRACE_TMR_STOP_EXIT(*perr);
             return (OS_FALSE);
    }
}
#endif


/*
*********************************************************************************************************
*                             SIGNAL THAT IT'S TIME TO UPDATE THE TIMERS (提醒,是时候更新定时器了)
*
* Description: This function is typically called by the ISR that occurs at the timer tick rate and is
*              used to signal to OSTmr_Task() that it's time to update the timers.
*当时钟滴答发生的时候,这个函数被ISR调用,用来提醒OSTmr_Task更新定时器
* Arguments  : none
*
* Returns    : OS_ERR_NONE         The call was successful and the timer task was signaled.
*              OS_ERR_SEM_OVF      If OSTmrSignal() was called more often than OSTmr_Task() can handle
*                                  the timers. This would indicate that your system is heavily loaded.
*              OS_ERR_EVENT_TYPE   Unlikely you would get this error because the semaphore used for
*                                  signaling is created by uC/OS-II.
*              OS_ERR_PEVENT_NULL  Again, unlikely you would ever get this error because the semaphore
*                                  used for signaling is created by uC/OS-II.
*********************************************************************************************************
*/

#if OS_TMR_EN > 0u
INT8U  OSTmrSignal (void)
{
    INT8U  err;


    err = OSSemPost(OSTmrSemSignal);
    return (err);
}
#endif


/*
*********************************************************************************************************
*                                      ALLOCATE AND FREE A TIMER (获得一个控制块)
*
* Description: This function is called to allocate a timer.
*这个函数用来获得一个定时器控制块
* Arguments  : none
*
* Returns    : a pointer to a timer if one is available
指向控制块的指针
*********************************************************************************************************
*/

#if OS_TMR_EN > 0u
static  OS_TMR  *OSTmr_Alloc (void)
{
    OS_TMR *ptmr;

    
    if (OSTmrFreeList == (OS_TMR *)0) {
        return ((OS_TMR *)0);
    }
    //如果timer的定时器控制块还有空闲的
    ptmr            = (OS_TMR *)OSTmrFreeList;
    OSTmrFreeList   = (OS_TMR *)ptmr->OSTmrNext;


    //此处错误,源代码错误,强转类型应该为 (OS_TMR *)或者 (void *)


    ptmr->OSTmrNext = (OS_TCB *)0;
    ptmr->OSTmrPrev = (OS_TCB *)0;
    OSTmrUsed++;//全局变量,用来记录控制块的使用个数
    OSTmrFree--;//全局变量,用来计数可用的定时器控制块的个数
    return (ptmr);//返回控制块指针
}
#endif


/*
*********************************************************************************************************
*                                   RETURN A TIMER TO THE FREE LIST (删除一个定时器)
*
* Description: This function is called to return a timer object to the free list of timers.
*这个函数用来删除一个定时器,将定时器的资源返回给空闲链表
* Arguments  : ptmr     is a pointer to the timer to free
*指向将被free的定时器控制块
* Returns    : none
*********************************************************************************************************
*/

#if OS_TMR_EN > 0u
static  void  OSTmr_Free (OS_TMR *ptmr)
{
    //将定时器的状态置位
    ptmr->OSTmrState       = OS_TMR_STATE_UNUSED;      /* Clear timer object fields                                   */
    ptmr->OSTmrOpt         = OS_TMR_OPT_NONE;
    ptmr->OSTmrPeriod      = 0u;
    ptmr->OSTmrMatch       = 0u;
    ptmr->OSTmrCallback    = (OS_TMR_CALLBACK)0;
    ptmr->OSTmrCallbackArg = (void *)0;
#if OS_TMR_CFG_NAME_EN > 0u
    ptmr->OSTmrName        = (INT8U *)(void *)"?";
#endif

    //将定时器控制块返回给空闲链表


    //此处错误,源代码错误,强转类型应该为 (OS_TMR *)或者 (void *)


    ptmr->OSTmrPrev        = (OS_TCB *)0;              /* Chain timer to free list                                    */
    ptmr->OSTmrNext        = OSTmrFreeList;
    OSTmrFreeList          = ptmr;

    OSTmrUsed--;                                       /* Update timer object statistics                              */
    OSTmrFree++;
}
#endif


/*
*********************************************************************************************************
*                                                    INITIALIZATION (初始化)
*                                          INITIALIZE THE FREE LIST OF TIMERS (初始化定时器空闲列表)
*
* Description: This function is called by OSInit() to initialize the free list of OS_TMRs.
*这个函数被OSInit调用,来初始化空闲定时器列表
* Arguments  : none
*
* Returns    : none
*********************************************************************************************************
*/

#if OS_TMR_EN > 0u
void  OSTmr_Init (void)
{
#if OS_EVENT_NAME_EN > 0u
    INT8U    err;
#endif
    INT16U   ix;
    INT16U   ix_next;
    OS_TMR  *ptmr1;
    OS_TMR  *ptmr2;


    OS_MemClr((INT8U *)&OSTmrTbl[0],      sizeof(OSTmrTbl));            /* Clear all the TMRs                         */
    OS_MemClr((INT8U *)&OSTmrWheelTbl[0], sizeof(OSTmrWheelTbl));       /* Clear the timer wheel                      */

    for (ix = 0u; ix < (OS_TMR_CFG_MAX - 1u); ix++) {                   /* Init. list of free TMRs                    */
        ix_next = ix + 1u;
        ptmr1 = &OSTmrTbl[ix];
        ptmr2 = &OSTmrTbl[ix_next];
        ptmr1->OSTmrType    = OS_TMR_TYPE;
        ptmr1->OSTmrState   = OS_TMR_STATE_UNUSED;                      /* Indicate that timer is inactive            */
        ptmr1->OSTmrNext    = (void *)ptmr2;                            /* Link to next timer                         */
#if OS_TMR_CFG_NAME_EN > 0u
        ptmr1->OSTmrName    = (INT8U *)(void *)"?";
#endif
    }
    ptmr1               = &OSTmrTbl[ix];
    ptmr1->OSTmrType    = OS_TMR_TYPE;
    ptmr1->OSTmrState   = OS_TMR_STATE_UNUSED;                          /* Indicate that timer is inactive            */
    ptmr1->OSTmrNext    = (void *)0;                                    /* Last OS_TMR                                */
#if OS_TMR_CFG_NAME_EN > 0u
    ptmr1->OSTmrName    = (INT8U *)(void *)"?";
#endif
    //全局变量
    //定义系统时钟为0
    OSTmrTime           = 0u;
    OSTmrUsed           = 0u;
    OSTmrFree           = OS_TMR_CFG_MAX;
    OSTmrFreeList       = &OSTmrTbl[0];
    //创建信号量
    OSTmrSem            = OSSemCreate(1u);
    OSTmrSemSignal      = OSSemCreate(0u);

//为信号量命名
#if OS_EVENT_NAME_EN > 0u                                               /* Assign names to semaphores                 */
    OSEventNameSet(OSTmrSem,       (INT8U *)(void *)"uC/OS-II TmrLock",   &err);
    OSEventNameSet(OSTmrSemSignal, (INT8U *)(void *)"uC/OS-II TmrSignal", &err);
#endif

    OSTmr_InitTask();
}
#endif


/*
*********************************************************************************************************
*                                INITIALIZE THE TIMER MANAGEMENT TASK (初始化定时器管理Task)
*
* Description: This function is called by OSTmrInit() to create the timer management task.
*                               * Arguments  : none
*这个函数被OSTmrInit函数调用,来创建定时器管理Task
* Returns    : none
*********************************************************************************************************
*/

#if OS_TMR_EN > 0u
static  void  OSTmr_InitTask (void)
{
#if OS_TASK_NAME_EN > 0u
    INT8U  err;
#endif


#if OS_TASK_CREATE_EXT_EN > 0u
    #if OS_STK_GROWTH == 1u
    (void)OSTaskCreateExt(OSTmr_Task,
                          (void *)0,                                       /* No arguments passed to OSTmrTask()      */
                          &OSTmrTaskStk[OS_TASK_TMR_STK_SIZE - 1u],        /* Set Top-Of-Stack                        */
                          OS_TASK_TMR_PRIO,
                          OS_TASK_TMR_ID,
                          &OSTmrTaskStk[0],                                /* Set Bottom-Of-Stack                     */
                          OS_TASK_TMR_STK_SIZE,
                          (void *)0,                                       /* No TCB extension                        */
                          OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);      /* Enable stack checking + clear stack     */
    #else
    (void)OSTaskCreateExt(OSTmr_Task,
                          (void *)0,                                       /* No arguments passed to OSTmrTask()      */
                          &OSTmrTaskStk[0],                                /* Set Top-Of-Stack                        */
                          OS_TASK_TMR_PRIO,
                          OS_TASK_TMR_ID,
                          &OSTmrTaskStk[OS_TASK_TMR_STK_SIZE - 1u],        /* Set Bottom-Of-Stack                     */
                          OS_TASK_TMR_STK_SIZE,
                          (void *)0,                                       /* No TCB extension                        */
                          OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);      /* Enable stack checking + clear stack     */
    #endif
#else
    #if OS_STK_GROWTH == 1u
    (void)OSTaskCreate(OSTmr_Task,
                       (void *)0,
                       &OSTmrTaskStk[OS_TASK_TMR_STK_SIZE - 1u],
                       OS_TASK_TMR_PRIO);
    #else
    (void)OSTaskCreate(OSTmr_Task,
                       (void *)0,
                       &OSTmrTaskStk[0],
                       OS_TASK_TMR_PRIO);
    #endif
#endif

#if OS_TASK_NAME_EN > 0u
    OSTaskNameSet(OS_TASK_TMR_PRIO, (INT8U *)(void *)"uC/OS-II Tmr", &err);
#endif
}
#endif


/*
*********************************************************************************************************
*                                 INSERT A TIMER INTO THE TIMER WHEEL (将一个定时器插入到定时器轮子中)
*
* Description: This function is called to insert the timer into the timer wheel.  The timer is always
*              inserted at the beginning of the list.
*这个函数被用来调用,将定时器插入到定时器轮子中,定时器总是被插入到轮子的开头处
* Arguments  : ptmr          Is a pointer to the timer to insert.
*指向定时器的指针
*              type          Is either:两者选择其一
*                               OS_TMR_LINK_PERIODIC    Means to re-insert the timer after a period expired
                                                        每个周期结束后都将定时器重新插入到轮子中
*                               OS_TMR_LINK_DLY         Means to insert    the timer the first time
*                                                       第一次插入到轮子中,都是此种类型。无论是否为周期定时器
* Returns    : none
*********************************************************************************************************
*/

#if OS_TMR_EN > 0u
static  void  OSTmr_Link (OS_TMR  *ptmr,
                          INT8U    type)
{
    OS_TMR       *ptmr1;
    OS_TMR_WHEEL *pspoke;
    INT16U        spoke;

    //将定时器状态改为运行态
    ptmr->OSTmrState = OS_TMR_STATE_RUNNING;
    //周期性插入定时器
    if (type == OS_TMR_LINK_PERIODIC) {                            /* Determine when timer will expire                */
        //设定下一次定时器结束时间为当前系统时间加上定时器周期时间
        ptmr->OSTmrMatch = ptmr->OSTmrPeriod + OSTmrTime;
    } else {
        //如果定时器延时为0,说明必然是一个周期定时器
        if (ptmr->OSTmrDly == 0u) {
            ptmr->OSTmrMatch = ptmr->OSTmrPeriod + OSTmrTime;
        } else {
            //如果定时器有延时,1.若为普通一次性定时器,则正常,2.如果为周期性定时器,则为进入周期循环的第一次不属于周期内的延迟
            ptmr->OSTmrMatch = ptmr->OSTmrDly    + OSTmrTime;
        }
    }
    spoke  = (INT16U)(ptmr->OSTmrMatch % OS_TMR_CFG_WHEEL_SIZE);
    pspoke = &OSTmrWheelTbl[spoke];

//链表插入操作
    if (pspoke->OSTmrFirst == (OS_TMR *)0) {                       /* Link into timer wheel                           */
        pspoke->OSTmrFirst   = ptmr;
        ptmr->OSTmrNext      = (OS_TMR *)0;
        pspoke->OSTmrEntries = 1u;
    } else {
        ptmr1                = pspoke->OSTmrFirst;                 /* Point to first timer in the spoke               */
        pspoke->OSTmrFirst   = ptmr;
        ptmr->OSTmrNext      = (void *)ptmr1;
        ptmr1->OSTmrPrev     = (void *)ptmr;
        pspoke->OSTmrEntries++;
    }
    ptmr->OSTmrPrev = (void *)0;                                   /* Timer always inserted as first node in list     */
}
#endif


/*
*********************************************************************************************************
*                                 REMOVE A TIMER FROM THE TIMER WHEEL (从定时器轮中删除指定的定时器)
*
* Description: This function is called to remove the timer from the timer wheel.
*从定时器轮中删除定时器
* Arguments  : ptmr          Is a pointer to the timer to remove.
*指向即将被删除的定时器
* Returns    : none
*********************************************************************************************************
*/

#if OS_TMR_EN > 0u
static  void  OSTmr_Unlink (OS_TMR *ptmr)
{
    OS_TMR        *ptmr1;
    OS_TMR        *ptmr2;
    OS_TMR_WHEEL  *pspoke;
    INT16U         spoke;

    //spoke (车轮的辐条,轮辐)
    // #define OS_TMR_CFG_WHEEL_SIZE     7u   /*     Size of timer wheel (#Spokes)                            */
    // Timer expires when OSTmrTime == OSTmrMatch
    // 一共有七个轮子,每个轮子都有一系列定时器在转
    // 获取当前定时器属于那个轮子
    // 这种方法为哈希方法,链表处理哈希冲突
    spoke  = (INT16U)(ptmr->OSTmrMatch % OS_TMR_CFG_WHEEL_SIZE);
    pspoke = &OSTmrWheelTbl[spoke];

    if (pspoke->OSTmrFirst == ptmr) {                       /* See if timer to remove is at the beginning of list     */
        ptmr1              = (OS_TMR *)ptmr->OSTmrNext;
        pspoke->OSTmrFirst = (OS_TMR *)ptmr1;
        if (ptmr1 != (OS_TMR *)0) {
            ptmr1->OSTmrPrev = (void *)0;
        }
    } else {
        //轮子是双向链表,轮子本身提供一种入口,是定时器控制块本身为双向链表格式
        ptmr1            = (OS_TMR *)ptmr->OSTmrPrev;       /* Remove timer from somewhere in the list                */
        ptmr2            = (OS_TMR *)ptmr->OSTmrNext;
        ptmr1->OSTmrNext = ptmr2;
        if (ptmr2 != (OS_TMR *)0) {
            ptmr2->OSTmrPrev = (void *)ptmr1;
        }
    }
    //将定时器的状态置位
    ptmr->OSTmrState = OS_TMR_STATE_STOPPED;
    ptmr->OSTmrNext  = (void *)0;
    ptmr->OSTmrPrev  = (void *)0;
    pspoke->OSTmrEntries--;//轮子实体数减一
}
#endif


/*
*********************************************************************************************************
*                                        TIMER MANAGEMENT TASK (定时器管理任务)
*
* Description: This task is created by OSTmrInit().
*
* Arguments  : none
*
* Returns    : none
*********************************************************************************************************
*/

//注意,此函数仅仅只是管理函数,当定时器到时间了,负责将其状态标记,至于怎么处理定时器,是创建定时器任务的事,
//此函数仅仅负责调用回调函数就行,不负责定时器的增删改查
#if OS_TMR_EN > 0u
static  void  OSTmr_Task (void *p_arg)
{
    INT8U            err;
    OS_TMR          *ptmr;
    OS_TMR          *ptmr_next;
    OS_TMR_CALLBACK  pfnct;
    OS_TMR_WHEEL    *pspoke;
    INT16U           spoke;

    //防止编译器报错
    p_arg = p_arg;                                               /* Prevent compiler warning for not using 'p_arg'    */
    for (;;) {
        //等待始终滴答信号量
        OSSemPend(OSTmrSemSignal, 0u, &err);                     /* Wait for signal indicating time to update timers  */
        //调度器上锁,禁止任务调度
        OSSchedLock();
        //系统时钟自增
        OSTmrTime++;                                             /* Increment the current time                        */
        spoke  = (INT16U)(OSTmrTime % OS_TMR_CFG_WHEEL_SIZE);    /* Position on current timer wheel entry             */
        pspoke = &OSTmrWheelTbl[spoke];
        ptmr   = pspoke->OSTmrFirst;
        while (ptmr != (OS_TMR *)0) {
            ptmr_next = (OS_TMR *)ptmr->OSTmrNext;               /* Point to next timer to update because current ... */
                                                                 /* ... timer could get unlinked from the wheel.      */
            if (OSTmrTime == ptmr->OSTmrMatch) {                 /* Process each timer that expires                   */
                OS_TRACE_TMR_EXPIRED(ptmr);
                OSTmr_Unlink(ptmr);                              /* Remove from current wheel spoke                   */
                if (ptmr->OSTmrOpt == OS_TMR_OPT_PERIODIC) {
                    OSTmr_Link(ptmr, OS_TMR_LINK_PERIODIC);      /* Recalculate new position of timer in wheel        */
                } else {
                    ptmr->OSTmrState = OS_TMR_STATE_COMPLETED;   /* Indicate that the timer has completed             */
                }
                pfnct = ptmr->OSTmrCallback;                     /* Execute callback function if available            */
                if (pfnct != (OS_TMR_CALLBACK)0) {
                    (*pfnct)((void *)ptmr, ptmr->OSTmrCallbackArg);
                }
            }
            ptmr = ptmr_next;
        }
        OSSchedUnlock();
    }
}
#endif

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值