⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timerlib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 2 页
字号:
* RETURNS: 0 (OK), or -1 (ERROR) if <timerid> is invalid.** ERRNO: EINVAL*/int timer_gettime    (    timer_t           timerid,	 /* timer ID                       */    struct itimerspec *value	 /* where to return remaining time */    )    {    struct timespec now; 	 /* current time */     struct timespec timerExpire; /* absolute time that timer will go off */    if (timerid == NULL || value == NULL)	{	errno = EINVAL;	return (ERROR);	}    if (timerid->clock_id != CLOCK_REALTIME)	{	errno = EINVAL;	return (ERROR);	}    /* if timer is disarmed simply set value to 0 */    if (timerid->active == FALSE)        {        value->it_value.tv_sec = 0;        value->it_value.tv_nsec = 0;        value->it_interval.tv_sec = 0;        value->it_interval.tv_nsec = 0;        return (OK);        }    /* get current time */    if (clock_gettime (CLOCK_REALTIME, &now) == ERROR)	return (ERROR);;    /* use time stamp and get absolute time that timer will go off */    timerExpire.tv_sec = timerid->timeStamp.tv_sec + timerid->exp.it_value.tv_sec;    timerExpire.tv_nsec = timerid->timeStamp.tv_nsec + timerid->exp.it_value.tv_nsec;    TV_NORMALIZE (timerExpire);    /* compute difference using current time */    value->it_value.tv_sec = timerExpire.tv_sec - now.tv_sec;    value->it_value.tv_nsec = timerExpire.tv_nsec - now.tv_nsec;    TV_NORMALIZE (value->it_value);    /* get reload value */    value->it_interval.tv_sec = timerid->exp.it_interval.tv_sec;    value->it_interval.tv_nsec = timerid->exp.it_interval.tv_nsec;    TV_NORMALIZE (value->it_interval);    return (OK);    }/********************************************************************************* timer_getoverrun - return the timer expiration overrun (POSIX)** This routine returns the timer expiration overrun count for <timerid>,* when called from a timer expiration signal catcher.  The overrun count is* the number of extra timer expirations that have occurred, up to the* implementation-defined maximum _POSIX_DELAYTIMER_MAX.  If the count is* greater than the maximum, it returns the maximum.** RETURNS:* The number of overruns, or _POSIX_DELAYTIMER_MAX if the count equals or is* greater than _POSIX_DELAYTIMER_MAX, or -1 (ERROR) if <timerid> is invalid.** ERRNO: EINVAL, ENOSYS*/int timer_getoverrun    (    timer_t timerid	/* timer ID */    )    {    if (timerid == NULL)	{	errno = EINVAL;	return (ERROR);	}    return (timerid->sigpend.sigp_overruns);    }/********************************************************************************* timerWdHandler -*/LOCAL void timerWdHandler    (    timer_t timerid    )    {    ULONG delayTicks;    int status;    if (timerid == NULL)	{	if (timerLibLog)	    logMsg ("timerWdHandler: NULL timerid!\n", 0, 0, 0, 0, 0, 0);	return;	}    status = sigPendKill (timerid->taskId, &timerid->sigpend);    if (status != OK && timerLibLog)	{	logMsg ("timerWdHandler: kill failed (timer=%#x, tid=%#x, errno=%#x)\n",		(int)timerid, timerid->taskId, errno, 0, 0, 0);	}    if (TV_ISZERO(timerid->exp.it_interval))	{	timerid->active = FALSE;	}    else	{	/* interval timer needs reloading */	TV_CONVERT_TO_TICK (delayTicks, timerid->exp.it_interval);	if (delayTicks < 1)	    delayTicks = 1;	/* delay of 0 will cause recursion! */	/* time stamp when we arm interval timer */	(void) clock_gettime (CLOCK_REALTIME, &(timerid->timeStamp));	wdStart (timerid->wdog, (int)delayTicks, (FUNCPTR)timerWdHandler,		(int)timerid);	}    }/********************************************************************************* timer_settime - set the time until the next expiration and arm timer (POSIX)** This routine sets the next expiration of the timer, using the `.it_value'* of <value>, thus arming the timer.  If the timer is already armed, this* call resets the time until the next expiration.  If `.it_value' is zero,* the timer is disarmed.** If <flags> is not equal to TIMER_ABSTIME, the interval is relative to the* current time, the interval being the `.it_value' of the <value> parameter.* If <flags> is equal to TIMER_ABSTIME, the expiration is set to* the difference between the absolute time of `.it_value' and the current* value of the clock associated with <timerid>.  If the time has already* passed, then the timer expiration notification is made immediately.* The task that sets the timer receives the signal; in other words, the taskId* is noted.  If a timer is set by an ISR, the signal is delivered to the* task that created the timer.** The reload value of the timer is set to the value specified by* the `.it_interval' field of <value>.  When a timer is* armed with a nonzero `.it_interval' a periodic timer is set up.** Time values that are between two consecutive non-negative integer* multiples of the resolution of the specified timer are rounded up to* the larger multiple of the resolution.** If <ovalue> is non-NULL, the routine stores a value representing the* previous amount of time before the timer would have expired.  Or if the* timer is disarmed, the routine stores zero, together with the previous* timer reload value.  The <ovalue> parameter is the same value as that * returned by timer_gettime() and is subject to the timer resolution.** WARNING* If clock_settime() is called to reset the absolute clock time after a timer* has been set with timer_settime(), and if <flags> is equal to TIMER_ABSTIME, * then the timer will behave unpredictably.  If you must reset the absolute* clock time after setting a timer, do not use <flags> equal to TIMER_ABSTIME.** RETURNS:* 0 (OK), or -1 (ERROR) if <timerid> is invalid, the number of nanoseconds * specified by <value> is less than 0 or greater than or equal to * 1,000,000,000, or the time specified by <value> exceeds the maximum * allowed by the timer.** ERRNO: EINVAL*/int timer_settime    (    timer_t                 timerid,	/* timer ID                           */    int                     flags,	/* absolute or relative               */    const struct itimerspec *value,	/* time to be set                     */    struct itimerspec       *ovalue	/* previous time set (NULL=no result) */    )    {    struct timespec now;    ULONG delayTicks;    if (timerid == NULL)	{	errno = EINVAL;	return (ERROR);	}    if (timerid->clock_id != CLOCK_REALTIME || !TV_VALID(value->it_value))	{	errno = EINVAL;	return (ERROR);	}    if (ovalue != NULL)	{	/* remainder (should already be zero if disarmed) */	TV_SET(ovalue->it_value, timerid->exp.it_value);	TV_SET(ovalue->it_interval, timerid->exp.it_interval);	}    if (TV_ISZERO(value->it_value))	{	if (timerid->active)	    {	    timerid->active = FALSE;	    wdCancel (timerid->wdog);	    }	return (OK);	}    TV_SET(timerid->exp.it_interval, value->it_interval);    TV_SET(timerid->exp.it_value, value->it_value);    if (flags == TIMER_ABSTIME)	{	/* convert current to relative time */	(void) clock_gettime (CLOCK_REALTIME, &now);	/* could be in the past */	if (TV_GT(now, timerid->exp.it_value))	    {	    TV_ZERO(timerid->exp.it_value);	    }	else	    {    	    TV_SUB(timerid->exp.it_value, now);	    }	/* time stamp when timer is armed */	TV_SET (timerid->timeStamp, now);	}    else	/* time stamp when timer is armed */	(void) clock_gettime (CLOCK_REALTIME, &(timerid->timeStamp));    TV_CONVERT_TO_TICK (delayTicks, timerid->exp.it_value);    if (timerid->active)	wdCancel (timerid->wdog);    else	timerid->active = TRUE;    wdStart (timerid->wdog, delayTicks, (FUNCPTR)timerWdHandler, (int)timerid);    return (OK);    }/********************************************************************************* timer_show - show information on a specified timer** WARNING* Non-POSIX.** RETURNS: 0 (OK), or -1 (ERROR) if <timerid> is invalid, or the context is * invalid.** ERRNO: EINVAL** NOMANUAL*/int timer_show    (    timer_t timerid	/* timer ID */    )    {    static char *title1 = "task       timerid    evp        routine\n";    static char *title2 = "---------- ---------- ---------- ----------\n";    if (intContext ())	return (ERROR);    if (timerid == NULL)	return (OK);    printf (title1);    printf (title2);    printf ("%#10x %#10x %#10x %#10x\n", timerid->taskId, (unsigned int)timerid,		(unsigned int)&timerid->sevent, (unsigned int)timerid->routine);    return (OK);    }/********************************************************************************* nanosleep - suspend the current task until the time interval elapses (POSIX)** This routine suspends the current task for a specified time <rqtp>* or until a signal or event notification is made.** The suspension may be longer than requested due to the rounding up of the* request to the timer's resolution or to other scheduling activities (e.g.,* a higher priority task intervenes).** If <rmtp> is non-NULL, the `timespec' structure is updated to contain the* amount of time remaining.  If <rmtp> is NULL, the remaining time is not* returned.  The <rqtp> parameter is greater than 0 or less than or equal to* 1,000,000,000.** RETURNS:* 0 (OK), or -1 (ERROR) if the routine is interrupted by a signal or an * asynchronous event notification, or <rqtp> is invalid.** ERRNO: EINVAL, EINTR** SEE ALSO: taskDelay()*/int nanosleep    (    const struct timespec *rqtp,	/* time to delay                     */    struct timespec       *rmtp		/* premature wakeup (NULL=no result) */    )    {    int status;    /* int oldErrno; */    ULONG delayTicks;    struct timespec then;    struct timespec now;    int returnStatus;    if (rqtp == NULL || !TV_VALID(*rqtp))	{	errno = EINVAL;	return (ERROR);	}    if (TV_ISZERO(*rqtp))	return (OK);    (void)clockLibInit (); /* make sure clock "running" */    (void)clock_gettime (CLOCK_REALTIME, &then);    TV_CONVERT_TO_TICK (delayTicks, *rqtp);    /* return's 1 (RESTART) if interrupted sleep */    status = taskDelay (delayTicks);    if (status == 0)	returnStatus = 0;    else	returnStatus = -1;    if (rmtp != NULL)	{	(void)clock_gettime (CLOCK_REALTIME, &now);	TV_SUB (now, then);	/* make time relative to start */	if (TV_LT(now, *rqtp))	    {	    TV_SET(*rmtp, *rqtp);	    TV_SUB(*rmtp, now);	    }	else	    TV_ZERO((*rmtp));	}    return (returnStatus);    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -