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