PX4 Firmware
PX4 Autopilot Software http://px4.io
drv_hrt.h
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2012-2016 PX4 Development Team. 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  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name PX4 nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 
34 /**
35  * @file drv_hrt.h
36  *
37  * High-resolution timer with callouts and timekeeping.
38  */
39 
40 #pragma once
41 
42 #include <sys/ioctl.h>
43 #include <sys/types.h>
44 #include <stdbool.h>
45 #include <inttypes.h>
46 
47 #include <px4_platform_common/time.h>
48 #include <queue.h>
49 
51 
52 /**
53  * Absolute time, in microsecond units.
54  *
55  * Absolute time is measured from some arbitrary epoch shortly after
56  * system startup. It should never wrap or go backwards.
57  */
58 typedef uint64_t hrt_abstime;
59 
60 /**
61  * Callout function type.
62  *
63  * Note that callouts run in the timer interrupt context, so
64  * they are serialised with respect to each other, and must not
65  * block.
66  */
67 typedef void (* hrt_callout)(void *arg);
68 
69 /**
70  * Callout record.
71  */
72 typedef struct hrt_call {
73  struct sq_entry_s link;
74 
78  void *arg;
79 } *hrt_call_t;
80 
81 /**
82  * Get absolute time in [us] (does not wrap).
83  */
85 
86 /**
87  * Convert a timespec to absolute time.
88  */
89 __EXPORT extern hrt_abstime ts_to_abstime(const struct timespec *ts);
90 
91 /**
92  * Convert absolute time to a timespec.
93  */
94 __EXPORT extern void abstime_to_ts(struct timespec *ts, hrt_abstime abstime);
95 
96 /**
97  * Compute the delta between a timestamp taken in the past
98  * and now.
99  *
100  * This function is not interrupt save.
101  */
102 static inline hrt_abstime hrt_elapsed_time(const hrt_abstime *then)
103 {
104  return hrt_absolute_time() - *then;
105 }
106 
107 /**
108  * Compute the delta between a timestamp taken in the past
109  * and now.
110  *
111  * This function is safe to use even if the timestamp is updated
112  * by an interrupt during execution.
113  */
114 __EXPORT extern hrt_abstime hrt_elapsed_time_atomic(const volatile hrt_abstime *then);
115 
116 /**
117  * Store the absolute time in an interrupt-safe fashion.
118  *
119  * This function ensures that the timestamp cannot be seen half-written by an interrupt handler.
120  */
122 
123 #ifdef __PX4_QURT
124 /**
125  * Set a time offset to hrt_absolute_time on the DSP.
126  * @param time_diff_us: time difference of the DSP clock to Linux clock.
127  * This param is positive if the Linux clock is ahead of the DSP one.
128  */
129 __EXPORT extern int hrt_set_absolute_time_offset(int32_t time_diff_us);
130 #endif
131 
132 /**
133  * Call callout(arg) after delay has elapsed.
134  *
135  * If callout is NULL, this can be used to implement a timeout by testing the call
136  * with hrt_called().
137  */
138 __EXPORT extern void hrt_call_after(struct hrt_call *entry, hrt_abstime delay, hrt_callout callout, void *arg);
139 
140 /**
141  * Call callout(arg) at absolute time calltime.
142  */
143 __EXPORT extern void hrt_call_at(struct hrt_call *entry, hrt_abstime calltime, hrt_callout callout, void *arg);
144 
145 /**
146  * Call callout(arg) after delay, and then after every interval.
147  *
148  * Note thet the interval is timed between scheduled, not actual, call times, so the call rate may
149  * jitter but should not drift.
150  */
151 __EXPORT extern void hrt_call_every(struct hrt_call *entry, hrt_abstime delay, hrt_abstime interval,
152  hrt_callout callout, void *arg);
153 
154 /**
155  * If this returns true, the entry has been invoked and removed from the callout list,
156  * or it has never been entered.
157  *
158  * Always returns false for repeating callouts.
159  */
160 __EXPORT extern bool hrt_called(struct hrt_call *entry);
161 
162 /**
163  * Remove the entry from the callout list.
164  */
165 __EXPORT extern void hrt_cancel(struct hrt_call *entry);
166 
167 /**
168  * Initialise a hrt_call structure
169  */
170 __EXPORT extern void hrt_call_init(struct hrt_call *entry);
171 
172 /*
173  * delay a hrt_call_every() periodic call by the given number of
174  * microseconds. This should be called from within the callout to
175  * cause the callout to be re-scheduled for a later time. The periodic
176  * callouts will then continue from that new base time at the
177  * previously specified period.
178  */
179 __EXPORT extern void hrt_call_delay(struct hrt_call *entry, hrt_abstime delay);
180 
181 /*
182  * Initialise the HRT.
183  */
184 __EXPORT extern void hrt_init(void);
185 
186 #ifdef __PX4_POSIX
187 
188 __EXPORT extern hrt_abstime hrt_reset(void);
189 
190 __EXPORT extern hrt_abstime hrt_absolute_time_offset(void);
191 
192 #endif
193 
195 
196 
197 
198 #ifdef __cplusplus
199 
200 namespace time_literals
201 {
202 
203 // User-defined integer literals for different time units.
204 // The base unit is hrt_abstime in microseconds
205 
206 constexpr hrt_abstime operator "" _s(unsigned long long seconds)
207 {
208  return hrt_abstime(seconds * 1000000ULL);
209 }
210 
211 constexpr hrt_abstime operator "" _ms(unsigned long long seconds)
212 {
213  return hrt_abstime(seconds * 1000ULL);
214 }
215 
216 constexpr hrt_abstime operator "" _us(unsigned long long seconds)
217 {
218  return hrt_abstime(seconds);
219 }
220 
221 } /* namespace time_literals */
222 
223 
224 #endif /* __cplusplus */
struct sq_entry_s link
Definition: drv_hrt.h:73
struct hrt_call * hrt_call_t
Callout record.
#define __END_DECLS
Definition: visibility.h:59
__EXPORT hrt_abstime hrt_store_absolute_time(volatile hrt_abstime *now)
Store the absolute time in an interrupt-safe fashion.
void(* hrt_callout)(void *arg)
Callout function type.
Definition: drv_hrt.h:67
Definition: I2C.hpp:51
hrt_abstime deadline
Definition: drv_hrt.h:75
__EXPORT void hrt_call_at(struct hrt_call *entry, hrt_abstime calltime, hrt_callout callout, void *arg)
Call callout(arg) at absolute time calltime.
__EXPORT void hrt_call_after(struct hrt_call *entry, hrt_abstime delay, hrt_callout callout, void *arg)
Call callout(arg) after delay has elapsed.
void * arg
Definition: drv_hrt.h:78
#define __BEGIN_DECLS
Definition: visibility.h:58
hrt_callout callout
Definition: drv_hrt.h:77
__EXPORT void hrt_call_init(struct hrt_call *entry)
Initialise a hrt_call structure.
static hrt_abstime hrt_elapsed_time(const hrt_abstime *then)
Compute the delta between a timestamp taken in the past and now.
Definition: drv_hrt.h:102
__EXPORT bool hrt_called(struct hrt_call *entry)
If this returns true, the entry has been invoked and removed from the callout list, or it has never been entered.
__EXPORT void hrt_call_every(struct hrt_call *entry, hrt_abstime delay, hrt_abstime interval, hrt_callout callout, void *arg)
Call callout(arg) after delay, and then after every interval.
__BEGIN_DECLS typedef uint64_t hrt_abstime
Absolute time, in microsecond units.
Definition: drv_hrt.h:58
__EXPORT void hrt_call_delay(struct hrt_call *entry, hrt_abstime delay)
Callout record.
Definition: drv_hrt.h:72
__EXPORT void abstime_to_ts(struct timespec *ts, hrt_abstime abstime)
Convert absolute time to a timespec.
__EXPORT void hrt_init(void)
hrt_abstime period
Definition: drv_hrt.h:76
__EXPORT hrt_abstime ts_to_abstime(const struct timespec *ts)
Convert a timespec to absolute time.
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
__EXPORT void hrt_cancel(struct hrt_call *entry)
Remove the entry from the callout list.
__EXPORT hrt_abstime hrt_elapsed_time_atomic(const volatile hrt_abstime *then)
Compute the delta between a timestamp taken in the past and now.