Ejemplo n.º 1
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);
    }
}
Ejemplo n.º 2
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();
    }
}
Ejemplo n.º 3
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;


    ( 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(  );
    }
}
Ejemplo n.º 4
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);
    }
}