?? os_tmr.c
字號:
/*
************************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2005-2006, Micrium, Weston, FL
* All Rights Reserved
*
* TIMER MANAGEMENT
*
* File : OS_TMR.C
* By : Jean J. Labrosse
* Version : V2.83
************************************************************************************************************************
*/
#include <ucos_ii.h>
/*
************************************************************************************************************************
* 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.
************************************************************************************************************************
*/
/*
************************************************************************************************************************
* CONSTANTS
************************************************************************************************************************
*/
#define OS_TMR_LINK_DLY 0
#define OS_TMR_LINK_PERIODIC 1
/*
************************************************************************************************************************
* LOCAL PROTOTYPES
************************************************************************************************************************
*/
#if OS_TMR_EN > 0
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_Lock (void);
static void OSTmr_Unlock (void);
static void OSTmr_Task (void *p_arg);
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* 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.
*
* 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. The length of the ASCII string for the name can be as big as:
*
* OS_TMR_CFG_NAME_SIZE and should be found in OS_CFG.H
*
* perr Is a pointer to an error code. '*perr' will contain one of the following:
* OS_NO_ERR
* 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
* OS_ERR_TMR_NAME_TOO_LONG if the timer name is too long to fit
*
* Returns : A pointer to an OS_TMR data structure. This is the 'handle' that you application will use to reference
* the timer created/started.
************************************************************************************************************************
*/
#if OS_TMR_EN > 0
OS_TMR *OSTmrCreate (INT32U dly,
INT32U period,
INT8U opt,
OS_TMR_CALLBACK callback,
void *callback_arg,
INT8U *pname,
INT8U *perr)
{
OS_TMR *ptmr;
#if OS_TMR_CFG_NAME_SIZE > 0
INT8U len;
#endif
#if OS_ARG_CHK_EN > 0
if (perr == (INT8U *)0) { /* Validate arguments */
return ((OS_TMR *)0);
}
switch (opt) {
case OS_TMR_OPT_PERIODIC:
if (period == 0) {
*perr = OS_ERR_TMR_INVALID_PERIOD;
return ((OS_TMR *)0);
}
break;
case OS_TMR_OPT_ONE_SHOT:
if (dly == 0) {
*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 > 0) { /* See if trying to call from an ISR */
*perr = OS_ERR_TMR_ISR;
return ((OS_TMR *)0);
}
OSTmr_Lock();
ptmr = OSTmr_Alloc(); /* Obtain a timer from the free pool */
if (ptmr == (OS_TMR *)0) {
OSTmr_Unlock();
*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_SIZE > 0
if (pname !=(INT8U *)0) {
len = OS_StrLen(pname); /* Copy timer name */
if (len < OS_TMR_CFG_NAME_SIZE) {
(void)OS_StrCopy(ptmr->OSTmrName, pname);
} else {
#if OS_TMR_CFG_NAME_SIZE > 1
ptmr->OSTmrName[0] = '#'; /* Invalid size specified */
ptmr->OSTmrName[1] = OS_ASCII_NUL;
#endif
*perr = OS_ERR_TMR_NAME_TOO_LONG;
OSTmr_Unlock();
return (ptmr);
}
}
#endif
OSTmr_Unlock();
*perr = OS_NO_ERR;
return (ptmr);
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* 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_NO_ERR
* 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 > 0
BOOLEAN OSTmrDel (OS_TMR *ptmr,
INT8U *perr)
{
#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 */
OSTmr_Free(ptmr); /* Return timer to free list of timers */
OSTmr_Unlock();
*perr = OS_NO_ERR;
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 */
OSTmr_Unlock();
*perr = OS_NO_ERR;
return (OS_TRUE);
case OS_TMR_STATE_UNUSED: /* Already deleted */
OSTmr_Unlock();
*perr = OS_ERR_TMR_INACTIVE;
return (OS_FALSE);
default:
OSTmr_Unlock();
*perr = OS_ERR_TMR_INVALID_STATE;
return (OS_FALSE);
}
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* 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 where the name of the timer will be placed. It is the caller's responsibility
* to ensure that he has sufficient storage in the destination, i.e. at least OS_TMR_CFG_NAME_SIZE
*
* perr Is a pointer to an error code. '*perr' will contain one of the following:
* OS_NO_ERR 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_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 length of the string or 0 if the timer does not exist.
************************************************************************************************************************
*/
#if OS_TMR_EN > 0 && OS_TMR_CFG_NAME_SIZE > 0
INT8U OSTmrNameGet (OS_TMR *ptmr,
INT8U *pdest,
INT8U *perr)
{
INT8U len;
#if OS_ARG_CHK_EN > 0
if (perr == (INT8U *)0) {
return (0);
}
if (pdest == (INT8U *)0) {
*perr = OS_ERR_TMR_INVALID_DEST;
return (0);
}
if (ptmr == (OS_TMR *)0) {
*perr = OS_ERR_TMR_INVALID;
return (0);
}
#endif
if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */
*perr = OS_ERR_TMR_INVALID_TYPE;
return (0);
}
if (OSIntNesting > 0) { /* See if trying to call from an ISR */
*perr = OS_ERR_TMR_ISR;
return (0);
}
OSTmr_Lock();
switch (ptmr->OSTmrState) {
case OS_TMR_STATE_RUNNING:
case OS_TMR_STATE_STOPPED:
case OS_TMR_STATE_COMPLETED:
len = OS_StrCopy(pdest, ptmr->OSTmrName);
OSTmr_Unlock();
*perr = OS_NO_ERR;
return (len);
case OS_TMR_STATE_UNUSED: /* Timer is not allocated */
OSTmr_Unlock();
*perr = OS_ERR_TMR_INACTIVE;
return (0);
default:
OSTmr_Unlock();
*perr = OS_ERR_TMR_INVALID_STATE;
return (0);
}
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* 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_NO_ERR
* 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.
************************************************************************************************************************
*/
#if OS_TMR_EN > 0
INT32U OSTmrRemainGet (OS_TMR *ptmr,
INT8U *perr)
{
INT32U remain;
#if OS_ARG_CHK_EN > 0
if (perr == (INT8U *)0) {
return (0);
}
if (ptmr == (OS_TMR *)0) {
*perr = OS_ERR_TMR_INVALID;
return (0);
}
#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -