Contiki-NG
rtimer.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2005, Swedish Institute of Computer Science
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  *
31  */
32 
33 /**
34  * \file
35  * Header file for the real-time timer module.
36  * \author
37  * Adam Dunkels <adam@sics.se>
38  *
39  */
40 
41 /** \addtogroup threads
42  * @{ */
43 
44 /**
45  * \defgroup rt Real-time task scheduling
46  *
47  * The real-time module handles the scheduling and execution of
48  * real-time tasks (with predictable execution times).
49  *
50  * @{
51  */
52 
53 #ifndef RTIMER_H_
54 #define RTIMER_H_
55 
56 #include "contiki.h"
57 #include "dev/watchdog.h"
58 #include <stdbool.h>
59 
60 /*---------------------------------------------------------------------------*/
61 
62 /** \brief The rtimer size (in bytes) */
63 #ifdef RTIMER_CONF_CLOCK_SIZE
64 #define RTIMER_CLOCK_SIZE RTIMER_CONF_CLOCK_SIZE
65 #else /* RTIMER_CONF_CLOCK_SIZE */
66 /* Default: 32bit rtimer*/
67 #define RTIMER_CLOCK_SIZE 4
68 #endif /* RTIMER_CONF_CLOCK_SIZE */
69 
70 #if RTIMER_CLOCK_SIZE == 2
71 /* 16-bit rtimer */
72 typedef uint16_t rtimer_clock_t;
73 #define RTIMER_CLOCK_DIFF(a,b) ((int16_t)((a)-(b)))
74 
75 #elif RTIMER_CLOCK_SIZE == 4
76 /* 32-bit rtimer */
77 typedef uint32_t rtimer_clock_t;
78 #define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b)))
79 
80 #elif RTIMER_CLOCK_SIZE == 8
81 /* 64-bit rtimer */
82 typedef uint64_t rtimer_clock_t;
83 #define RTIMER_CLOCK_DIFF(a,b) ((int64_t)((a)-(b)))
84 
85 #else
86 #error Unsupported rtimer size (check RTIMER_CLOCK_SIZE)
87 #endif
88 
89 #define RTIMER_CLOCK_MAX ((rtimer_clock_t)-1)
90 #define RTIMER_CLOCK_LT(a, b) (RTIMER_CLOCK_DIFF((a),(b)) < 0)
91 
92 #include "rtimer-arch.h"
93 
94 
95 /*
96  * RTIMER_GUARD_TIME is the minimum amount of rtimer ticks between
97  * the current time and the future time when a rtimer is scheduled.
98  * Necessary to avoid accidentally scheduling a rtimer in the past
99  * on platforms with fast rtimer ticks. Should be >= 2.
100  */
101 #ifdef RTIMER_CONF_GUARD_TIME
102 #define RTIMER_GUARD_TIME RTIMER_CONF_GUARD_TIME
103 #else /* RTIMER_CONF_GUARD_TIME */
104 #define RTIMER_GUARD_TIME (RTIMER_ARCH_SECOND >> 14)
105 #endif /* RTIMER_CONF_GUARD_TIME */
106 
107 /*---------------------------------------------------------------------------*/
108 
109 /**
110  * Number of rtimer ticks for 1 second.
111  */
112 #define RTIMER_SECOND RTIMER_ARCH_SECOND
113 
114 /**
115  * \brief Initialize the real-time scheduler.
116  *
117  * This function initializes the real-time scheduler and
118  * must be called at boot-up, before any other functions
119  * from the real-time scheduler is called.
120  */
121 void rtimer_init(void);
122 
123 struct rtimer;
124 typedef void (* rtimer_callback_t)(struct rtimer *t, void *ptr);
125 
126 /**
127  * \brief Representation of a real-time task
128  *
129  * This structure represents a real-time task and is used
130  * by the real-time module and the architecture specific
131  * support module for the real-time module.
132  */
133 struct rtimer {
134  rtimer_clock_t time;
135  rtimer_callback_t func;
136  void *ptr;
137 };
138 
139 /**
140  * TODO: we need to document meanings of these symbols.
141  */
142 enum {
143  RTIMER_OK, /**< rtimer task is scheduled successfully */
144  RTIMER_ERR_FULL,
145  RTIMER_ERR_TIME,
146  RTIMER_ERR_ALREADY_SCHEDULED,
147 };
148 
149 /**
150  * \brief Post a real-time task.
151  * \param task A pointer to the task variable allocated somewhere.
152  * \param time The time when the task is to be executed.
153  * \param duration Unused argument.
154  * \param func A function to be called when the task is executed.
155  * \param ptr An opaque pointer that will be supplied as an argument to the callback function.
156  * \return RTIMER_OK if the task could be scheduled. Any other value indicates
157  * the task could not be scheduled.
158  *
159  * This function schedules a real-time task at a specified
160  * time in the future.
161  *
162  */
163 int rtimer_set(struct rtimer *task, rtimer_clock_t time,
164  rtimer_clock_t duration, rtimer_callback_t func, void *ptr);
165 
166 /**
167  * \brief Execute the next real-time task and schedule the next task, if any
168  *
169  * This function is called by the architecture dependent
170  * code to execute and schedule the next real-time task.
171  *
172  */
173 void rtimer_run_next(void);
174 
175 /**
176  * \brief Get the current clock time
177  * \return The current time
178  *
179  * This function returns what the real-time module thinks
180  * is the current time. The current time is used to set
181  * the timeouts for real-time tasks.
182  *
183  * \hideinitializer
184  */
185 #define RTIMER_NOW() rtimer_arch_now()
186 
187 /**
188  * \brief Get the time that a task last was executed
189  * \param task The task
190  * \return The time that a task last was executed
191  *
192  * This function returns the time that the task was last
193  * executed. This typically is used to get a periodic
194  * execution of a task without clock drift.
195  *
196  * \hideinitializer
197  */
198 #define RTIMER_TIME(task) ((task)->time)
199 
200 /** \brief Busy-wait until a condition. Start time is t0, max wait time is max_time */
201 #ifndef RTIMER_BUSYWAIT_UNTIL_ABS
202 #define RTIMER_BUSYWAIT_UNTIL_ABS(cond, t0, max_time) \
203  ({ \
204  bool c; \
205  while(!(c = cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), (t0) + (max_time))); \
206  c; \
207  })
208 #endif /* RTIMER_BUSYWAIT_UNTIL_ABS */
209 
210 /** \brief Busy-wait until a condition for at most max_time */
211 #define RTIMER_BUSYWAIT_UNTIL(cond, max_time) \
212  ({ \
213  rtimer_clock_t t0 = RTIMER_NOW(); \
214  RTIMER_BUSYWAIT_UNTIL_ABS(cond, t0, max_time); \
215  })
216 
217 /** \brief Busy-wait for a fixed duration */
218 #define RTIMER_BUSYWAIT(duration) RTIMER_BUSYWAIT_UNTIL(0, duration)
219 
220 /*---------------------------------------------------------------------------*/
221 
222 /**
223  * \name Architecture-dependent symbols
224  *
225  * The functions declared in this section must be defined in
226  * architecture-dependent implementation of rtimer. Alternatively,
227  * they can be defined as macros in rtimer-arch.h.
228  *
229  * In addition, the architecture-dependent header (rtimer-arch.h)
230  * must define the following macros.
231  *
232  * - RTIMER_ARCH_SECOND
233  * - US_TO_RTIMERTICKS(us)
234  * - RTIMERTICKS_TO_US(t)
235  * - RTIMERTICKS_TO_US_64(t)
236  *
237  * @{
238  */
239 
240 /**
241  * Initialized the architecture-dependent part of rtimer.
242  */
243 void rtimer_arch_init(void);
244 
245 /**
246  * Schedule the call to `rtimer_run_next` at the time t.
247  */
248 void rtimer_arch_schedule(rtimer_clock_t t);
249 
250 /*
251  * Return the current time in rtimer ticks.
252  *
253  * Currently rtimer_arch_now() needs to be defined in rtimer-arch.h
254  */
255 /* rtimer_clock_t rtimer_arch_now(void); */
256 
257 /** @} */
258 
259 #endif /* RTIMER_H_ */
260 
261 /** @} */
262 /** @} */
int rtimer_set(struct rtimer *rtimer, rtimer_clock_t time, rtimer_clock_t duration, rtimer_callback_t func, void *ptr)
Post a real-time task.
Definition: rtimer.c:67
Representation of a real-time task.
Definition: rtimer.h:133
void rtimer_run_next(void)
Execute the next real-time task and schedule the next task, if any.
Definition: rtimer.c:92
void rtimer_arch_init(void)
Initialized the architecture-dependent part of rtimer.
Definition: rtimer-arch.c:59
rtimer task is scheduled successfully
Definition: rtimer.h:143
void rtimer_init(void)
Initialize the real-time scheduler.
Definition: rtimer.c:61
void rtimer_arch_schedule(rtimer_clock_t t)
Schedule the call to rtimer_run_next at the time t.
Definition: rtimer-arch.c:71