source: rtems/cpukit/include/rtems/score/todimpl.h @ 08bd7d3

5
Last change on this file since 08bd7d3 was 08bd7d3, checked in by Joel Sherrill <joel@…>, on 11/12/19 at 15:33:41

Add TOD Hooks to allow BSP to take action when TOD is set

Two use cases were envisioned for this.

1) a BSP or application which desires to update a real-time clock

when the RTEMS TOD is set.

2) a paravirtualized BSP can use this to propagate setting the time

in an RTEMS application to the hosting environment. This enables
the entire set of applications in the virtualized environments
to have a single consistent TOD.

  • Property mode set to 100644
File size: 9.6 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup RTEMSScoreTOD
5 *
6 * @brief Time of Day Handler API
7 */
8
9/*
10 *  COPYRIGHT (c) 1989-2009.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.org/license/LICENSE.
16 */
17
18#ifndef _RTEMS_SCORE_TODIMPL_H
19#define _RTEMS_SCORE_TODIMPL_H
20
21#include <rtems/score/timestamp.h>
22#include <rtems/score/timecounterimpl.h>
23#include <rtems/score/watchdog.h>
24
25#include <sys/time.h>
26#include <time.h>
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32/**
33 * @defgroup RTEMSScoreTOD Time of Day Handler
34 *
35 * @ingroup RTEMSScore
36 *
37 * @brief Time of Day Handler
38 *
39 * The following constants are related to the time of day and are
40 * independent of RTEMS.
41 *
42 * @{
43 */
44
45/**
46 *  This constant represents the number of seconds in a minute.
47 */
48#define TOD_SECONDS_PER_MINUTE (uint32_t)60
49
50/**
51 *  This constant represents the number of minutes per hour.
52 */
53#define TOD_MINUTES_PER_HOUR   (uint32_t)60
54
55/**
56 *  This constant represents the number of months in a year.
57 */
58#define TOD_MONTHS_PER_YEAR    (uint32_t)12
59
60/**
61 *  This constant represents the number of days in a non-leap year.
62 */
63#define TOD_DAYS_PER_YEAR      (uint32_t)365
64
65/**
66 *  This constant represents the number of hours per day.
67 */
68#define TOD_HOURS_PER_DAY      (uint32_t)24
69
70/**
71 *  This constant represents the number of seconds in a day which does
72 *  not include a leap second.
73 */
74#define TOD_SECONDS_PER_DAY    (uint32_t) (TOD_SECONDS_PER_MINUTE * \
75                                TOD_MINUTES_PER_HOUR   * \
76                                TOD_HOURS_PER_DAY)
77
78/**
79 *  This constant represents the number of seconds in a non-leap year.
80 */
81#define TOD_SECONDS_PER_NON_LEAP_YEAR (365 * TOD_SECONDS_PER_DAY)
82
83/**
84 *  This constant represents the number of millisecond in a second.
85 */
86#define TOD_MILLISECONDS_PER_SECOND     (uint32_t)1000
87
88/**
89 *  This constant represents the number of microseconds in a second.
90 */
91#define TOD_MICROSECONDS_PER_SECOND     (uint32_t)1000000
92
93/**
94 *  This constant represents the number of nanoseconds in a second.
95 */
96#define TOD_NANOSECONDS_PER_SECOND      (uint32_t)1000000000
97
98/**
99 *  This constant represents the number of nanoseconds in a mircosecond.
100 */
101#define TOD_NANOSECONDS_PER_MICROSECOND (uint32_t)1000
102
103/**@}*/
104
105/**
106 *  Seconds from January 1, 1970 to January 1, 1988.  Used to account for
107 *  differences between POSIX API and RTEMS core. The timespec format time
108 *  is kept in POSIX compliant form.
109 */
110#define TOD_SECONDS_1970_THROUGH_1988 \
111  (((1987 - 1970 + 1)  * TOD_SECONDS_PER_NON_LEAP_YEAR) + \
112  (4 * TOD_SECONDS_PER_DAY))
113
114/**
115 *  @brief Earliest year to which an time of day can be initialized.
116 *
117 *  The following constant define the earliest year to which an
118 *  time of day can be initialized.  This is considered the
119 *  epoch.
120 */
121#define TOD_BASE_YEAR 1988
122
123/**
124 * @addtogroup RTEMSScoreTOD
125 *
126 * This handler encapsulates functionality used to manage time of day.
127 *
128 * @{
129 */
130
131/**
132 *  @brief TOD control.
133 */
134typedef struct {
135  /**
136   *  @brief Indicates if the time of day is set.
137   *
138   *  This is true if the application has set the current
139   *  time of day, and false otherwise.
140   */
141  bool is_set;
142} TOD_Control;
143
144/**
145 * @brief TOD Management information
146 */
147extern TOD_Control _TOD;
148
149/**
150 * @brief Locks the time of day mutex.
151 */
152void _TOD_Lock( void );
153
154/**
155 * @brief Unlocks the time of day mutex.
156 */
157void _TOD_Unlock( void );
158
159/**
160 * @brief Checks if api mutex is owner of the time of day mutex.
161 *
162 * @retval true It is owner of the time of day mutex.
163 * @retval false It is not owner of the time of day mutex.
164 */
165#if defined(RTEMS_DEBUG)
166bool _TOD_Is_owner( void );
167#endif
168
169/**
170 * @brief Acquires the lock context for the timecounter.
171 *
172 * @param lock_context The lock to acquire.
173 */
174static inline void _TOD_Acquire( ISR_lock_Context *lock_context )
175{
176  _Timecounter_Acquire( lock_context );
177}
178
179/**
180 * @brief Releases the lock context for the timecounter.
181 *
182 * @param lock_context The lock to release.
183 */
184static inline void _TOD_Release( ISR_lock_Context *lock_context )
185{
186  _Timecounter_Release( lock_context );
187}
188
189/**
190 * @brief Sets the time of day.
191 *
192 * The caller must be the owner of the TOD lock.
193 *
194 * @param tod The new time of day in timespec format representing
195 *   the time since UNIX Epoch.
196 * @param lock_context The ISR lock context used for the corresponding
197 *   _TOD_Acquire().  The caller must be the owner of the TOD lock.  This
198 *   function will release the TOD lock.
199 *
200 * @retval true on success
201 * @retval false on failure
202 */
203bool _TOD_Set(
204  const struct timespec *tod,
205  ISR_lock_Context      *lock_context
206);
207
208/**
209 * @brief Gets the current time in the timespec format.
210 *
211 * @param[out] time The value gathered by the request.
212 */
213static inline void _TOD_Get(
214  struct timespec *tod
215)
216{
217  _Timecounter_Nanotime( tod );
218}
219
220/**
221 * @brief Gets the system uptime with potential accuracy to the nanosecond.
222 *
223 * This routine returns the system uptime with potential accuracy
224 * to the nanosecond.
225 *
226 * The initial uptime value is undefined.
227 *
228 * @param[out] time Is a pointer to the uptime after the method call.
229 */
230static inline void _TOD_Get_uptime(
231  Timestamp_Control *time
232)
233{
234  *time = _Timecounter_Sbinuptime();
235}
236
237/**
238 * @brief Gets the system uptime with potential accuracy to the nanosecond.
239 *
240 * The initial uptime value is zero.
241 *
242 * @param[out] time Is a pointer to the uptime after the method call.
243 */
244static inline void _TOD_Get_zero_based_uptime(
245  Timestamp_Control *time
246)
247{
248  *time = _Timecounter_Sbinuptime() - SBT_1S;
249}
250
251/**
252 * @brief Gets the system uptime with potential accuracy to the nanosecond.
253 *
254 * The initial uptime value is zero.
255 *
256 * @param[out] time Is a pointer to the uptime after the method call.
257 */
258static inline void _TOD_Get_zero_based_uptime_as_timespec(
259  struct timespec *time
260)
261{
262  _Timecounter_Nanouptime( time );
263  --time->tv_sec;
264}
265
266/**
267 * @brief Returns Number of seconds Since RTEMS epoch.
268 *
269 * The following contains the number of seconds from 00:00:00
270 * January 1, TOD_BASE_YEAR until the current time of day.
271 *
272 * @return The number of seconds since RTEMS epoch.
273 */
274static inline uint32_t _TOD_Seconds_since_epoch( void )
275{
276  return (uint32_t) _Timecounter_Time_second;
277}
278
279/**
280 * @brief Gets number of ticks in a second.
281 *
282 * This method returns the number of ticks in a second.
283 *
284 * @note If the clock tick value does not multiply evenly into a second
285 *       then this number of ticks will be slightly shorter than a second.
286 *
287 * @return The number of ticks in a second.
288 */
289uint32_t TOD_TICKS_PER_SECOND_method(void);
290
291/**
292 *  @brief Gets number of ticks in a second.
293 *
294 *  This method exists to hide the fact that TOD_TICKS_PER_SECOND can not
295 *  be implemented as a macro in a .h file due to visibility issues.
296 *  The Configuration Table is not available to SuperCore .h files but
297 *  is available to their .c files.
298 */
299#define TOD_TICKS_PER_SECOND TOD_TICKS_PER_SECOND_method()
300
301/**
302 * @brief This routine returns a timeval based upon the internal timespec
303 *      format TOD.
304 *
305 * @param[out] time The timeval to be filled in by the method.
306 */
307RTEMS_INLINE_ROUTINE void _TOD_Get_timeval(
308  struct timeval *time
309)
310{
311  _Timecounter_Microtime( time );
312}
313
314/**
315 * @brief Adjusts the Time of Time.
316 *
317 * This method is used to adjust the current time of day by the
318 * specified amount.
319 *
320 * @param delta is the amount to adjust.
321 */
322void _TOD_Adjust(
323  const struct timespec *delta
324);
325
326/**
327 * @brief Check if the TOD is Set
328 *
329 * @retval true The time is set.
330 * @retval false The time is not set.
331 */
332RTEMS_INLINE_ROUTINE bool _TOD_Is_set( void )
333{
334  return _TOD.is_set;
335}
336
337/** @} */
338
339/**
340 * @defgroup RTEMSScoreTODHooks Time of Day Handler Action Hooks
341 *
342 * @ingroup RTEMSScoreTOD
343 *
344 * @brief Time of Day Handler Action Hooks
345 *
346 * The following support registering a hook which is invoked
347 * when the TOD is set. These can be used by a paravirtualized
348 * BSP to mirror time changes to the hosting environment or a
349 * regular BSP to program a real-time clock when the RTEMS TOD
350 * is set.
351 *
352 * @{
353 */
354
355/**
356 *  @brief Possible actions where a registered hook could be invoked
357 */
358typedef enum {
359  /**
360   *  @brief Constant to indicate the TOD is being set.
361   */
362  TOD_ACTION_SET_CLOCK
363} TOD_Action;
364
365/**
366 * @brief Structure to manage each TOD action hook
367 */
368typedef struct TOD_Hook {
369  /** This is the chain node portion of an object. */
370  Chain_Node Node;
371
372  /** This is the TOD action hook that is invoked. */
373  bool (*handler)(TOD_Action, const struct timespec *);
374} TOD_Hook;
375
376/**
377 * @brief Set of registered methods for TOD Actions
378 */
379extern Chain_Control _TOD_Hooks;
380
381/**
382 * @brief Add a TOD Action Hook
383 *
384 * This method is used to add a hook to the TOD action set.
385 *
386 * @brief hook is the action hook to register.
387 *
388 * @retval true if the hook is added.
389 * @retval false if the hook cannot be added.
390 */
391void _TOD_Hook_Register(
392  TOD_Hook *hook
393);
394
395/**
396 * @brief Remove a TOD Action Hook
397 *
398 * This method is used to remove a hook from the TOD action set.
399 *
400 * @brief hook is the action hook to unregister.
401 *
402 * @retval true if the hook is unregister.
403 * @retval false if the hook cannot be unregister.
404 */
405void _TOD_Hook_Unregister(
406  TOD_Hook *hook
407);
408
409/**
410 * @brief Run the TOD Action Hooks
411 *
412 * This method is used to invoke the set of TOD action hooks.
413 *
414 * @brief action is the action which triggered this run.
415 * @brief tod is the current tod
416 *
417 * @retval true if the hooks can be run.
418 * @retval false if the hook cannot be run.
419 */
420bool _TOD_Hook_Run(
421  TOD_Action             action,
422  const struct timespec *tod
423);
424
425
426/** @} */
427
428#ifdef __cplusplus
429}
430#endif
431
432#endif
433/* end of include file */
Note: See TracBrowser for help on using the repository browser.