📄 os_tmr.c
字号:
/*
************************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2009-2011; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* TIMER MANAGEMENT
*
* File : OS_TMR.C
* By : JJL
* Version : V3.02.00
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
* product then, you need to contact Micrium to properly license uC/OS-III for its use in your
* application/product. We provide ALL the source code for your convenience and to help you
* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
* it commercially 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 contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
************************************************************************************************************************
*/
#include <os.h>
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_tmr__c = "$Id: $";
#endif
#if OS_CFG_TMR_EN > 0u
/*
************************************************************************************************************************
* CONSTANTS
************************************************************************************************************************
*/
#define OS_OPT_LINK_DLY (OS_OPT)(0u)
#define OS_OPT_LINK_PERIODIC (OS_OPT)(1u)
/*$PAGE*/
/*
************************************************************************************************************************
* CREATE A TIMER
*
* Description: This function is called by your application code to create a timer.
*
* Arguments : p_tmr Is a pointer to a timer control block
*
* p_name Is a pointer to an ASCII string that is used to name the timer. Names are useful for
* debugging.
*
* 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_OPT_TMR_PERIODIC' as an option, when the timer expires, it will
* automatically restart with the same period.
*
* opt Specifies either:
*
* OS_OPT_TMR_ONE_SHOT The timer counts down only once
* OS_OPT_TMR_PERIODIC The timer counts down and then reloads itself
*
* p_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 *p_tmr, void *p_arg);
*
* p_callback_arg Is an argument (a pointer) that is passed to the callback function when it is called.
*
* p_err Is a pointer to an error code. '*p_err' will contain one of the following:
*
* OS_ERR_NONE
* OS_ERR_ILLEGAL_CREATE_RUN_TIME if you are trying to create the timer after you called
* OSSafetyCriticalStart().
* OS_ERR_OBJ_CREATED if the timer has already been created
* OS_ERR_OBJ_PTR_NULL is 'p_tmr' is a NULL pointer
* OS_ERR_OBJ_TYPE if the object type is invalid
* OS_ERR_OPT_INVALID you specified an invalid option
* OS_ERR_TMR_INVALID_DLY you specified an invalid delay
* OS_ERR_TMR_INVALID_PERIOD you specified an invalid period
* OS_ERR_TMR_ISR if the call was made from an ISR
*
* Returns : none
*
* Note(s) : 1) This function only creates the timer. In other words, the timer is not started when created. To
* start the timer, call OSTmrStart().
************************************************************************************************************************
*/
void OSTmrCreate (OS_TMR *p_tmr,
CPU_CHAR *p_name,
OS_TICK dly,
OS_TICK period,
OS_OPT opt,
OS_TMR_CALLBACK_PTR p_callback,
void *p_callback_arg,
OS_ERR *p_err)
{
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#ifdef OS_SAFETY_CRITICAL_IEC61508
if (OSSafetyCriticalStartFlag == DEF_TRUE) {
*p_err = OS_ERR_ILLEGAL_CREATE_RUN_TIME;
return;
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* See if trying to call from an ISR */
*p_err = OS_ERR_TMR_ISR;
return;
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_tmr == (OS_TMR *)0) { /* Validate 'p_tmr' */
*p_err = OS_ERR_OBJ_PTR_NULL;
return;
}
switch (opt) {
case OS_OPT_TMR_PERIODIC:
if (period == (OS_TICK)0) {
*p_err = OS_ERR_TMR_INVALID_PERIOD;
return;
}
break;
case OS_OPT_TMR_ONE_SHOT:
if (dly == (OS_TICK)0) {
*p_err = OS_ERR_TMR_INVALID_DLY;
return;
}
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return;
}
#endif
CPU_CRITICAL_ENTER();
p_tmr->State = (OS_STATE )OS_TMR_STATE_STOPPED; /* Initialize the timer fields */
p_tmr->Type = (OS_OBJ_TYPE )OS_OBJ_TYPE_TMR;
p_tmr->NamePtr = (CPU_CHAR *)p_name;
p_tmr->Dly = (OS_TICK )dly;
p_tmr->Match = (OS_TICK )0;
p_tmr->Remain = (OS_TICK )0;
p_tmr->Period = (OS_TICK )period;
p_tmr->Opt = (OS_OPT )opt;
p_tmr->CallbackPtr = (OS_TMR_CALLBACK_PTR)p_callback;
p_tmr->CallbackPtrArg = (void *)p_callback_arg;
p_tmr->NextPtr = (OS_TMR *)0;
p_tmr->PrevPtr = (OS_TMR *)0;
#if OS_CFG_DBG_EN > 0u
OS_TmrDbgListAdd(p_tmr);
#endif
OSTmrQty++; /* Keep track of the number of timers created */
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
}
/*$PAGE*/
/*
************************************************************************************************************************
* DELETE A TIMER
*
* Description: This function is called by your application code to delete a timer.
*
* Arguments : p_tmr Is a pointer to the timer to stop and delete.
*
* p_err Is a pointer to an error code. '*p_err' will contain one of the following:
*
* OS_ERR_NONE
* OS_ERR_OBJ_TYPE 'p_tmr' is not pointing to a timer
* OS_ERR_TMR_INVALID 'p_tmr' is a NULL pointer
* 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 : DEF_TRUE if the timer was deleted
* DEF_FALSE if not or upon an error
************************************************************************************************************************
*/
#if OS_CFG_TMR_DEL_EN > 0u
CPU_BOOLEAN OSTmrDel (OS_TMR *p_tmr,
OS_ERR *p_err)
{
OS_ERR err;
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return (DEF_FALSE);
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* See if trying to call from an ISR */
*p_err = OS_ERR_TMR_ISR;
return (DEF_FALSE);
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_tmr == (OS_TMR *)0) {
*p_err = OS_ERR_TMR_INVALID;
return (DEF_FALSE);
}
#endif
#if OS_CFG_OBJ_TYPE_CHK_EN > 0u
if (p_tmr->Type != OS_OBJ_TYPE_TMR) { /* Make sure timer was created */
*p_err = OS_ERR_OBJ_TYPE;
return (DEF_FALSE);
}
#endif
OSSchedLock(&err);
#if OS_CFG_DBG_EN > 0u
OS_TmrDbgListRemove(p_tmr);
#endif
OSTmrQty--; /* One less timer */
switch (p_tmr->State) {
case OS_TMR_STATE_RUNNING:
OS_TmrUnlink(p_tmr); /* Remove from current wheel spoke */
OS_TmrClr(p_tmr);
OSSchedUnlock(&err);
*p_err = OS_ERR_NONE;
return (DEF_TRUE);
case OS_TMR_STATE_STOPPED: /* Timer has not started or ... */
case OS_TMR_STATE_COMPLETED: /* ... timer has completed the ONE-SHOT time */
OS_TmrClr(p_tmr); /* Clear timer fields */
OSSchedUnlock(&err);
*p_err = OS_ERR_NONE;
return (DEF_TRUE);
case OS_TMR_STATE_UNUSED: /* Already deleted */
OSSchedUnlock(&err);
*p_err = OS_ERR_TMR_INACTIVE;
return (DEF_FALSE);
default:
OSSchedUnlock(&err);
*p_err = OS_ERR_TMR_INVALID_STATE;
return (DEF_FALSE);
}
}
#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 : p_tmr Is a pointer to the timer to obtain the remaining time from.
*
* p_err Is a pointer to an error code. '*p_err' will contain one of the following:
*
* OS_ERR_NONE
* OS_ERR_OBJ_TYPE 'p_tmr' is not pointing to a timer
* OS_ERR_TMR_INVALID 'p_tmr' is a NULL pointer
* OS_ERR_TMR_ISR if the call was made from an ISR
* OS_ERR_TMR_INACTIVE 'p_tmr' 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
* OS_TmrTask() 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.
************************************************************************************************************************
*/
OS_TICK OSTmrRemainGet (OS_TMR *p_tmr,
OS_ERR *p_err)
{
OS_TICK remain;
OS_ERR err;
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((OS_TICK)0);
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* See if trying to call from an ISR */
*p_err = OS_ERR_TMR_ISR;
return ((OS_TICK)0);
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_tmr == (OS_TMR *)0) {
*p_err = OS_ERR_TMR_INVALID;
return ((OS_TICK)0);
}
#endif
#if OS_CFG_OBJ_TYPE_CHK_EN > 0u
if (p_tmr->Type != OS_OBJ_TYPE_TMR) { /* Make sure timer was created */
*p_err = OS_ERR_OBJ_TYPE;
return ((OS_TICK)0);
}
#endif
OSSchedLock(&err);
switch (p_tmr->State) {
case OS_TMR_STATE_RUNNING:
remain = p_tmr->Match /* Determine how much time is left to timeout */
- OSTmrTickCtr;
p_tmr->Remain = remain;
OSSchedUnlock(&err);
*p_err = OS_ERR_NONE;
return (remain);
case OS_TMR_STATE_STOPPED: /* It's assumed that the timer has not started yet */
if (p_tmr->Opt == OS_OPT_TMR_PERIODIC) {
if (p_tmr->Dly == 0u) {
remain = p_tmr->Period;
} else {
remain = p_tmr->Dly;
}
} else {
remain = p_tmr->Dly;
}
p_tmr->Remain = remain;
OSSchedUnlock(&err);
*p_err = OS_ERR_NONE;
return (remain);
case OS_TMR_STATE_COMPLETED: /* Only ONE-SHOT that timed out can be in this state */
OSSchedUnlock(&err);
*p_err = OS_ERR_NONE;
return ((OS_TICK)0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -