Added support for POSIX timers
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@111 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
parent
a9a8941d93
commit
b3a170538f
|
@ -65,7 +65,7 @@
|
|||
* Eliminate compilation warnings that that crept into
|
||||
recent check-ins
|
||||
* Add kill()
|
||||
* Added the framework to support POSIX timers (more to be done)
|
||||
* Added support for POSIX timers
|
||||
* Some Documentation updates
|
||||
* Added support for the Neuros OSD / DM320
|
||||
|
||||
|
|
|
@ -867,7 +867,7 @@ below and discussed in the following paragraphs:</p>
|
|||
</ul>
|
||||
|
||||
<ul>
|
||||
<code>CONFIG_DISABLE_CLOCK</code>, <code>CONFIG_DISABLE_PTHREAD</code>,
|
||||
<code>CONFIG_DISABLE_CLOCK</code>, <code>CONFI_DISABLE_POSIX_TIMERS</code>, <code>CONFIG_DISABLE_PTHREAD</code>,
|
||||
<code>CONFIG_DISABLE_SIGNALS</code>, <code>CONFIG_DISABLE_MQUEUE</code>,
|
||||
</ul>
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ User's Manual
|
|||
<P>
|
||||
Gregory Nutt
|
||||
<P>
|
||||
<SMALL>Last Update: January 28, 2007</SMALL>
|
||||
<SMALL>Last Update: March 21, 2007</SMALL>
|
||||
</CENTER>
|
||||
|
||||
<H1>1.0 <A NAME="Introduction">Introduction</A></H1>
|
||||
|
@ -37,7 +37,7 @@ perspective of the firmware developer. This section is divided
|
|||
into several paragraphs that describe different groups of OS interfaces:
|
||||
<UL>
|
||||
<LI>Paragraph 2.1 <A HREF="#Task_Control">Task Control Interfaces</A>
|
||||
8nnnnn<LI>Paragraph 2.2 <A HREF="#Task_Schedule">Task Scheduling Interfaces</A>
|
||||
<LI>Paragraph 2.2 <A HREF="#Task_Schedule">Task Scheduling Interfaces</A>
|
||||
<LI>Paragraph 2.3 <A HREF="#Task_Switch">Task Switching Interfaces</A>
|
||||
<LI>Paragraph 2.4 <A HREF="#Message_Queue">Named Message Queue Interfaces</A>
|
||||
<LI>Paragraph 2.5 <A HREF="#Semaphores">Counting Semaphore Interfaces</A>
|
||||
|
@ -1840,6 +1840,7 @@ interface of the same name.
|
|||
<li><a href="#wddelete">2.6.2 wd_delete</a></li>
|
||||
<li><a href="#wdstart">2.6.3 wd_start</a></li>
|
||||
<li><a href="#wdcancel">2.6.4 wd_cancel</a></li>
|
||||
<li><a href="#wdgettime">2.6.5 wd_gettime</a></li>
|
||||
</ul>
|
||||
|
||||
<H3><a name="wdcreate">2.6.1 wd_create</a></H3>
|
||||
|
@ -2017,6 +2018,30 @@ VxWorks provides the following comparable interface:
|
|||
STATUS wdCancel (WDOG_ID wdog);
|
||||
</PRE>
|
||||
|
||||
<h3><a name="wdgettime">2.6.5 wd_gettime</a></h3>
|
||||
<p>
|
||||
<b>Function Prototype:</b>
|
||||
</p>
|
||||
<pre>
|
||||
#include <wdog.h>
|
||||
Sint wd_gettime(WDOG_ID wdog);
|
||||
</pre>
|
||||
<p>
|
||||
<b>Description:</b>
|
||||
This function returns the time remaining before the the specified watchdog expires.
|
||||
</p>
|
||||
<p>
|
||||
<b>Input Parameters:</b>
|
||||
<ul>
|
||||
<li><code>wdog</code>. Identifies the watchdog that the request is for.</li>
|
||||
</ul>
|
||||
</p>
|
||||
<p>
|
||||
<b>Returned Value:</b>
|
||||
The time in system ticks remaining until the watchdog time expires. Zero
|
||||
means either that wdog is not valid or that the wdog has already expired.
|
||||
</p>
|
||||
|
||||
<HR>
|
||||
|
||||
<H2><A NAME="ClocksNTimers">2.7 Clocks and Timers</A></H2>
|
||||
|
@ -2217,7 +2242,8 @@ VxWorks provides the following comparable interface:
|
|||
<b>Input Parameters:</b>
|
||||
</p>
|
||||
<ul>
|
||||
<li><code>clockid</code>. Specifies the clock to use as the timing base.</li>
|
||||
<li><code>clockid</code>. Specifies the clock to use as the timing base.
|
||||
Must be <code>CLOCK_REALTIME</code>.</li>
|
||||
<li><code>evp</code>. Refers to a user allocated sigevent structure that defines the
|
||||
asynchronous notification. evp may be NULL (see above).</li>
|
||||
<li><code>timerid</code>. The pre-thread timer created by the call to timer_create().</li>
|
||||
|
@ -2241,6 +2267,13 @@ VxWorks provides the following comparable interface:
|
|||
to the CPU-time clock that is specified by clock_id and associated with a
|
||||
thread different thread invoking timer_create().</li>
|
||||
</ul>
|
||||
<p>
|
||||
<b>POSIX Compatibility:</b>
|
||||
Comparable to the POSIX interface of the same name. Differences from the full POSIX implementation include:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Only <code>CLOCK_REALTIME</code> is supported for the <code>clockid</code> argument.</li>
|
||||
</ul>
|
||||
|
||||
<H3><a name="timerdelete">2.7.8 timer_delete</A></H3>
|
||||
<p>
|
||||
|
@ -2275,6 +2308,10 @@ VxWorks provides the following comparable interface:
|
|||
<ul>
|
||||
<li><code>EINVAL</code>. The timer specified timerid is not valid.</li>
|
||||
</ul>
|
||||
<p>
|
||||
<b>POSIX Compatibility:</b>
|
||||
Comparable to the POSIX interface of the same name.
|
||||
</p>
|
||||
|
||||
<H3><a name="timersettime">2.7.9 timer_settime</A></H3>
|
||||
<p>
|
||||
|
@ -2326,6 +2363,8 @@ VxWorks provides the following comparable interface:
|
|||
amount of time before the timer would have expired, or zero if the timer was
|
||||
disarmed, together with the previous timer reload value. Timers will not
|
||||
expire before their scheduled time.
|
||||
</p>
|
||||
<b>NOTE:</b>At present, the <code>ovalue</code> argument is ignored.
|
||||
</p>
|
||||
<p>
|
||||
<b>Input Parameters:</b>
|
||||
|
@ -2334,7 +2373,7 @@ VxWorks provides the following comparable interface:
|
|||
<li><code>timerid</code>. The pre-thread timer, previously created by the call to timer_create(), to be be set.</li>
|
||||
<li><code>flags</code>. Specifie characteristics of the timer (see above)</li>
|
||||
<li><code>value</code>. Specifies the timer value to set</li>
|
||||
<li><code>ovalue</code>. A location in which to return the time remaining from the previous timer setting.</li>
|
||||
<li><code>ovalue</code>. A location in which to return the time remaining from the previous timer setting (ignored).</li>
|
||||
</ul>
|
||||
<p>
|
||||
<b>Returned Values:</b>
|
||||
|
@ -2348,6 +2387,13 @@ VxWorks provides the following comparable interface:
|
|||
<li><code>EINVAL</code>. A value structure specified a nanosecond value less than zero or greater than or equal to 1000 million,
|
||||
and the it_value member of that structure did not specify zero seconds and nanoseconds.</li>
|
||||
</ul>
|
||||
<p>
|
||||
<b>POSIX Compatibility:</b>
|
||||
Comparable to the POSIX interface of the same name. Differences from the full POSIX implementation include:
|
||||
</p>
|
||||
<ul>
|
||||
<li>The <code>ovalue</code> argument is ignored.</li>
|
||||
</ul>
|
||||
|
||||
<H3><a name="timergettime">2.7.10 timer_gettime</A></H3>
|
||||
<p>
|
||||
|
@ -2367,6 +2413,11 @@ VxWorks provides the following comparable interface:
|
|||
even if the timer was armed with absolute time. The <code>it_interval</code> member of
|
||||
<code>value</code> will contain the reload value last set by <code>timer_settime()</code>.
|
||||
</p>
|
||||
<p>
|
||||
Due to the asynchronous operation of this function, the time reported
|
||||
by this function could be significantly more than that actual time
|
||||
remaining on the timer at any time.
|
||||
</p>
|
||||
<p>
|
||||
<b>Input Parameters:</b>
|
||||
</p>
|
||||
|
@ -2386,6 +2437,10 @@ VxWorks provides the following comparable interface:
|
|||
The <code>timerid</code> argument does not correspond to an ID returned by
|
||||
<code>timer_create()</code> but not yet deleted by <code>timer_delete()</code>.</li>
|
||||
</ul>
|
||||
<p>
|
||||
<b>POSIX Compatibility:</b>
|
||||
Comparable to the POSIX interface of the same name.
|
||||
</p>
|
||||
|
||||
<H3><a name="timergetoverrun">2.7.11 timer_getoverrun</A></H3>
|
||||
<p>
|
||||
|
@ -2414,6 +2469,9 @@ VxWorks provides the following comparable interface:
|
|||
for the timer, or if the <i>Realtime Signals Extension</i> is not supported, the
|
||||
return value of <code>timer_getoverrun()</code> is unspecified.
|
||||
</p>
|
||||
<p>
|
||||
<b>NOTE:</b> This interface is not currently implemented in NuttX.
|
||||
</p>
|
||||
<p>
|
||||
<b>Input Parameters:</b>
|
||||
</p>
|
||||
|
@ -2431,6 +2489,13 @@ VxWorks provides the following comparable interface:
|
|||
The <code>timerid</code> argument does not correspond to an ID returned by
|
||||
<code>timer_create()</code> but not yet deleted by <code>timer_delete()</code>.</li>
|
||||
</ul>
|
||||
<p>
|
||||
<b>POSIX Compatibility:</b>
|
||||
Comparable to the POSIX interface of the same name. Differences from the full POSIX implementation include:
|
||||
</p>
|
||||
<ul>
|
||||
<li>This interface is not currently implemented by NuttX.</li>
|
||||
</ul>
|
||||
|
||||
<B>Assumptions/Limitations:</B>
|
||||
<P>
|
||||
|
@ -4925,6 +4990,7 @@ notify a task when a message is available on a queue.
|
|||
<li><a href="#wdcancel">wd_cancel</a></li>
|
||||
<li><a href="#wdcreate">wd_create</a></li>
|
||||
<li><a href="#wddelete">wd_delete</a></li>
|
||||
<li><a href="#wdgettime">wd_gettime</a></li>
|
||||
<li><a href="#wdstart">wd_start</a></li>
|
||||
</ul>
|
||||
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
NuttX TODO List
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Task/Scheduler
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
- When a tasks exits, shouldn't all of its child pthreads also be terminated?
|
||||
- Should task_delete() cause atexit() function to be called?
|
||||
- Implement sys/mman.h and functions
|
||||
- Implement sys/wait.h and functions
|
||||
- Implement priority inheritance
|
||||
- Implement vfork(). Could be tricky because of stack references.
|
||||
- Make the system timer frequency configurable via defconfig. See:
|
||||
_POSIX_CLOCKRES_MIN in limits.h
|
||||
CLK_TCK in time.h
|
||||
Definitions in sched/clock_internal.h
|
||||
|
||||
o Memory Managment
|
||||
- Add an option to free all memory allocated by a task when the task exits.
|
||||
This may not be worth the overhead for a deeply embedded system.
|
||||
|
||||
o Signals
|
||||
- 'Standard' signals and signal actions are not supported. Does this
|
||||
make since in a deeply embedded system?
|
||||
|
||||
o pthreads
|
||||
- pthread_cancel(): Should implemenent cancellation points and pthread_testcancel()
|
||||
|
||||
o Libraries
|
||||
|
||||
o File system
|
||||
- This probabaly needs some rethinking.
|
||||
- Add some concept like mount points to handle mounted "real" filesystems.
|
||||
|
||||
o Console Output
|
||||
|
||||
o Documentation
|
||||
- Document fs & driver logic
|
||||
- Document filesystem, library
|
||||
|
||||
o Build system
|
||||
- Something leaves garbage link 'include' in arch/*/include
|
||||
- Separate configurations from architectures. arch/* contains
|
||||
generic logic. Like arch/armnommu, arch/arm, arch/805x, etc.
|
||||
config/* has like config/pjrc-8052, config/c5471, etc.
|
||||
|
||||
o Applications & Tests
|
||||
|
||||
o C5471
|
||||
- At present, there is a failure in the examples/ostest POSIX timer
|
||||
test when CONFIG_DEBUG is enabled. This is almost certainly yet
|
||||
another case where printf (or its kin) are being called from a
|
||||
sensitive area in the OS.
|
||||
|
||||
o pjrc-8052 / MCS51
|
||||
* Current status:
|
||||
- Basic OS task management seems OK
|
||||
- Fails when interrupts enabled. The stack pointer is around 0x6e
|
||||
before the failure occurs. It looks like some issue when the
|
||||
stack pointer moves from the directly to indirectly addressable
|
||||
region (0x80 boundary).
|
||||
- Work on the 8052 is temporarily on hold
|
||||
- Use timer 0 as system timer. Timer 2 is needed for second UART.
|
||||
Logic is implemented, but there needs to be a system configuration
|
||||
to change the ticks-per-second value to match the timer interrupt
|
||||
rate
|
||||
- During build, there are several integer overflows reported:
|
||||
gmtime_r.c aroud lines 184 and 185
|
||||
clock_initialize.c at line 107
|
||||
pthread_create.c at 330
|
||||
sighand.c at 225 and 244
|
||||
|
||||
o DM320
|
||||
- In progress
|
|
@ -108,7 +108,7 @@ defconfig -- This is a configuration file similar to the Linux
|
|||
o pthread_condtimedwait() depends on signals to wake
|
||||
up waiting tasks.
|
||||
|
||||
CONFIG_DISABLE_CLOCK, CONFIG_DISABLE_PTHREAD.
|
||||
CONFIG_DISABLE_CLOCK, CONFIG_DISABLE_POSIX_TIMERS, CONFIG_DISABLE_PTHREAD.
|
||||
CONFIG_DISABLE_SIGNALS, CONFIG_DISABLE_MQUEUE
|
||||
|
||||
|
||||
|
|
|
@ -138,6 +138,7 @@ CONFIG_DEV_CONSOLE=y
|
|||
# up waiting tasks.
|
||||
#
|
||||
CONFIG_DISABLE_CLOCK=n
|
||||
CONFIG_DISABLE_POSIX_TIMERS=n
|
||||
CONFIG_DISABLE_PTHREAD=n
|
||||
CONFIG_DISABLE_SIGNALS=n
|
||||
CONFIG_DISABLE_MQUEUE=n
|
||||
|
@ -207,6 +208,10 @@ CONFIG_RRLOAD_BINARY=y
|
|||
# CONFIG_PREALLOC_WDOGS - The number of pre-allocated watchdog
|
||||
# structures. The system manages a pool of preallocated
|
||||
# watchdog structures to minimize dynamic allocations
|
||||
# CONFIG_PREALLOC_TIMERS - The number of pre-allocated POSIX
|
||||
# timer structures. The system manages a pool of preallocated
|
||||
# timer structures to minimize dynamic allocations. Set to
|
||||
# zero for all dynamic allocations.
|
||||
#
|
||||
CONFIG_MAX_TASKS=64
|
||||
CONFIG_MAX_TASK_ARGS=4
|
||||
|
@ -220,6 +225,7 @@ CONFIG_PREALLOC_MQ_MSGS=32
|
|||
CONFIG_MQ_MAXMSGSIZE=32
|
||||
CONFIG_MAX_WDOGPARMS=4
|
||||
CONFIG_PREALLOC_WDOGS=32
|
||||
CONFIG_PREALLOC_TIMERS=8
|
||||
|
||||
#
|
||||
# Stack and heap information
|
||||
|
|
|
@ -135,6 +135,7 @@ CONFIG_DEV_CONSOLE=n
|
|||
# up waiting tasks.
|
||||
#
|
||||
CONFIG_DISABLE_CLOCK=n
|
||||
CONFIG_DISABLE_POSIX_TIMERS=n
|
||||
CONFIG_DISABLE_PTHREAD=n
|
||||
CONFIG_DISABLE_SIGNALS=n
|
||||
CONFIG_DISABLE_MQUEUE=n
|
||||
|
@ -204,6 +205,10 @@ CONFIG_RRLOAD_BINARY=y
|
|||
# CONFIG_PREALLOC_WDOGS - The number of pre-allocated watchdog
|
||||
# structures. The system manages a pool of preallocated
|
||||
# watchdog structures to minimize dynamic allocations
|
||||
# CONFIG_PREALLOC_TIMERS - The number of pre-allocated POSIX
|
||||
# timer structures. The system manages a pool of preallocated
|
||||
# timer structures to minimize dynamic allocations. Set to
|
||||
# zero for all dynamic allocations.
|
||||
#
|
||||
CONFIG_MAX_TASKS=64
|
||||
CONFIG_MAX_TASK_ARGS=4
|
||||
|
@ -217,6 +222,7 @@ CONFIG_PREALLOC_MQ_MSGS=32
|
|||
CONFIG_MQ_MAXMSGSIZE=32
|
||||
CONFIG_MAX_WDOGPARMS=4
|
||||
CONFIG_PREALLOC_WDOGS=32
|
||||
CONFIG_PREALLOC_TIMERS=8
|
||||
|
||||
#
|
||||
# Stack and heap information
|
||||
|
|
|
@ -39,7 +39,7 @@ SECTIONS
|
|||
{
|
||||
/* The OS entry point is here */
|
||||
|
||||
. = 0x01108000;
|
||||
. = 0x01008000;
|
||||
.text : {
|
||||
_stext = ABSOLUTE(.);
|
||||
*(.text)
|
||||
|
|
|
@ -132,6 +132,7 @@ CONFIG_DEV_CONSOLE=n
|
|||
# up waiting tasks.
|
||||
#
|
||||
CONFIG_DISABLE_CLOCK=y
|
||||
CONFIG_DISABLE_POSIX_TIMERS=y
|
||||
CONFIG_DISABLE_PTHREAD=y
|
||||
CONFIG_DISABLE_SIGNALS=y
|
||||
CONFIG_DISABLE_MQUEUE=y
|
||||
|
@ -201,6 +202,10 @@ CONFIG_RRLOAD_BINARY=n
|
|||
# CONFIG_PREALLOC_WDOGS - The number of pre-allocated watchdog
|
||||
# structures. The system manages a pool of preallocated
|
||||
# watchdog structures to minimize dynamic allocations
|
||||
# CONFIG_PREALLOC_TIMERS - The number of pre-allocated POSIX
|
||||
# timer structures. The system manages a pool of preallocated
|
||||
# timer structures to minimize dynamic allocations. Set to
|
||||
# zero for all dynamic allocations.
|
||||
#
|
||||
CONFIG_MAX_TASKS=8
|
||||
CONFIG_MAX_TASK_ARGS=4
|
||||
|
@ -214,6 +219,7 @@ CONFIG_PREALLOC_MQ_MSGS=0
|
|||
CONFIG_MQ_MAXMSGSIZE=0
|
||||
CONFIG_MAX_WDOGPARMS=2
|
||||
CONFIG_PREALLOC_WDOGS=4
|
||||
CONFIG_PREALLOC_TIMERS=0
|
||||
|
||||
#
|
||||
# Stack and heap information
|
||||
|
|
|
@ -98,6 +98,7 @@ CONFIG_DEV_CONSOLE=y
|
|||
# up waiting tasks.
|
||||
#
|
||||
CONFIG_DISABLE_CLOCK=n
|
||||
CONFIG_DISABLE_POSIX_TIMERS=n
|
||||
CONFIG_DISABLE_PTHREAD=n
|
||||
CONFIG_DISABLE_SIGNALS=n
|
||||
CONFIG_DISABLE_MQUEUE=n
|
||||
|
@ -167,6 +168,10 @@ CONFIG_RRLOAD_BINARY=n
|
|||
# CONFIG_PREALLOC_WDOGS - The number of pre-allocated watchdog
|
||||
# structures. The system manages a pool of preallocated
|
||||
# watchdog structures to minimize dynamic allocations
|
||||
# CONFIG_PREALLOC_TIMERS - The number of pre-allocated POSIX
|
||||
# timer structures. The system manages a pool of preallocated
|
||||
# timer structures to minimize dynamic allocations. Set to
|
||||
# zero for all dynamic allocations.
|
||||
#
|
||||
CONFIG_MAX_TASKS=64
|
||||
CONFIG_MAX_TASK_ARGS=4
|
||||
|
@ -180,6 +185,7 @@ CONFIG_PREALLOC_MQ_MSGS=32
|
|||
CONFIG_MQ_MAXMSGSIZE=32
|
||||
CONFIG_MAX_WDOGPARMS=4
|
||||
CONFIG_PREALLOC_WDOGS=32
|
||||
CONFIG_PREALLOC_TIMERS=8
|
||||
|
||||
#
|
||||
# Stack and heap information
|
||||
|
|
|
@ -55,6 +55,9 @@ ifneq ($(CONFIG_DISABLE_PTHREAD),y)
|
|||
CSRCS += mqueue.c
|
||||
endif
|
||||
endif
|
||||
ifneq ($(CONFIG_DISABLE_POSIX_TIMERS),y)
|
||||
CSRCS += posixtimer.c
|
||||
endif
|
||||
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
|
||||
|
|
|
@ -165,6 +165,12 @@ static int user_main(int argc, char *argv[])
|
|||
sighand_test();
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_DISABLE_POSIX_TIMERS) && !defined(CONFIG_DISABLE_SIGNALS)
|
||||
/* Verify posix timers */
|
||||
|
||||
timer_test();
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_DISABLE_PTHREAD) && CONFIG_RR_INTERVAL > 0
|
||||
/* Verify round robin scheduling */
|
||||
|
||||
|
|
|
@ -0,0 +1,245 @@
|
|||
/***********************************************************************
|
||||
* posixtimer.c
|
||||
*
|
||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <signal.h>
|
||||
#include <sched.h>
|
||||
#include <errno.h>
|
||||
#include "ostest.h"
|
||||
|
||||
#ifndef NULL
|
||||
# define NULL (void*)0
|
||||
#endif
|
||||
|
||||
#define MY_TIMER_SIGNAL 17
|
||||
#define SIGVALUE_INT 42
|
||||
|
||||
static sem_t sem;
|
||||
static int g_nsigreceived = 0;
|
||||
|
||||
static void timer_expiration(int signo, siginfo_t *info, void *ucontext)
|
||||
{
|
||||
sigset_t oldset;
|
||||
sigset_t allsigs;
|
||||
int status;
|
||||
|
||||
printf("timer_expiration: Received signal %d\n" , signo);
|
||||
|
||||
g_nsigreceived++;
|
||||
|
||||
/* Check signo */
|
||||
|
||||
if (signo != MY_TIMER_SIGNAL)
|
||||
{
|
||||
printf("timer_expiration: ERROR expected signo=%d\n" , MY_TIMER_SIGNAL);
|
||||
}
|
||||
|
||||
/* Check siginfo */
|
||||
|
||||
if (info->si_value.sival_int != SIGVALUE_INT)
|
||||
{
|
||||
printf("timer_expiration: ERROR sival_int=%d expected %d\n",
|
||||
info->si_value.sival_int, SIGVALUE_INT);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("timer_expiration: sival_int=%d\n" , info->si_value.sival_int);
|
||||
}
|
||||
|
||||
if (info->si_signo != MY_TIMER_SIGNAL)
|
||||
{
|
||||
printf("timer_expiration: ERROR expected si_signo=%d, got=%d\n",
|
||||
MY_TIMER_SIGNAL, info->si_signo);
|
||||
}
|
||||
|
||||
if (info->si_code == SI_TIMER)
|
||||
{
|
||||
printf("timer_expiration: si_code=%d (SI_TIMER)\n" , info->si_code);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("timer_expiration: ERROR si_code=%d, expected SI_TIMER=%d\n",
|
||||
info->si_code, SI_TIMER);
|
||||
}
|
||||
|
||||
/* Check ucontext_t */
|
||||
|
||||
printf("timer_expiration: ucontext=%p\n" , ucontext);
|
||||
|
||||
/* Check sigprocmask */
|
||||
|
||||
(void)sigfillset(&allsigs);
|
||||
status = sigprocmask(SIG_SETMASK, NULL, &oldset);
|
||||
if (status != OK)
|
||||
{
|
||||
printf("timer_expiration: ERROR sigprocmask failed, status=%d\n",
|
||||
status);
|
||||
}
|
||||
|
||||
if (oldset != allsigs)
|
||||
{
|
||||
printf("timer_expiration: ERROR sigprocmask=%x expected=%x\n",
|
||||
oldset, allsigs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void timer_test(void)
|
||||
{
|
||||
struct sched_param param;
|
||||
sigset_t sigset;
|
||||
struct sigaction act;
|
||||
struct sigaction oact;
|
||||
struct sigevent notify;
|
||||
struct itimerspec timer;
|
||||
timer_t timerid;
|
||||
int status;
|
||||
int i;
|
||||
|
||||
printf("timer_test: Initializing semaphore to 0\n" );
|
||||
sem_init(&sem, 0, 0);
|
||||
|
||||
/* Start waiter thread */
|
||||
|
||||
printf("timer_test: Unmasking signal %d\n" , MY_TIMER_SIGNAL);
|
||||
|
||||
(void)sigemptyset(&sigset);
|
||||
(void)sigaddset(&sigset, MY_TIMER_SIGNAL);
|
||||
status = sigprocmask(SIG_UNBLOCK, &sigset, NULL);
|
||||
if (status != OK)
|
||||
{
|
||||
printf("timer_test: ERROR sigprocmask failed, status=%d\n",
|
||||
status);
|
||||
}
|
||||
|
||||
printf("timer_test: Registering signal handler\n" );
|
||||
act.sa_sigaction = timer_expiration;
|
||||
act.sa_flags = SA_SIGINFO;
|
||||
|
||||
(void)sigfillset(&act.sa_mask);
|
||||
(void)sigdelset(&act.sa_mask, MY_TIMER_SIGNAL);
|
||||
|
||||
status = sigaction(MY_TIMER_SIGNAL, &act, &oact);
|
||||
if (status != OK)
|
||||
{
|
||||
printf("timer_test: ERROR sigaction failed, status=%d\n" , status);
|
||||
}
|
||||
|
||||
#ifndef SDCC
|
||||
printf("timer_test: oact.sigaction=%p oact.sa_flags=%x oact.sa_mask=%x\n",
|
||||
oact.sa_sigaction, oact.sa_flags, oact.sa_mask);
|
||||
#endif
|
||||
|
||||
/* Create the POSIX timer */
|
||||
|
||||
printf("timer_test: Creating timer\n" );
|
||||
|
||||
notify.sigev_notify = SIGEV_SIGNAL;
|
||||
notify.sigev_signo = MY_TIMER_SIGNAL;
|
||||
notify.sigev_value.sival_int = SIGVALUE_INT;
|
||||
|
||||
status = timer_create(CLOCK_REALTIME, ¬ify, &timerid);
|
||||
if (status != OK)
|
||||
{
|
||||
printf("timer_test: timer_create failed, errno=%d\n", get_errno_ptr());
|
||||
goto errorout;
|
||||
}
|
||||
|
||||
/* Start the POSIX timer */
|
||||
|
||||
printf("timer_test: Starting timer\n" );
|
||||
|
||||
timer.it_value.tv_sec = 2;
|
||||
timer.it_value.tv_nsec = 0;
|
||||
timer.it_interval.tv_sec = 2;
|
||||
timer.it_interval.tv_nsec = 0;
|
||||
|
||||
status = timer_settime(timerid, 0, &timer, NULL);
|
||||
if (status != OK)
|
||||
{
|
||||
printf("timer_test: timer_settime failed, errno=%d\n", get_errno_ptr());
|
||||
goto errorout;
|
||||
}
|
||||
|
||||
/* Take the semaphore */
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
printf("timer_test: Waiting on semaphore\n" );
|
||||
fflush(stdout);
|
||||
status = sem_wait(&sem);
|
||||
if (status != 0)
|
||||
{
|
||||
int error = *get_errno_ptr();
|
||||
if (error == EINTR)
|
||||
{
|
||||
printf("timer_test: sem_wait() successfully interrupted by signal\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("timer_test: ERROR sem_wait failed, errno=%d\n" , error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("timer_test: ERROR awakened with no error!\n" );
|
||||
}
|
||||
printf("timer_test: g_nsigreceived=%d\n", g_nsigreceived);
|
||||
}
|
||||
|
||||
errorout:
|
||||
sem_destroy(&sem);
|
||||
|
||||
/* Then delete the timer */
|
||||
|
||||
printf("timer_test: Deleting timer\n" );
|
||||
status = timer_delete(timerid);
|
||||
if (status != OK)
|
||||
{
|
||||
printf("timer_test: timer_create failed, errno=%d\n", get_errno_ptr());
|
||||
}
|
||||
|
||||
/* Detach the signal handler */
|
||||
|
||||
act.sa_sigaction = SIG_DFL;
|
||||
status = sigaction(MY_TIMER_SIGNAL, &act, &oact);
|
||||
|
||||
printf("timer_test: done\n" );
|
||||
fflush(stdout);
|
||||
}
|
|
@ -110,7 +110,6 @@ static void wakeup_action(int signo, siginfo_t *info, void *ucontext)
|
|||
printf("wakeup_action: ERROR sigprocmask=%x expected=%x\n",
|
||||
oldset, allsigs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int waiter_main(int argc, char *argv[])
|
||||
|
@ -120,7 +119,7 @@ static int waiter_main(int argc, char *argv[])
|
|||
struct sigaction oact;
|
||||
int status;
|
||||
|
||||
printf("wakeup_action: Waiter started\n" );
|
||||
printf("waiter_main: Waiter started\n" );
|
||||
|
||||
printf("waiter_main: Unmasking signal %d\n" , WAKEUP_SIGNAL);
|
||||
(void)sigemptyset(&sigset);
|
||||
|
@ -172,6 +171,11 @@ static int waiter_main(int argc, char *argv[])
|
|||
printf("waiter_main: ERROR awakened with no error!\n" );
|
||||
}
|
||||
|
||||
/* Detach the signal handler */
|
||||
|
||||
act.sa_sigaction = SIG_DFL;
|
||||
status = sigaction(WAKEUP_SIGNAL, &act, &oact);
|
||||
|
||||
printf("waiter_main: done\n" );
|
||||
fflush(stdout);
|
||||
threadexited = TRUE;
|
||||
|
@ -186,14 +190,12 @@ void sighand_test(void)
|
|||
int policy;
|
||||
int status;
|
||||
|
||||
printf("waiter_main: Initializing semaphore to 0\n" );
|
||||
printf("sighand_test: Initializing semaphore to 0\n" );
|
||||
sem_init(&sem, 0, 0);
|
||||
|
||||
/* Start waiter thread */
|
||||
|
||||
printf("sighand_test: Starting waiter task\n" );
|
||||
|
||||
|
||||
status = sched_getparam (0, ¶m);
|
||||
if (status != OK)
|
||||
{
|
||||
|
|
|
@ -67,9 +67,14 @@
|
|||
#define SIGRTMIN 0 /* First real time signal */
|
||||
#define SIGRTMAX 31 /* Last real time signal */
|
||||
|
||||
/* sigprocmask() "how" definitions. Only one of the following
|
||||
* can be specified:
|
||||
*/
|
||||
/* A few of the real time signals are used within the OS: */
|
||||
|
||||
#define SIGALRM 2 /* Default signal used with POSIX timers (used only */
|
||||
/* no other signal is provided) */
|
||||
#define SIGCONDTIMEDOUT 3 /* Used in the implementation of */
|
||||
/* pthread_cond_timedwait */
|
||||
|
||||
/* sigprocmask() "how" definitions. Only one of the following can be specified: */
|
||||
|
||||
#define SIG_BLOCK 1 /* Block the given signals */
|
||||
#define SIG_UNBLOCK 2 /* Unblock the given signals */
|
||||
|
@ -97,44 +102,49 @@
|
|||
#define SIGEV_NONE 0 /* No notification desired */
|
||||
#define SIGEV_SIGNAL 1 /* Notify via signal */
|
||||
|
||||
/* Special values of sigaction (all treated like NULL) */
|
||||
|
||||
#define SIG_DFL ((CODE void*)0)
|
||||
#define SIG_IGN ((CODE void*)0)
|
||||
|
||||
/********************************************************************************
|
||||
* Global Type Declarations
|
||||
********************************************************************************/
|
||||
|
||||
/* This defines a set of 32 signals (numbered 0 through 31). */
|
||||
|
||||
typedef uint32 sigset_t;
|
||||
typedef uint32 sigset_t; /* Bit set of 32 signals */
|
||||
|
||||
/* This defines the type of the siginfo si_value field */
|
||||
|
||||
union sigval
|
||||
{
|
||||
int sival_int;
|
||||
void *sival_ptr;
|
||||
int sival_int; /* Integer value */
|
||||
void *sival_ptr; /* Pointer value */
|
||||
};
|
||||
|
||||
/* This structure contains elements that define a queue signal.
|
||||
* The following is used to attach a signal to a message queue
|
||||
* to notify a task when a message is available on a queue
|
||||
/* This structure contains elements that define a queue signal. The following is
|
||||
* used to attach a signal to a message queue to notify a task when a message is
|
||||
* available on a queue
|
||||
*/
|
||||
|
||||
struct sigevent
|
||||
{
|
||||
int sigev_signo; /* Notification: SIGNAL or NONE */
|
||||
union sigval sigev_value; /* Generate this signal */
|
||||
int sigev_notify; /* Queue this value */
|
||||
ubyte sigev_notify; /* Notification method: SIGEV_SIGNAL or SIGEV_NONE */
|
||||
ubyte sigev_signo; /* Notification signal */
|
||||
union sigval sigev_value; /* Data passed with notification */
|
||||
};
|
||||
|
||||
/* The following types is used to pass parameters to/from
|
||||
* signal handlers
|
||||
*/
|
||||
/* The following types is used to pass parameters to/from signal handlers */
|
||||
|
||||
typedef struct siginfo
|
||||
struct siginfo
|
||||
{
|
||||
int si_signo;
|
||||
int si_code;
|
||||
union sigval si_value;
|
||||
} siginfo_t;
|
||||
ubyte si_signo; /* Identifies signal */
|
||||
ubyte si_code; /* Source: SI_USER, SI_QUEUE, SI_TIMER, SI_ASYNCIO, or SI_MESGQ */
|
||||
union sigval si_value; /* Data passed with signal */
|
||||
};
|
||||
|
||||
typedef struct siginfo siginfo_t;
|
||||
|
||||
/* The following structure defines the action to take for given signal */
|
||||
|
||||
|
@ -142,8 +152,8 @@ struct sigaction
|
|||
{
|
||||
union
|
||||
{
|
||||
void (*_sa_handler)(int);
|
||||
void (*_sa_sigaction)(int, FAR siginfo_t *, FAR void *);
|
||||
CODE void (*_sa_handler)(int);
|
||||
CODE void (*_sa_sigaction)(int, FAR siginfo_t *, FAR void *);
|
||||
} sa_u;
|
||||
sigset_t sa_mask;
|
||||
int sa_flags;
|
||||
|
|
|
@ -70,9 +70,9 @@
|
|||
* Global Type Declarations
|
||||
********************************************************************************/
|
||||
|
||||
typedef ubyte time_t;
|
||||
typedef ubyte clockid_t;
|
||||
typedef ubyte timer_t;
|
||||
typedef uint32 time_t; /* Holds time in seconds */
|
||||
typedef ubyte clockid_t; /* Identifies one time base source */
|
||||
typedef FAR void *timer_t; /* Represents one POSIX timer */
|
||||
|
||||
struct timespec
|
||||
{
|
||||
|
|
|
@ -102,6 +102,7 @@ EXTERN STATUS wd_delete(WDOG_ID wdog);
|
|||
EXTERN STATUS wd_start(WDOG_ID wdog, int delay, wdentry_t wdentry,
|
||||
int argc, ...);
|
||||
EXTERN STATUS wd_cancel(WDOG_ID wdog);
|
||||
EXTERN int wd_gettime(WDOG_ID wdog);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -55,10 +55,11 @@ SCHED_SRCS = sched_setparam.c sched_getparam.c \
|
|||
sched_yield.c sched_rrgetinterval.c sched_foreach.c \
|
||||
sched_getprioritymax.c sched_getprioritymin.c \
|
||||
sched_lock.c sched_unlock.c sched_lockcount.c
|
||||
WDOG_SRCS = wd_initialize.c wd_create.c wd_start.c wd_cancel.c wd_delete.c
|
||||
WDOG_SRCS = wd_initialize.c wd_create.c wd_start.c wd_cancel.c wd_delete.c \
|
||||
wd_gettime.c
|
||||
TIME_SRCS = sched_processtimer.c sleep.c usleep.c
|
||||
CLOCK_SRCS = clock_initialize.c mktime.c gmtime_r.c clock_settime.c \
|
||||
clock_gettime.c clock_getres.c
|
||||
CLOCK_SRCS = clock_initialize.c mktime.c gmtime_r.c clock_settime.c clock_gettime.c \
|
||||
clock_getres.c clock_time2ticks.c clock_abstime2ticks.c clock_ticks2time.c
|
||||
SIGNAL_SRCS = sig_initialize.c \
|
||||
sig_action.c sig_procmask.c sig_pending.c sig_suspend.c \
|
||||
sig_kill.c sig_queue.c sig_waitinfo.c sig_timedwait.c \
|
||||
|
@ -99,8 +100,9 @@ SEM_SRCS = sem_initialize.c sem_init.c sem_destroy.c\
|
|||
sem_open.c sem_close.c sem_unlink.c \
|
||||
sem_wait.c sem_trywait.c sem_post.c sem_getvalue.c \
|
||||
sem_waitirq.c sem_findnamed.c
|
||||
ifneq ($(CONFIG_DISABLE_POSIX_TIMERSA),y)
|
||||
TIMERS_SRCS = timer_create.c timer_delete.c timer_getoverrun.c timer_gettime.c timer_settime.c
|
||||
ifneq ($(CONFIG_DISABLE_POSIX_TIMERS),y)
|
||||
TIMER_SRCS = timer_initialize.c timer_create.c timer_delete.c timer_getoverrun.c \
|
||||
timer_gettime.c timer_settime.c
|
||||
endif
|
||||
IRQ_SRCS = irq_initialize.c irq_attach.c irq_dispatch.c irq_unexpectedisr.c
|
||||
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
/********************************************************************************
|
||||
* clock_abstime2ticks.c
|
||||
*
|
||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Included Files
|
||||
********************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
#include "clock_internal.h"
|
||||
|
||||
/********************************************************************************
|
||||
* Definitions
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Private Type Declarations
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Global Variables
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Private Variables
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Private Functions
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Public Functions
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Function: clock_abstime2ticks
|
||||
*
|
||||
* Description:
|
||||
* Convert an absolute timespec delay to system timer ticks.
|
||||
*
|
||||
* Parameters:
|
||||
* clockid - The timing source to use in the conversion
|
||||
* reltime - Convert this absolue time to system clock ticks.
|
||||
* ticks - Return the converted number of ticks here.
|
||||
*
|
||||
* Return Value:
|
||||
* OK on success; A non-zero error number on failure;
|
||||
*
|
||||
* Assumptions:
|
||||
* Interrupts should be disabled so that the time is not changing during the
|
||||
* calculation
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
extern int clock_abstime2ticks(clockid_t clockid, const struct timespec *abstime,
|
||||
int *ticks)
|
||||
{
|
||||
struct timespec currtime;
|
||||
struct timespec reltime;
|
||||
sint32 relusec;
|
||||
int ret;
|
||||
|
||||
/* Convert the timespec to clock ticks. NOTE: Here we use
|
||||
* internal knowledge that CLOCK_REALTIME is defined to be zero!
|
||||
*/
|
||||
|
||||
ret = clock_gettime(clockid, &currtime);
|
||||
if (ret)
|
||||
{
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* The relative time to wait is the absolute time minus the
|
||||
* current time.
|
||||
*/
|
||||
|
||||
reltime.tv_nsec = (abstime->tv_nsec - currtime.tv_nsec);
|
||||
reltime.tv_sec = (abstime->tv_sec - currtime.tv_sec);
|
||||
|
||||
/* Check if we were supposed to borrow from the seconds to
|
||||
* borrow from the seconds
|
||||
*/
|
||||
|
||||
if (reltime.tv_nsec < 0)
|
||||
{
|
||||
reltime.tv_nsec += NSEC_PER_SEC;
|
||||
reltime.tv_sec -= 1;
|
||||
}
|
||||
|
||||
/* Convert this relative time into microseconds.*/
|
||||
|
||||
return clock_time2ticks(&reltime, ticks);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/************************************************************
|
||||
/********************************************************************************
|
||||
* clock_internal.h
|
||||
*
|
||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
|
@ -31,21 +31,21 @@
|
|||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
************************************************************/
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef __CLOCK_INTERNAL_H
|
||||
#define __CLOCK_INTERNAL_H
|
||||
|
||||
/************************************************************
|
||||
/********************************************************************************
|
||||
* Included Files
|
||||
************************************************************/
|
||||
********************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <nuttx/compiler.h>
|
||||
|
||||
/************************************************************
|
||||
/********************************************************************************
|
||||
* Definitions
|
||||
************************************************************/
|
||||
********************************************************************************/
|
||||
|
||||
/* Timing constants */
|
||||
|
||||
|
@ -59,7 +59,7 @@
|
|||
#define MSEC_PER_TICK 10
|
||||
#define USEC_PER_TICK (MSEC_PER_TICK * USEC_PER_MSEC)
|
||||
#define NSEC_PER_TICK (MSEC_PER_TICK * NSEC_PER_MSEC)
|
||||
#define TICK_PER_SEC (MSEC_PER_SEC / MSEC_PER_TICK)
|
||||
#define TICK_PER_SEC (MSEC_PER_SEC / MSEC_PER_TICK)
|
||||
|
||||
#define MSEC2TICK(msec) (((msec)+(MSEC_PER_TICK/2))/MSEC_PER_TICK)
|
||||
#define USEC2TICK(usec) (((usec)+(USEC_PER_TICK/2))/USEC_PER_TICK)
|
||||
|
@ -73,25 +73,29 @@
|
|||
# define GREG_DAY 15
|
||||
#endif /* CONFIG_JULIAN_TIME */
|
||||
|
||||
/************************************************************
|
||||
/********************************************************************************
|
||||
* Public Type Definitions
|
||||
************************************************************/
|
||||
********************************************************************************/
|
||||
|
||||
/************************************************************
|
||||
/********************************************************************************
|
||||
* Global Variables
|
||||
************************************************************/
|
||||
********************************************************************************/
|
||||
|
||||
extern volatile uint32 g_system_timer;
|
||||
extern struct timespec g_basetime;
|
||||
extern uint32 g_tickbias;
|
||||
extern uint32 g_tickbias;
|
||||
|
||||
/************************************************************
|
||||
/********************************************************************************
|
||||
* Public Function Prototypes
|
||||
************************************************************/
|
||||
********************************************************************************/
|
||||
|
||||
extern void weak_function clock_initialize(void);
|
||||
extern void weak_function clock_timer(void);
|
||||
|
||||
extern time_t clock_calendar2utc(int year, int month, int day);
|
||||
extern int clock_abstime2ticks(clockid_t clockid, const struct timespec *abstime,
|
||||
int *ticks);
|
||||
extern int clock_time2ticks(const struct timespec *reltime, int *ticks);
|
||||
extern int clock_ticks2time(int ticks, struct timespec *reltime);
|
||||
|
||||
#endif /* __CLOCK_INTERNAL_H */
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/********************************************************************************
|
||||
* clock_ticks2time.c
|
||||
*
|
||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Included Files
|
||||
********************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include "clock_internal.h"
|
||||
|
||||
/********************************************************************************
|
||||
* Definitions
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Private Type Declarations
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Global Variables
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Private Variables
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Private Functions
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Public Functions
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Function: clock_ticks2time
|
||||
*
|
||||
* Description:
|
||||
* Convert the system time tick value to a relative time.
|
||||
*
|
||||
* Parameters:
|
||||
* ticks - The number of system time ticks to convert.
|
||||
* reltime - Return the converted system time here.
|
||||
*
|
||||
* Return Value:
|
||||
* Always returns OK
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
int clock_ticks2time(int ticks, struct timespec *reltime)
|
||||
{
|
||||
int remainder;
|
||||
|
||||
reltime->tv_sec = ticks / TICK_PER_SEC;
|
||||
remainder = ticks - TICK_PER_SEC * reltime->tv_sec;
|
||||
reltime->tv_nsec = remainder * NSEC_PER_TICK;
|
||||
return OK;
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
/********************************************************************************
|
||||
* clock_time2ticks.c
|
||||
*
|
||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Included Files
|
||||
********************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include "clock_internal.h"
|
||||
|
||||
/********************************************************************************
|
||||
* Definitions
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Private Type Declarations
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Global Variables
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Private Variables
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Private Functions
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Public Functions
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Function: clock_time2ticks
|
||||
*
|
||||
* Description:
|
||||
* Convert a timespec delay to system timer ticks. This function is suitable
|
||||
* for calculating relative time delays and does not depend on the other
|
||||
* clock_* logic.
|
||||
*
|
||||
* Parameters:
|
||||
* reltime - Convert this relative time to system clock ticks.
|
||||
* ticks - Return the converted number of ticks here.
|
||||
*
|
||||
* Return Value:
|
||||
* Always returns OK
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
int clock_time2ticks(const struct timespec *reltime, int *ticks)
|
||||
{
|
||||
sint32 relusec;
|
||||
|
||||
/* Convert the relative time into microseconds.*/
|
||||
|
||||
relusec = reltime->tv_sec * USEC_PER_SEC + reltime->tv_nsec / NSEC_PER_USEC;
|
||||
|
||||
/* Convert microseconds to clock ticks */
|
||||
|
||||
*ticks = relusec / USEC_PER_TICK;
|
||||
return OK;
|
||||
}
|
|
@ -57,6 +57,7 @@
|
|||
# include "pthread_internal.h"
|
||||
#endif
|
||||
#include "clock_internal.h"
|
||||
#include "timer_internal.h"
|
||||
#include "irq_internal.h"
|
||||
|
||||
/************************************************************
|
||||
|
@ -304,6 +305,15 @@ void os_start(void)
|
|||
user_initialize();
|
||||
}
|
||||
|
||||
/* Initialize the watchdog facility (if included in the link) */
|
||||
|
||||
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
|
||||
if (wd_initialize != NULL)
|
||||
#endif
|
||||
{
|
||||
wd_initialize();
|
||||
}
|
||||
|
||||
/* Initialize the POSIX timer facility (if included in the link) */
|
||||
|
||||
#ifndef CONFIG_DISABLE_CLOCK
|
||||
|
@ -315,14 +325,14 @@ void os_start(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Initialize the watchdog facility (if included in the link) */
|
||||
|
||||
#ifndef CONFIG_DISABLE_POSIX_TIMERS
|
||||
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
|
||||
if (wd_initialize != NULL)
|
||||
if (timer_initialize != NULL)
|
||||
#endif
|
||||
{
|
||||
wd_initialize();
|
||||
timer_initialize();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Initialize the signal facility (if in link) */
|
||||
|
||||
|
|
|
@ -54,8 +54,6 @@
|
|||
* Definitions
|
||||
************************************************************/
|
||||
|
||||
#define ECHO_COND_WAIT_SIGNO 3
|
||||
|
||||
/************************************************************
|
||||
* Private Type Declarations
|
||||
************************************************************/
|
||||
|
@ -105,70 +103,6 @@ static void pthread_condtimedout(int argc, uint32 pid, uint32 signo, ...)
|
|||
#endif
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* Function: pthread_timeoutticks
|
||||
*
|
||||
* Description:
|
||||
* Convert a timespec delay to system timer ticks.
|
||||
*
|
||||
* Parameters:
|
||||
* abstime - wait until this absolute time
|
||||
*
|
||||
* Return Value:
|
||||
* The relative number of ticks to wait (or ERROR on
|
||||
* failure;
|
||||
*
|
||||
* Assumptions:
|
||||
* Interrupts should be disabled so that the time is
|
||||
* not changing during the calculation
|
||||
*
|
||||
************************************************************/
|
||||
|
||||
int pthread_timeouticks(const struct timespec *abstime, int *ticks)
|
||||
{
|
||||
struct timespec currtime;
|
||||
struct timespec reltime;
|
||||
sint32 relusec;
|
||||
int ret;
|
||||
|
||||
/* Convert the timespec to clock ticks. NOTE: Here we use
|
||||
* internal knowledge that CLOCK_REALTIME is defined to be zero!
|
||||
*/
|
||||
|
||||
ret = clock_gettime(0, &currtime);
|
||||
if (ret)
|
||||
{
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* The relative time to wait is the absolute time minus the
|
||||
* current time.
|
||||
*/
|
||||
|
||||
reltime.tv_nsec = (abstime->tv_nsec - currtime.tv_nsec);
|
||||
reltime.tv_sec = (abstime->tv_sec - currtime.tv_sec);
|
||||
|
||||
/* Check if we were supposed to borrow from the seconds to
|
||||
* borrow from the seconds
|
||||
*/
|
||||
|
||||
if (reltime.tv_nsec < 0)
|
||||
{
|
||||
reltime.tv_nsec += NSEC_PER_SEC;
|
||||
reltime.tv_sec -= 1;
|
||||
}
|
||||
|
||||
/* Convert this relative time into microseconds.*/
|
||||
|
||||
relusec = reltime.tv_sec * USEC_PER_SEC +
|
||||
reltime.tv_nsec / NSEC_PER_USEC;
|
||||
|
||||
/* Convert microseconds to clock ticks */
|
||||
|
||||
*ticks = relusec / USEC_PER_TICK;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* Public Functions
|
||||
************************************************************/
|
||||
|
@ -255,7 +189,7 @@ int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
|||
* here so that this time stays valid until the wait begins.
|
||||
*/
|
||||
|
||||
ret = pthread_timeouticks(abstime, &ticks);
|
||||
ret = clock_abstime2ticks(CLOCK_REALTIME, abstime, &ticks);
|
||||
if (ret)
|
||||
{
|
||||
/* Restore interrupts (pre-emption will be enabled when
|
||||
|
@ -299,7 +233,7 @@ int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
|||
/* Start the watchdog */
|
||||
|
||||
wd_start(wdog, ticks, (wdentry_t)pthread_condtimedout,
|
||||
2, (uint32)mypid, (uint32)ECHO_COND_WAIT_SIGNO);
|
||||
2, (uint32)mypid, (uint32)SIGCONDTIMEDOUT);
|
||||
|
||||
/* Take the condition semaphore. Do not restore interrupts
|
||||
* until we return from the wait. This is necessary to
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include <errno.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include "os_internal.h"
|
||||
#include "timer_internal.h"
|
||||
|
||||
/************************************************************
|
||||
* Private Functions
|
||||
|
@ -87,6 +88,7 @@ static void sched_releasepid(pid_t pid)
|
|||
* OK on success; ERROR on failure
|
||||
*
|
||||
* Assumptions:
|
||||
* Interrupts are disabled.
|
||||
*
|
||||
************************************************************/
|
||||
|
||||
|
@ -97,6 +99,21 @@ int sched_releasetcb(FAR _TCB *tcb)
|
|||
|
||||
if (tcb)
|
||||
{
|
||||
/* Relase any timers that the task might hold. We do this
|
||||
* before release the PID because it may still be trying to
|
||||
* deliver signals (although interrupts are should be
|
||||
* disabled here).
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_DISABLE_POSIX_TIMERS
|
||||
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
|
||||
if (timer_deleteall != NULL)
|
||||
#endif
|
||||
{
|
||||
timer_deleteall(tcb->pid);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Release the task's process ID if one was assigned. PID
|
||||
* zero is reserved for the IDLE task. The TCB of the IDLE
|
||||
* task is never release so a value of zero simply means that
|
||||
|
|
|
@ -38,10 +38,14 @@
|
|||
********************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <wdog.h>
|
||||
#include <errno.h>
|
||||
#include "timer_internal.h"
|
||||
|
||||
#ifdef CONFIG_POSIX_TIMERS
|
||||
#ifndef CONFIG_DISABLE_POSIX_TIMERS
|
||||
|
||||
/********************************************************************************
|
||||
* Definitions
|
||||
|
@ -59,6 +63,52 @@
|
|||
* Private Functions
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Function: timer_allocate
|
||||
*
|
||||
* Description:
|
||||
* Allocate one POSIX timer and place it into the allocated timer list.
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
static struct posix_timer_s *timer_allocate(void)
|
||||
{
|
||||
struct posix_timer_s *ret;
|
||||
irqstate_t flags;
|
||||
|
||||
/* Try to get a preallocated timer from the free list */
|
||||
|
||||
#if CONFIG_PREALLOC_TIMERS > 0
|
||||
flags = irqsave();
|
||||
ret = (struct posix_timer_s*)sq_remfirst((sq_queue_t*)&g_freetimers);
|
||||
irqrestore(flags);
|
||||
|
||||
/* Did we get one? */
|
||||
|
||||
if (!ret)
|
||||
#endif
|
||||
{
|
||||
/* Allocate a new timer from the heap */
|
||||
|
||||
ret = (struct posix_timer_s*)malloc(sizeof(struct posix_timer_s));
|
||||
if (ret)
|
||||
{
|
||||
ret->pt_flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we have a timer, then put it into the allocated timer list */
|
||||
|
||||
if (ret)
|
||||
{
|
||||
flags = irqsave();
|
||||
sq_addlast((sq_entry_t*)ret, (sq_queue_t*)&g_alloctimers);
|
||||
irqrestore(flags);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Public Functions
|
||||
********************************************************************************/
|
||||
|
@ -113,8 +163,60 @@
|
|||
|
||||
int timer_create(clockid_t clockid, FAR struct sigevent *evp, FAR timer_t *timerid)
|
||||
{
|
||||
#warning "Not Implemented"
|
||||
return ENOTSUP;
|
||||
struct posix_timer_s *ret;
|
||||
WDOG_ID wdog;
|
||||
|
||||
/* Sanity checks. Also, we support only CLOCK_REALTIME */
|
||||
|
||||
if (!timerid || clockid != CLOCK_REALTIME)
|
||||
{
|
||||
*get_errno_ptr() = EINVAL;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Allocate a watchdog to provide the underling CLOCK_REALTIME timer */
|
||||
|
||||
wdog = wd_create();
|
||||
if (!wdog)
|
||||
{
|
||||
*get_errno_ptr() = EAGAIN;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Allocate a timer instance to contain the watchdog */
|
||||
|
||||
ret = timer_allocate();
|
||||
if (!ret)
|
||||
{
|
||||
*get_errno_ptr() = EAGAIN;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Initialize the timer instance */
|
||||
|
||||
ret->pt_owner = getpid();
|
||||
ret->pt_delay = 0;
|
||||
ret->pt_wdog = wdog;
|
||||
|
||||
if (evp)
|
||||
{
|
||||
ret->pt_signo = evp->sigev_signo;
|
||||
#ifdef CONFIG_CAN_PASS_STRUCTS
|
||||
ret->pt_value = evp->sigev_value;
|
||||
#else
|
||||
ret->pt_value.sival_ptr = evp->sigev_value.sigval_ptr;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
ret->pt_signo = SIGALRM;
|
||||
ret->pt_value.sival_ptr = ret;
|
||||
}
|
||||
|
||||
/* Return the timer */
|
||||
|
||||
*timerid = ret;
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POSIX_TIMERS */
|
||||
#endif /* CONFIG_DISABLE_POSIX_TIMERS */
|
||||
|
|
|
@ -39,7 +39,10 @@
|
|||
|
||||
#include <nuttx/config.h>
|
||||
#include <time.h>
|
||||
#include <queue.h>
|
||||
#include <errno.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include "timer_internal.h"
|
||||
|
||||
#ifndef CONFIG_DISABLE_POSIX_TIMERS
|
||||
|
||||
|
@ -59,6 +62,43 @@
|
|||
* Private Functions
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Function: timer_free
|
||||
*
|
||||
* Description:
|
||||
* Remove the timer from the allocated timer list and free it or return it to
|
||||
* the free list (depending on whether or not the timer is one of the
|
||||
* preallocated timers)
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
static void timer_free(struct posix_timer_s *timer)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
/* Remove the timer from the allocated list */
|
||||
|
||||
flags = irqsave();
|
||||
sq_rem((FAR sq_entry_t*)timer, (sq_queue_t*)&g_alloctimers);
|
||||
|
||||
/* Return it to the free list if it is one of the preallocated timers */
|
||||
|
||||
#if CONFIG_PREALLOC_TIMERS > 0
|
||||
if ((timer->pt_flags & PT_FLAGS_PREALLOCATED) != 0)
|
||||
{
|
||||
sq_addlast((FAR sq_entry_t*)&timer, (FAR sq_queue_t*)&g_freetimers);
|
||||
irqrestore(flags);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Otherwise, return it to the heap */
|
||||
|
||||
irqrestore(flags);
|
||||
sched_free(timer);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Public Functions
|
||||
********************************************************************************/
|
||||
|
@ -88,8 +128,24 @@
|
|||
|
||||
int timer_delete(timer_t timerid)
|
||||
{
|
||||
#warning "Not Implemented"
|
||||
return ENOTSUP;
|
||||
FAR struct posix_timer_s *timer = (FAR struct posix_timer_s *)timerid;
|
||||
|
||||
/* Some sanity checks */
|
||||
|
||||
if (!timer)
|
||||
{
|
||||
*get_errno_ptr() = EINVAL;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Disarm the timer */
|
||||
|
||||
(void)wd_cancel(timer->pt_wdog);
|
||||
|
||||
/* Release the timer structure */
|
||||
|
||||
timer_free(timer);
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DISABLE_POSIX_TIMERS */
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <nuttx/config.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include "timer_internal.h"
|
||||
|
||||
#ifndef CONFIG_DISABLE_POSIX_TIMERS
|
||||
|
||||
|
@ -102,7 +103,8 @@
|
|||
int timer_getoverrun(timer_t timerid)
|
||||
{
|
||||
#warning "Not Implemented"
|
||||
return ENOTSUP;
|
||||
*get_errno_ptr() = ENOSYS;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DISABLE_POSIX_TIMERS */
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
#include <nuttx/config.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include "clock_internal.h"
|
||||
#include "timer_internal.h"
|
||||
|
||||
#ifndef CONFIG_DISABLE_POSIX_TIMERS
|
||||
|
||||
|
@ -87,14 +89,33 @@
|
|||
* EINVAL - The timerid argument does not correspond to an ID returned by
|
||||
* timer_create() but not yet deleted by timer_delete().
|
||||
*
|
||||
* Assumptions:
|
||||
* Assumptions/Limitations:
|
||||
* Due to the asynchronous operation of this function, the time reported
|
||||
* by this function could be significantly more than that actual time
|
||||
* remaining on the timer at any time.
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
int timer_gettime(timer_t timerid, FAR struct itimerspec *value)
|
||||
{
|
||||
#warning "Not Implemented"
|
||||
return ENOTSUP;
|
||||
FAR struct posix_timer_s *timer = (FAR struct posix_timer_s *)timerid;
|
||||
int ticks;
|
||||
|
||||
if (!timer || !value)
|
||||
{
|
||||
*get_errno_ptr() = EINVAL;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Get the number of ticks before the underlying watchdog expires */
|
||||
|
||||
ticks = wd_gettime(timer->pt_wdog);
|
||||
|
||||
/* Convert that to a struct timespec and return it */
|
||||
|
||||
(void)clock_ticks2time(ticks, &value->it_value);
|
||||
(void)clock_ticks2time(timer->pt_delay, &value->it_interval);
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DISABLE_POSIX_TIMERS */
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
/********************************************************************************
|
||||
* timer_initialize.c
|
||||
*
|
||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Included Files
|
||||
********************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <time.h>
|
||||
#include <queue.h>
|
||||
#include <errno.h>
|
||||
#include <nuttx/compiler.h>
|
||||
#include "timer_internal.h"
|
||||
|
||||
#ifndef CONFIG_DISABLE_POSIX_TIMERS
|
||||
|
||||
/********************************************************************************
|
||||
* Definitions
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Private Data
|
||||
********************************************************************************/
|
||||
|
||||
/* These are the preallocated times */
|
||||
|
||||
#if CONFIG_PREALLOC_TIMERS > 0
|
||||
static struct posix_timer_s g_prealloctimers[CONFIG_PREALLOC_TIMERS];
|
||||
#endif
|
||||
|
||||
/********************************************************************************
|
||||
* Public Data
|
||||
********************************************************************************/
|
||||
|
||||
/* This is a list of free, preallocated timer structures */
|
||||
|
||||
#if CONFIG_PREALLOC_TIMERS > 0
|
||||
volatile sq_queue_t g_freetimers;
|
||||
#endif
|
||||
|
||||
/* This is a list of instantiated timer structures -- active and inactive. The
|
||||
* timers are place on this list by timer_create() and removed from the list by
|
||||
* timer_delete() or when the owning thread exits.
|
||||
*/
|
||||
|
||||
volatile sq_queue_t g_alloctimers;
|
||||
|
||||
/********************************************************************************
|
||||
* Private Functions
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Public Functions
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Function: timer_initialize
|
||||
*
|
||||
* Description:
|
||||
* Boot up configuration of the POSIX timer facility.
|
||||
*
|
||||
* Parameters:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
void weak_function timer_initialize(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Place all of the pre-allocated timers into the free timer list */
|
||||
|
||||
#if CONFIG_PREALLOC_TIMERS > 0
|
||||
sq_init((sq_queue_t*)&g_freetimers);
|
||||
|
||||
for (i = 0; i < CONFIG_PREALLOC_TIMERS; i++)
|
||||
{
|
||||
g_prealloctimers[i].pt_flags = PT_FLAGS_PREALLOCATED;
|
||||
sq_addlast((FAR sq_entry_t*)&g_prealloctimers[i], (FAR sq_queue_t*)&g_freetimers);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Initialize the list of allocated timers */
|
||||
|
||||
sq_init((sq_queue_t*)&g_alloctimers);
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Function: timer_deleteall
|
||||
*
|
||||
* Description:
|
||||
* This function is called whenever a thread exits. Any timers owned by that
|
||||
* thread are deleted as though called by timer_delete().
|
||||
*
|
||||
* It is provided in this file so that it can be weakly defined but also,
|
||||
* like timer_intitialize(), be brought into the link whenever the timer
|
||||
* resources are referenced.
|
||||
*
|
||||
* Parameters:
|
||||
* pid - the task ID of the thread that exitted
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
void weak_function timer_deleteall(pid_t pid)
|
||||
{
|
||||
FAR struct posix_timer_s *timer;
|
||||
FAR struct posix_timer_s *next;
|
||||
irqstate_t flags;
|
||||
|
||||
flags = irqsave();
|
||||
for (timer = g_alloctimers.head; timer; timer = next)
|
||||
{
|
||||
next = timer->flink;
|
||||
if (timer->pt_owner = pid)
|
||||
{
|
||||
timer_delete((timer_t)timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DISABLE_POSIX_TIMERS */
|
|
@ -0,0 +1,96 @@
|
|||
/********************************************************************************
|
||||
* timer_internal.h
|
||||
*
|
||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef __TIMER_INTERNAL_H
|
||||
#define __TIMER_INTERNAL_H
|
||||
|
||||
/********************************************************************************
|
||||
* Included Files
|
||||
********************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/types.h>
|
||||
#include <wdog.h>
|
||||
#include <nuttx/compiler.h>
|
||||
|
||||
/********************************************************************************
|
||||
* Definitions
|
||||
********************************************************************************/
|
||||
|
||||
#define PT_FLAGS_PREALLOCATED 0x01
|
||||
|
||||
/********************************************************************************
|
||||
* Public Types
|
||||
********************************************************************************/
|
||||
|
||||
/* This structure represents one POSIX timer */
|
||||
|
||||
struct posix_timer_s
|
||||
{
|
||||
FAR struct posix_timer_s *flink;
|
||||
|
||||
ubyte pt_flags; /* See PT_FLAGS_* definitions */
|
||||
ubyte pt_signo; /* Notification signal */
|
||||
pid_t pt_owner; /* Creator of timer */
|
||||
int pt_delay; /* If non-zero, used to reset repetitive timers */
|
||||
WDOG_ID pt_wdog; /* The watchdog that provides the timing */
|
||||
union sigval pt_value; /* Data passed with notification */
|
||||
};
|
||||
|
||||
/********************************************************************************
|
||||
* Public Data
|
||||
********************************************************************************/
|
||||
|
||||
/* This is a list of free, preallocated timer structures */
|
||||
|
||||
#if CONFIG_PREALLOC_TIMERS > 0
|
||||
extern volatile sq_queue_t g_freetimers;
|
||||
#endif
|
||||
|
||||
/* This is a list of instantiated timer structures -- active and inactive. The
|
||||
* timers are place on this list by timer_create() and removed from the list by
|
||||
* timer_delete() or when the owning thread exits.
|
||||
*/
|
||||
|
||||
extern volatile sq_queue_t g_alloctimers;
|
||||
|
||||
/********************************************************************************
|
||||
* Public Function Prototypes
|
||||
********************************************************************************/
|
||||
|
||||
extern void weak_function timer_initialize(void);
|
||||
extern void weak_function timer_deleteall(pid_t pid);
|
||||
|
||||
#endif /* __TIMER_INTERNAL_H */
|
|
@ -40,6 +40,10 @@
|
|||
#include <nuttx/config.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include "os_internal.h"
|
||||
#include "clock_internal.h"
|
||||
#include "sig_internal.h"
|
||||
#include "timer_internal.h"
|
||||
|
||||
#ifndef CONFIG_DISABLE_POSIX_TIMERS
|
||||
|
||||
|
@ -55,10 +59,145 @@
|
|||
* Public Data
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Private Function Prototypes
|
||||
********************************************************************************/
|
||||
|
||||
static void inline timer_sigqueue(FAR struct posix_timer_s *timer);
|
||||
static void inline timer_restart(FAR struct posix_timer_s *timer, uint32 itimer);
|
||||
static void timer_timeout(int argc, uint32 itimer, ...);
|
||||
|
||||
/********************************************************************************
|
||||
* Private Functions
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Function: timer_sigqueue
|
||||
*
|
||||
* Description:
|
||||
* This function basically reimplements sigqueue() so that the si_code can
|
||||
* be correctly set to SI_TIMER
|
||||
*
|
||||
* Parameters:
|
||||
* timer - A reference to the POSIX timer that just timed out
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* This function executes in the context of the watchod timer interrupt.
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
static void inline timer_sigqueue(FAR struct posix_timer_s *timer)
|
||||
{
|
||||
FAR _TCB *tcb;
|
||||
|
||||
/* Get the TCB of the receiving task */
|
||||
|
||||
tcb = sched_gettcb(timer->pt_owner);
|
||||
if (tcb)
|
||||
{
|
||||
siginfo_t info;
|
||||
|
||||
/* Create the siginfo structure */
|
||||
|
||||
info.si_signo = timer->pt_signo;
|
||||
info.si_code = SI_TIMER;
|
||||
#ifndef CONFIG_CAN_PASS_STRUCTS
|
||||
info.si_value = timer->pt_value;
|
||||
#else
|
||||
info.si_value.sival_ptr = timer->pt_value.sival_ptr;
|
||||
#endif
|
||||
|
||||
/* Send the signal */
|
||||
|
||||
(void)sig_received(tcb, &info);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Function: timer_restart
|
||||
*
|
||||
* Description:
|
||||
* If a periodic timer has been selected, then restart the watchdog.
|
||||
*
|
||||
* Parameters:
|
||||
* timer - A reference to the POSIX timer that just timed out
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* This function executes in the context of the watchod timer interrupt.
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
static void inline timer_restart(FAR struct posix_timer_s *timer, uint32 itimer)
|
||||
{
|
||||
/* If this is a repetitive timer, then restart the watchdog */
|
||||
|
||||
if (timer->pt_delay)
|
||||
{
|
||||
(void)wd_start(timer->pt_wdog, timer->pt_delay, timer_timeout, 1, itimer);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Function: timer_timeout
|
||||
*
|
||||
* Description:
|
||||
* This function is called if the timeout elapses before
|
||||
* the condition is signaled.
|
||||
*
|
||||
* Parameters:
|
||||
* argc - the number of arguments (should be 1)
|
||||
* itimer - A reference to the POSIX timer that just timed out
|
||||
* signo - The signal to use to wake up the task
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* This function executes in the context of the watchod timer interrupt.
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
static void timer_timeout(int argc, uint32 itimer, ...)
|
||||
{
|
||||
#ifndef CONFIG_CAN_PASS_STRUCTS
|
||||
/* On many small machines, pointers are encoded and cannot be simply cast from
|
||||
* uint32 to _TCB*. The following union works around this (see wdogparm_t).
|
||||
*/
|
||||
|
||||
union
|
||||
{
|
||||
FAR struct posix_timer_s *timer;
|
||||
uint32 itimer;
|
||||
} u;
|
||||
|
||||
u.itimer = itimer;
|
||||
|
||||
/* Send the specified signal to the specified task. */
|
||||
|
||||
timer_sigqueue(u.timer);
|
||||
|
||||
/* If this is a repetitive timer, the restart the watchdog */
|
||||
|
||||
timer_restart(u.timer, itimer);
|
||||
#else
|
||||
FAR struct posix_timer_s *timer = (FAR struct posix_timer_s *)itimer;
|
||||
|
||||
/* Send the specified signal to the specified task. */
|
||||
|
||||
timer_sigqueue(timer);
|
||||
|
||||
/* If this is a repetitive timer, the restart the watchdog */
|
||||
|
||||
timer_restart(timer, itimer);
|
||||
#endif
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Public Functions
|
||||
********************************************************************************/
|
||||
|
@ -109,7 +248,7 @@
|
|||
* flags - Specifie characteristics of the timer (see above)
|
||||
* value - Specifies the timer value to set
|
||||
* ovalue - A location in which to return the time remaining from the previous
|
||||
* timer setting.
|
||||
* timer setting. (ignored)
|
||||
*
|
||||
* Return Value:
|
||||
* If the timer_settime() succeeds, a value of 0 (OK) will be returned.
|
||||
|
@ -129,8 +268,96 @@
|
|||
int timer_settime(timer_t timerid, int flags, FAR const struct itimerspec *value,
|
||||
FAR struct itimerspec *ovalue)
|
||||
{
|
||||
#warning "Not Implemented"
|
||||
return ENOTSUP;
|
||||
FAR struct posix_timer_s *timer = (FAR struct posix_timer_s *)timerid;
|
||||
irqstate_t state;
|
||||
int delay;
|
||||
int ret = OK;
|
||||
|
||||
/* Some sanity checks */
|
||||
|
||||
if (!timer || !value)
|
||||
{
|
||||
*get_errno_ptr() = EINVAL;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Disarm the timer (in case the timer was already armed when timer_settime()
|
||||
* is called).
|
||||
*/
|
||||
|
||||
(void)wd_cancel(timer->pt_wdog);
|
||||
|
||||
/* If the it_value member of value is zero, the timer will not be re-armed */
|
||||
|
||||
if (value->it_value.tv_sec <= 0 && value->it_value.tv_nsec <= 0)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Setup up any repititive timer */
|
||||
|
||||
if (value->it_interval.tv_sec > 0 || value->it_interval.tv_nsec > 0)
|
||||
{
|
||||
(void)clock_time2ticks(&value->it_interval, &timer->pt_delay);
|
||||
}
|
||||
else
|
||||
{
|
||||
timer->pt_delay = 0;
|
||||
}
|
||||
|
||||
/* We need to disable timer interrupts through the following section so
|
||||
* that the system timer is stable.
|
||||
*/
|
||||
|
||||
state = irqsave();
|
||||
|
||||
/* Check if abstime is selected */
|
||||
|
||||
if ((flags & TIMER_ABSTIME) != 0)
|
||||
{
|
||||
#ifdef CONFIG_DISABLE_CLOCK
|
||||
/* Absolute timing depends upon having access to clock functionality */
|
||||
|
||||
*get_errno_ptr() = ENOSYS;
|
||||
return ERROR;
|
||||
#else
|
||||
/* Calculate a delay corresponding to the absolute time in 'value'.
|
||||
* NOTE: We have internal knowledge the clock_abstime2ticks only
|
||||
* returns an error if clockid != CLOCK_REALTIME.
|
||||
*/
|
||||
|
||||
(void)clock_abstime2ticks(CLOCK_REALTIME, &value->it_value, &delay);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Calculate a delay assuming that 'value' holds the relative time
|
||||
* to wait. We have internal knowledge that clock_time2ticks always
|
||||
* returns success.
|
||||
*/
|
||||
|
||||
(void)clock_time2ticks(&value->it_value, &delay);
|
||||
}
|
||||
|
||||
/* If the time is in the past or now, then set up the next interval
|
||||
* instead.
|
||||
*/
|
||||
|
||||
if (delay <= 0)
|
||||
{
|
||||
delay = timer->pt_delay;
|
||||
}
|
||||
|
||||
/* Then start the watchdog */
|
||||
|
||||
|
||||
if (delay > 0)
|
||||
{
|
||||
ret = wd_start(timer->pt_wdog, timer->pt_delay, timer_timeout, 1, (uint32)timer);
|
||||
}
|
||||
|
||||
irqrestore(state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DISABLE_POSIX_TIMERS */
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
/********************************************************************************
|
||||
* wd_gettime.c
|
||||
*
|
||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Included Files
|
||||
********************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <wdog.h>
|
||||
#include "os_internal.h"
|
||||
#include "wd_internal.h"
|
||||
|
||||
/********************************************************************************
|
||||
* Definitions
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Private Types
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Global Variables
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Private Variables
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Private Functions
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Public Functions
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* Function: wd_gettime
|
||||
*
|
||||
* Description:
|
||||
* This function returns the time remaining before the the specified watchdog
|
||||
* expires.
|
||||
*
|
||||
* Parameters:
|
||||
* wdog = watchdog ID
|
||||
*
|
||||
* Return Value:
|
||||
* The time in system ticks remaining until the watchdog time expires. Zero
|
||||
* means either that wdog is not valid or that the wdog has already expired.
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
int wd_gettime(WDOG_ID wdog)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
/* Verify the wdog */
|
||||
|
||||
flags = irqsave();
|
||||
if (wdog && wdog->active)
|
||||
{
|
||||
/* Traverse the watchdog list accumulating lag times until we find the wdog
|
||||
* that we are looking for
|
||||
*/
|
||||
|
||||
wdog_t *curr;
|
||||
int delay = 0;
|
||||
|
||||
for (curr = (wdog_t*)g_wdactivelist.head; curr; curr = curr->next)
|
||||
{
|
||||
delay += curr->lag;
|
||||
if (curr == wdog)
|
||||
{
|
||||
irqrestore(flags);
|
||||
return delay;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
irqrestore(flags);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue