μC/OS-II---计时器管理1(os_tmr.c)

目录

    • 创建一个计时器
    • 重新启动一个计时器
    • 停止一个计时器
    • 删除一个计时器

在这里插入图片描述

  • 计时器是倒计时器,当计数器达到零时执行某个动作。用户通过回调函数提供这个动作。回调函数是用户声明的函数,在计时器到期时被调用。在回调函数中绝对不能进行阻塞调用(例如调用OSTimeDly()、OSTimeDlyHMSM()…或任何导致计时器任务阻塞或被删除的操作),这一点非常重要。

创建一个计时器

#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();
		return ((OS_TMR *)0);
	}
	
#endif
#if OS_ARG_CHK_EN > 0u
	
	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;
			
		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();
	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();
	*perr = OS_ERR_NONE;
	return (ptmr);
}
#endif

重新启动一个计时器

#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
	
	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);
	}
}
#endif

停止一个计时器

#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
	
	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);
	}
}
#endif

删除一个计时器

#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
#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);
	}
}
#endif

你可能感兴趣的:(μC/OS-II学习,c语言)