Exemple #1
0
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 (;;) {
		/* 等待OSTmrSignal()发送的定时器更新的信号,在OSTimeTickHook()中调用,发送频率100HZ */
        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_TMR_STATE_STOPPED
				 * 虽然定时器已经不在该定时器分组中了,但是该定时器仍然有效,可以通过定时器控制块访问
				 */
                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();
    }
}
Exemple #2
0
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
    if (ptmr->OSTmrType != OS_TMR_TYPE) {                   /* Validate timer structure                               */
        *perr = OS_ERR_TMR_INVALID_TYPE;
        return (OS_FALSE);
    }
    if (OSIntNesting > 0u) {                                /* See if trying to call from an ISR                      */
        *perr  = OS_ERR_TMR_ISR;
        return (OS_FALSE);
    }
    OSSchedLock();
    switch (ptmr->OSTmrState) {
        case OS_TMR_STATE_RUNNING:                          /* Restart the timer                                      */
             OSTmr_Unlink(ptmr);                            /* ... Stop the timer                                     */
             OSTmr_Link(ptmr, OS_TMR_LINK_DLY);             /* ... Link timer to timer wheel                          */
             OSSchedUnlock();
             *perr = OS_ERR_NONE;
             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;
             return (OS_TRUE);

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

        default:
             OSSchedUnlock();
             *perr = OS_ERR_TMR_INVALID_STATE;
             return (OS_FALSE);
    }
}
Exemple #3
0
BOOLEAN  OSTmrDel (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
    if (ptmr->OSTmrType != OS_TMR_TYPE) {                   /* Validate timer structure                               */
        *perr = OS_ERR_TMR_INVALID_TYPE;
        return (OS_FALSE);
    }
    if (OSIntNesting > 0u) {                                /* See if trying to call from an ISR                      */
        *perr  = OS_ERR_TMR_ISR;
        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;
             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;
             return (OS_TRUE);

        case OS_TMR_STATE_UNUSED:                           /* Already deleted                                        */
             OSSchedUnlock();
             *perr = OS_ERR_TMR_INACTIVE;
             return (OS_FALSE);

        default:
             OSSchedUnlock();
             *perr = OS_ERR_TMR_INVALID_STATE;
             return (OS_FALSE);
    }
}
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;


    ( void ) p_arg;             /* Not using 'p_arg', prevent compiler warning       */
    for ( ;; )
    {
        OSSemPend( OSTmrSemSignal, 0, &err );   /* Wait for signal indicating time to update timers  */
        OSTmr_Lock(  );
        OSTmrTime++;            /* Increment the current time                        */
        spoke = 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 = 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                   */
                pfnct = ptmr->OSTmrCallback;    /* Execute callback function if available            */
                if ( pfnct != ( OS_TMR_CALLBACK ) 0 )
                {
                    ( *pfnct ) ( ptmr, ptmr->OSTmrCallbackArg );
                }
                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             */
                }
            }
            ptmr = ptmr_next;
        }
        OSTmr_Unlock(  );
    }
}
BOOLEAN  OSTmrStop (OS_TMR  *ptmr,
                    INT8U    opt,
                    void    *callback_arg,
                    INT8U   *perr)
{
    OS_TMR_CALLBACK  pfnct;


#if OS_ARG_CHK_EN > 0
    if (perr == (INT8U *)0) {                                     /* Validate arguments                               */
        return (OS_FALSE);
    }
    if (ptmr == (OS_TMR *)0) {
        *perr = OS_ERR_TMR_INVALID;
        return (OS_FALSE);
    }
#endif
    if (ptmr->OSTmrType != OS_TMR_TYPE) {                         /* Validate timer structure                         */
        *perr = OS_ERR_TMR_INVALID_TYPE;
        return (OS_FALSE);
    }
    if (OSIntNesting > 0) {                                       /* See if trying to call from an ISR                */
        *perr  = OS_ERR_TMR_ISR;
        return (OS_FALSE);
    }
    OSTmr_Lock();
    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;
             }
             OSTmr_Unlock();
             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.                   */
             OSTmr_Unlock();
             *perr = OS_ERR_TMR_STOPPED;
             return (OS_TRUE);

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

        default:
             OSTmr_Unlock();
             *perr = OS_ERR_TMR_INVALID_STATE;
             return (OS_FALSE);
    }
}
Exemple #6
0
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
    if (ptmr->OSTmrType != OS_TMR_TYPE) {                         /* Validate timer structure                         */
        *perr = OS_ERR_TMR_INVALID_TYPE;
        return (OS_FALSE);
    }
    if (OSIntNesting > 0u) {                                      /* See if trying to call from an ISR                */
        *perr  = OS_ERR_TMR_ISR;
        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();
             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;
             return (OS_TRUE);

		/* 如果定时器是未使用状态,则返回错误信息 */
        case OS_TMR_STATE_UNUSED:                                 /* Timer was not created                            */
             OSSchedUnlock();
             *perr = OS_ERR_TMR_INACTIVE;
             return (OS_FALSE);

        default:
             OSSchedUnlock();
             *perr = OS_ERR_TMR_INVALID_STATE;
             return (OS_FALSE);
    }
}
Exemple #7
0
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
    if (ptmr->OSTmrType != OS_TMR_TYPE) {                   /* Validate timer structure                               */
        *perr = OS_ERR_TMR_INVALID_TYPE;
        return (OS_FALSE);
    }
    if (OSIntNesting > 0u) {                                /* See if trying to call from an ISR                      */
        *perr  = OS_ERR_TMR_ISR;
        return (OS_FALSE);
    }
	/* 调度器加锁 */
    OSSchedLock();
	
    switch (ptmr->OSTmrState) {
		/* 如果当前定时器是正在运行状态,则把定时器从当前分组移除
		 * 更新定时器到时时间后,把定时器重新链接到新的分组,并设置为第一次开始计时
		 */
        case OS_TMR_STATE_RUNNING:                          /* Restart the timer                                      */
             OSTmr_Unlink(ptmr);                            /* ... Stop the timer                                     */
			/* 使用OS_TMR_LINK_DLY选项把定时器链接进新的分组 
			 * 会按照第一次插入定时器,设置Dly或者Period
			 */
             OSTmr_Link(ptmr, OS_TMR_LINK_DLY);             /* ... Link timer to timer wheel                          */
             OSSchedUnlock();
             *perr = OS_ERR_NONE;
             return (OS_TRUE);
		
		/* 如果定时器是Stop状态或者单次定时器的COMPLETED状态
		 * 则按照第一次插入定时器,设置Dly或者Period
		 */
        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;
             return (OS_TRUE);
		
		/* 如果定时器是未使用状态,返回错误信息 */
        case OS_TMR_STATE_UNUSED:                           /* Timer not created                                      */
             OSSchedUnlock();
             *perr = OS_ERR_TMR_INACTIVE;
             return (OS_FALSE);

        default:
             OSSchedUnlock();
             *perr = OS_ERR_TMR_INVALID_STATE;
             return (OS_FALSE);
    }
}
Exemple #8
0
BOOLEAN  OSTmrDel (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
    if (ptmr->OSTmrType != OS_TMR_TYPE) {                   /* Validate timer structure                               */
        *perr = OS_ERR_TMR_INVALID_TYPE;
        return (OS_FALSE);
    }
    if (OSIntNesting > 0u) {                                /* See if trying to call from an ISR                      */
        *perr  = OS_ERR_TMR_ISR;
        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;
             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;
             return (OS_TRUE);
		
		/* 如果定时器控制块是未使用状态,则返回错误信息 */
        case OS_TMR_STATE_UNUSED:                           /* Already deleted                                        */
             OSSchedUnlock();
             *perr = OS_ERR_TMR_INACTIVE;
             return (OS_FALSE);

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