ChibiOS 21.11.4
chvt.h
Go to the documentation of this file.
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file rt/include/chvt.h
22 * @brief Time and Virtual Timers module macros and structures.
23 *
24 * @addtogroup time
25 * @{
26 */
27
28#ifndef CHVT_H
29#define CHVT_H
30
31/*===========================================================================*/
32/* Module constants. */
33/*===========================================================================*/
34
35/*===========================================================================*/
36/* Module pre-compile time settings. */
37/*===========================================================================*/
38
39/*===========================================================================*/
40/* Derived constants and error checks. */
41/*===========================================================================*/
42
43#if (CH_CFG_ST_TIMEDELTA < 0) || (CH_CFG_ST_TIMEDELTA == 1)
44#error "invalid CH_CFG_ST_TIMEDELTA specified, must " \
45 "be zero or greater than one"
46#endif
47
48#if (CH_CFG_ST_TIMEDELTA > 0) && (CH_CFG_TIME_QUANTUM > 0)
49#error "CH_CFG_TIME_QUANTUM not supported in tickless mode"
50#endif
51
52#if (CH_CFG_ST_TIMEDELTA > 0) && (CH_DBG_THREADS_PROFILING == TRUE)
53#error "CH_DBG_THREADS_PROFILING not supported in tickless mode"
54#endif
55
56/*===========================================================================*/
57/* Module data structures and types. */
58/*===========================================================================*/
59
60/*===========================================================================*/
61/* Module macros. */
62/*===========================================================================*/
63
64/*===========================================================================*/
65/* External declarations. */
66/*===========================================================================*/
67
68/*
69 * Virtual Timers APIs.
70 */
71#ifdef __cplusplus
72extern "C" {
73#endif
75 vtfunc_t vtfunc, void *par);
77 vtfunc_t vtfunc, void *par);
80 void chVTDoTickI(void);
81#if CH_CFG_USE_TIMESTAMP == TRUE
83 void chVTResetTimeStampI(void);
84#endif
85#ifdef __cplusplus
86}
87#endif
88
89/*===========================================================================*/
90/* Module inline functions. */
91/*===========================================================================*/
92
93/**
94 * @brief Initializes a @p virtual_timer_t object.
95 * @note Initializing a timer object is not strictly required because
96 * the function @p chVTSetI() initializes the object too. This
97 * function is only useful if you need to perform a @p chVTIsArmed()
98 * check before calling @p chVTSetI().
99 *
100 * @param[out] vtp the @p virtual_timer_t structure pointer
101 *
102 * @init
103 */
104static inline void chVTObjectInit(virtual_timer_t *vtp) {
105
106 vtp->dlist.next = NULL;
107}
108
109/**
110 * @brief Current system time.
111 * @details Returns the number of system ticks since the @p chSysInit()
112 * invocation.
113 * @note The counter can reach its maximum and then restart from zero.
114 * @note This function can be called from any context but its atomicity
115 * is not guaranteed on architectures whose word size is less than
116 * @p systime_t size.
117 *
118 * @return The system time in ticks.
119 *
120 * @xclass
121 */
122static inline systime_t chVTGetSystemTimeX(void) {
123
124#if CH_CFG_ST_TIMEDELTA == 0
125 return currcore->vtlist.systime;
126#else /* CH_CFG_ST_TIMEDELTA > 0 */
127 return port_timer_get_time();
128#endif /* CH_CFG_ST_TIMEDELTA > 0 */
129}
130
131/**
132 * @brief Current system time.
133 * @details Returns the number of system ticks since the @p chSysInit()
134 * invocation.
135 * @note The counter can reach its maximum and then restart from zero.
136 *
137 * @return The system time in ticks.
138 *
139 * @api
140 */
141static inline systime_t chVTGetSystemTime(void) {
142 systime_t systime;
143
144 chSysLock();
145 systime = chVTGetSystemTimeX();
146 chSysUnlock();
147
148 return systime;
149}
150
151/**
152 * @brief Returns the elapsed time since the specified start time.
153 *
154 * @param[in] start start time
155 * @return The elapsed time.
156 *
157 * @xclass
158 */
160
161 return chTimeDiffX(start, chVTGetSystemTimeX());
162}
163
164/**
165 * @brief Checks if the current system time is within the specified time
166 * window.
167 * @note When start==end then the function returns always false because the
168 * time window has zero size.
169 *
170 * @param[in] start the start of the time window (inclusive)
171 * @param[in] end the end of the time window (non inclusive)
172 * @retval true current time within the specified time window.
173 * @retval false current time not within the specified time window.
174 *
175 * @xclass
176 */
177static inline bool chVTIsSystemTimeWithinX(systime_t start, systime_t end) {
178
179 return chTimeIsInRangeX(chVTGetSystemTimeX(), start, end);
180}
181
182/**
183 * @brief Checks if the current system time is within the specified time
184 * window.
185 * @note When start==end then the function returns always false because the
186 * time window has zero size.
187 *
188 * @param[in] start the start of the time window (inclusive)
189 * @param[in] end the end of the time window (non inclusive)
190 * @retval true current time within the specified time window.
191 * @retval false current time not within the specified time window.
192 *
193 * @api
194 */
195static inline bool chVTIsSystemTimeWithin(systime_t start, systime_t end) {
196
197 return chTimeIsInRangeX(chVTGetSystemTime(), start, end);
198}
199
200/**
201 * @brief Returns the time interval until the next timer event.
202 * @note The return value is not perfectly accurate and can report values
203 * in excess of @p CH_CFG_ST_TIMEDELTA ticks.
204 * @note The interval returned by this function is only meaningful if
205 * more timers are not added to the list until the returned time.
206 *
207 * @param[out] timep pointer to a variable that will contain the time
208 * interval until the next timer elapses. This pointer
209 * can be @p NULL if the information is not required.
210 * @return The time, in ticks, until next time event.
211 * @retval false if the timers list is empty.
212 * @retval true if the timers list contains at least one timer.
213 *
214 * @iclass
215 */
216static inline bool chVTGetTimersStateI(sysinterval_t *timep) {
217 virtual_timers_list_t *vtlp = &currcore->vtlist;
218 ch_delta_list_t *dlp = &vtlp->dlist;
219
221
222 if (dlp == dlp->next) {
223 return false;
224 }
225
226 if (timep != NULL) {
227#if CH_CFG_ST_TIMEDELTA == 0
228 *timep = dlp->next->delta;
229#else
230 *timep = (dlp->next->delta + (sysinterval_t)CH_CFG_ST_TIMEDELTA) -
232#endif
233 }
234
235 return true;
236}
237
238/**
239 * @brief Returns @p true if the specified timer is armed.
240 * @pre The timer must have been initialized using @p chVTObjectInit()
241 * or @p chVTDoSetI().
242 *
243 * @param[in] vtp the @p virtual_timer_t structure pointer
244 * @return true if the timer is armed.
245 *
246 * @iclass
247 */
248static inline bool chVTIsArmedI(const virtual_timer_t *vtp) {
249
251
252 return (bool)(vtp->dlist.next != NULL);
253}
254
255/**
256 * @brief Returns @p true if the specified timer is armed.
257 * @pre The timer must have been initialized using @p chVTObjectInit()
258 * or @p chVTDoSetI().
259 *
260 * @param[in] vtp the @p virtual_timer_t structure pointer
261 * @return true if the timer is armed.
262 *
263 * @api
264 */
265static inline bool chVTIsArmed(const virtual_timer_t *vtp) {
266 bool b;
267
268 chSysLock();
269 b = chVTIsArmedI(vtp);
270 chSysUnlock();
271
272 return b;
273}
274
275/**
276 * @brief Disables a Virtual Timer.
277 * @note The timer is first checked and disabled only if armed.
278 * @pre The timer must have been initialized using @p chVTObjectInit()
279 * or @p chVTDoSetI().
280 *
281 * @param[in] vtp the @p virtual_timer_t structure pointer
282 *
283 * @iclass
284 */
285static inline void chVTResetI(virtual_timer_t *vtp) {
286
287 if (chVTIsArmedI(vtp)) {
288 chVTDoResetI(vtp);
289 }
290}
291
292/**
293 * @brief Disables a Virtual Timer.
294 * @note The timer is first checked and disabled only if armed.
295 * @pre The timer must have been initialized using @p chVTObjectInit()
296 * or @p chVTDoSetI().
297 *
298 * @param[in] vtp the @p virtual_timer_t structure pointer
299 *
300 * @api
301 */
302static inline void chVTReset(virtual_timer_t *vtp) {
303
304 chSysLock();
305 chVTResetI(vtp);
306 chSysUnlock();
307}
308
309/**
310 * @brief Enables a one-shot virtual timer.
311 * @details If the virtual timer was already enabled then it is re-enabled
312 * using the new parameters.
313 * @pre The timer must have been initialized using @p chVTObjectInit()
314 * or @p chVTDoSetI().
315 *
316 * @param[in] vtp the @p virtual_timer_t structure pointer
317 * @param[in] delay the number of ticks before the operation timeouts, the
318 * special values are handled as follow:
319 * - @a TIME_INFINITE is allowed but interpreted as a
320 * normal time specification.
321 * - @a TIME_IMMEDIATE this value is not allowed.
322 * .
323 * @param[in] vtfunc the timer callback function. After invoking the
324 * callback the timer is disabled and the structure can
325 * be disposed or reused.
326 * @param[in] par a parameter that will be passed to the callback
327 * function
328 *
329 * @iclass
330 */
331static inline void chVTSetI(virtual_timer_t *vtp, sysinterval_t delay,
332 vtfunc_t vtfunc, void *par) {
333
334 chVTResetI(vtp);
335 chVTDoSetI(vtp, delay, vtfunc, par);
336}
337
338/**
339 * @brief Enables a one-shot virtual timer.
340 * @details If the virtual timer was already enabled then it is re-enabled
341 * using the new parameters.
342 * @pre The timer must have been initialized using @p chVTObjectInit()
343 * or @p chVTDoSetI().
344 *
345 * @param[in] vtp the @p virtual_timer_t structure pointer
346 * @param[in] delay the number of ticks before the operation timeouts, the
347 * special values are handled as follow:
348 * - @a TIME_INFINITE is allowed but interpreted as a
349 * normal time specification.
350 * - @a TIME_IMMEDIATE this value is not allowed.
351 * .
352 * @param[in] vtfunc the timer callback function. After invoking the
353 * callback the timer is disabled and the structure can
354 * be disposed or reused.
355 * @param[in] par a parameter that will be passed to the callback
356 * function
357 *
358 * @api
359 */
360static inline void chVTSet(virtual_timer_t *vtp, sysinterval_t delay,
361 vtfunc_t vtfunc, void *par) {
362
363 chSysLock();
364 chVTSetI(vtp, delay, vtfunc, par);
365 chSysUnlock();
366}
367
368/**
369 * @brief Enables a continuous virtual timer.
370 * @details If the virtual timer was already enabled then it is re-enabled
371 * using the new parameters.
372 * @pre The timer must have been initialized using @p chVTObjectInit()
373 * or @p chVTDoSetI().
374 *
375 * @param[in] vtp the @p virtual_timer_t structure pointer
376 * @param[in] delay the number of ticks before the operation timeouts, the
377 * special values are handled as follow:
378 * - @a TIME_INFINITE is allowed but interpreted as a
379 * normal time specification.
380 * - @a TIME_IMMEDIATE this value is not allowed.
381 * .
382 * @param[in] vtfunc the timer callback function. After invoking the
383 * callback the timer is disabled and the structure can
384 * be disposed or reused.
385 * @param[in] par a parameter that will be passed to the callback
386 * function
387 *
388 * @iclass
389 */
390static inline void chVTSetContinuousI(virtual_timer_t *vtp, sysinterval_t delay,
391 vtfunc_t vtfunc, void *par) {
392
393 chVTResetI(vtp);
394 chVTDoSetContinuousI(vtp, delay, vtfunc, par);
395}
396
397/**
398 * @brief Enables a continuous virtual timer.
399 * @details If the virtual timer was already enabled then it is re-enabled
400 * using the new parameters.
401 * @pre The timer must have been initialized using @p chVTObjectInit()
402 * or @p chVTDoSetI().
403 *
404 * @param[in] vtp the @p virtual_timer_t structure pointer
405 * @param[in] delay the number of ticks before the operation timeouts, the
406 * special values are handled as follow:
407 * - @a TIME_INFINITE is allowed but interpreted as a
408 * normal time specification.
409 * - @a TIME_IMMEDIATE this value is not allowed.
410 * .
411 * @param[in] vtfunc the timer callback function. After invoking the
412 * callback the timer is disabled and the structure can
413 * be disposed or reused.
414 * @param[in] par a parameter that will be passed to the callback
415 * function
416 *
417 * @api
418 */
419static inline void chVTSetContinuous(virtual_timer_t *vtp, sysinterval_t delay,
420 vtfunc_t vtfunc, void *par) {
421
422 chSysLock();
423 chVTSetContinuousI(vtp, delay, vtfunc, par);
424 chSysUnlock();
425}
426
427/**
428 * @brief Returns the current reload value.
429 *
430 * @param[in] vtp the @p virtual_timer_t structure pointer
431 * @return The reload value.
432 *
433 * @xclass
434 */
436
437 return vtp->reload;
438}
439
440/**
441 * @brief Changes a timer reload time interval.
442 * @note This function is meant to be called from a timer callback, it
443 * does nothing in any other context.
444 * @note Calling this function from a one-shot timer callback turns it
445 * into a continuous timer.
446 *
447 * @param[in] vtp the @p virtual_timer_t structure pointer
448 * @param[in] reload the new reload value, zero means no reload
449 *
450 * @xclass
451 */
453 sysinterval_t reload) {
454
455 vtp->reload = reload;
456}
457
458#if (CH_CFG_USE_TIMESTAMP == TRUE) || defined(__DOXYGEN__)
459/**
460 * @brief Generates a monotonic time stamp.
461 * @details This function generates a monotonic time stamp synchronized with
462 * the system time. The time stamp has the same resolution of
463 * system time.
464 * @note There is an assumption, this function must be called at
465 * least once before the system time wraps back to zero or
466 * synchronization is lost. You may use a periodic virtual timer with
467 * a very large interval in order to keep time stamps synchronized
468 * by calling this function.
469 *
470 * @return The time stamp.
471 *
472 * @api
473 */
474static inline systimestamp_t chVTGetTimeStamp(void) {
475 systimestamp_t stamp;
476
477 chSysLock();
478
479 stamp = chVTGetTimeStampI();
480
481 chSysUnlock();
482
483 return stamp;
484}
485
486/**
487 * @brief Resets and re-synchronizes the time stamps monotonic counter.
488 *
489 * @api
490 */
491static inline void chVTResetTimeStamp(void) {
492
493 chSysLock();
494
496
497 chSysUnlock();
498}
499#endif /* CH_CFG_USE_TIMESTAMP == TRUE */
500
501/**
502 * @brief Virtual Timers instance initialization.
503 * @note Internal use only.
504 *
505 * @param[out] vtlp pointer to the @p virtual_timers_list_t structure
506 *
507 * @notapi
508 */
509static inline void __vt_object_init(virtual_timers_list_t *vtlp) {
510
511 ch_dlist_init(&vtlp->dlist);
512#if CH_CFG_ST_TIMEDELTA == 0
513 vtlp->systime = (systime_t)0;
514#else /* CH_CFG_ST_TIMEDELTA > 0 */
515 vtlp->lasttime = (systime_t)0;
516#endif /* CH_CFG_ST_TIMEDELTA > 0 */
517#if CH_CFG_USE_TIMESTAMP == TRUE
519#endif
520}
521
522#endif /* CHVT_H */
523
524/** @} */
#define chSysUnlock()
Leaves the kernel lock state.
#define chVTIsSystemTimeWithinX(start, end)
Checks if the current system time is within the specified time window.
#define chSysLock()
Enters the kernel lock state.
#define chVTGetSystemTimeX()
Current system time.
#define chTimeDiffX(start, end)
Subtracts two system times returning an interval.
#define chVTTimeElapsedSinceX(start)
Returns the elapsed time since the specified start time.
#define chDbgCheckClassI()
Definition chdebug.h:99
static void ch_dlist_init(ch_delta_list_t *dlhp)
Delta list initialization.
Definition chlists.h:426
struct ch_delta_list ch_delta_list_t
Type of a generic bidirectional linked delta list header and element.
Definition chlists.h:95
struct ch_virtual_timers_list virtual_timers_list_t
Type of virtual timers list header.
struct ch_virtual_timer virtual_timer_t
Type of a Virtual Timer.
Definition chobjects.h:60
void(* vtfunc_t)(virtual_timer_t *vtp, void *p)
Type of a Virtual Timer callback function.
Definition chobjects.h:70
#define CH_CFG_ST_TIMEDELTA
#define currcore
Access to current core's instance structure.
Definition chsys.h:90
uint64_t systime_t
Type of system time.
Definition chtime.h:107
static bool chTimeIsInRangeX(systime_t time, systime_t start, systime_t end)
Checks if the specified time is within the specified time range.
Definition chtime.h:484
uint64_t sysinterval_t
Type of time interval.
Definition chtime.h:119
uint64_t systimestamp_t
Type of a time stamp.
Definition chtime.h:129
static void chVTSetI(virtual_timer_t *vtp, sysinterval_t delay, vtfunc_t vtfunc, void *par)
Enables a one-shot virtual timer.
Definition chvt.h:331
static systimestamp_t chVTGetTimeStamp(void)
Generates a monotonic time stamp.
Definition chvt.h:474
void chVTDoTickI(void)
Virtual timers ticker.
Definition chvt.c:464
void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay, vtfunc_t vtfunc, void *par)
Enables a one-shot virtual timer.
Definition chvt.c:277
static void __vt_object_init(virtual_timers_list_t *vtlp)
Virtual Timers instance initialization.
Definition chvt.h:509
static bool chVTGetTimersStateI(sysinterval_t *timep)
Returns the time interval until the next timer event.
Definition chvt.h:216
void chVTResetTimeStampI(void)
Resets and re-synchronizes the time stamps monotonic counter.
Definition chvt.c:657
static bool chVTIsArmedI(const virtual_timer_t *vtp)
Returns true if the specified timer is armed.
Definition chvt.h:248
static void chVTResetI(virtual_timer_t *vtp)
Disables a Virtual Timer.
Definition chvt.h:285
static void chVTSetReloadIntervalX(virtual_timer_t *vtp, sysinterval_t reload)
Changes a timer reload time interval.
Definition chvt.h:452
static void chVTSet(virtual_timer_t *vtp, sysinterval_t delay, vtfunc_t vtfunc, void *par)
Enables a one-shot virtual timer.
Definition chvt.h:360
static void chVTObjectInit(virtual_timer_t *vtp)
Initializes a virtual_timer_t object.
Definition chvt.h:104
sysinterval_t chVTGetRemainingIntervalI(virtual_timer_t *vtp)
Returns the remaining time interval before next timer trigger.
Definition chvt.c:424
static void chVTResetTimeStamp(void)
Resets and re-synchronizes the time stamps monotonic counter.
Definition chvt.h:491
static void chVTReset(virtual_timer_t *vtp)
Disables a Virtual Timer.
Definition chvt.h:302
static systime_t chVTGetSystemTime(void)
Current system time.
Definition chvt.h:141
systimestamp_t chVTGetTimeStampI(void)
Generates a monotonic time stamp.
Definition chvt.c:626
void chVTDoSetContinuousI(virtual_timer_t *vtp, sysinterval_t delay, vtfunc_t vtfunc, void *par)
Enables a continuous virtual timer.
Definition chvt.c:314
static bool chVTIsArmed(const virtual_timer_t *vtp)
Returns true if the specified timer is armed.
Definition chvt.h:265
static void chVTSetContinuousI(virtual_timer_t *vtp, sysinterval_t delay, vtfunc_t vtfunc, void *par)
Enables a continuous virtual timer.
Definition chvt.h:390
void chVTDoResetI(virtual_timer_t *vtp)
Disables a Virtual Timer.
Definition chvt.c:338
static sysinterval_t chVTGetReloadIntervalX(virtual_timer_t *vtp)
Returns the current reload value.
Definition chvt.h:435
static systime_t chVTGetSystemTimeX(void)
Current system time.
Definition chvt.h:122
static void chVTSetContinuous(virtual_timer_t *vtp, sysinterval_t delay, vtfunc_t vtfunc, void *par)
Enables a continuous virtual timer.
Definition chvt.h:419
static bool chVTIsSystemTimeWithin(systime_t start, systime_t end)
Checks if the current system time is within the specified time window.
Definition chvt.h:195
ch_delta_list_t * next
Next in the delta list.
Definition chlists.h:101
sysinterval_t delta
Time interval from previous.
Definition chlists.h:103
ch_delta_list_t dlist
Delta list element.
Definition chobjects.h:79
sysinterval_t reload
Current reload interval.
Definition chobjects.h:91
volatile uint64_t laststamp
Last generated time stamp.
Definition chobjects.h:121
ch_delta_list_t dlist
Delta list header.
Definition chobjects.h:104
volatile systime_t systime
System Time counter.
Definition chobjects.h:109
systime_t lasttime
System time of the last tick event.
Definition chobjects.h:115