source: rtems/cpukit/include/rtems/score/todimpl.h @ a660e9dc

Last change on this file since a660e9dc was a660e9dc, checked in by Sebastian Huber <sebastian.huber@…>, on 09/08/22 at 08:37:05

Do not use RTEMS_INLINE_ROUTINE

Directly use "static inline" which is available in C99 and later. This brings
the RTEMS implementation closer to standard C.

Close #3935.

  • Property mode set to 100644
File size: 12.6 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSScoreTOD
7 * @ingroup RTEMSScoreTODHooks
8 *
9 * @brief This header file provides the interfaces of the
10 *   @ref RTEMSScoreTOD and the @ref RTEMSScoreTODHooks.
11 */
12
13/*
14 *  COPYRIGHT (c) 1989-2009.
15 *  On-Line Applications Research Corporation (OAR).
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 * 1. Redistributions of source code must retain the above copyright
21 *    notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 *    notice, this list of conditions and the following disclaimer in the
24 *    documentation and/or other materials provided with the distribution.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39#ifndef _RTEMS_SCORE_TODIMPL_H
40#define _RTEMS_SCORE_TODIMPL_H
41
42#include <rtems/score/status.h>
43#include <rtems/score/timestamp.h>
44#include <rtems/score/timecounterimpl.h>
45#include <rtems/score/watchdog.h>
46#include <rtems/score/watchdogticks.h>
47
48#include <sys/time.h>
49#include <time.h>
50
51#ifdef __cplusplus
52extern "C" {
53#endif
54
55/**
56 * @defgroup RTEMSScoreTOD Time of Day Handler
57 *
58 * @ingroup RTEMSScore
59 *
60 * @brief This group contains the Time of Day Handler implementation.
61 *
62 * The following constants are related to the time of day and are
63 * independent of RTEMS.
64 *
65 * @{
66 */
67
68/**
69 *  This constant represents the number of seconds in a minute.
70 */
71#define TOD_SECONDS_PER_MINUTE (uint32_t)60
72
73/**
74 *  This constant represents the number of minutes per hour.
75 */
76#define TOD_MINUTES_PER_HOUR   (uint32_t)60
77
78/**
79 *  This constant represents the number of months in a year.
80 */
81#define TOD_MONTHS_PER_YEAR    (uint32_t)12
82
83/**
84 *  This constant represents the number of days in a non-leap year.
85 */
86#define TOD_DAYS_PER_YEAR      (uint32_t)365
87
88/**
89 *  This constant represents the number of hours per day.
90 */
91#define TOD_HOURS_PER_DAY      (uint32_t)24
92
93/**
94 *  This constant represents the number of seconds in a day which does
95 *  not include a leap second.
96 */
97#define TOD_SECONDS_PER_DAY    (uint32_t) (TOD_SECONDS_PER_MINUTE * \
98                                TOD_MINUTES_PER_HOUR   * \
99                                TOD_HOURS_PER_DAY)
100
101/**
102 *  This constant represents the number of seconds in a non-leap year.
103 */
104#define TOD_SECONDS_PER_NON_LEAP_YEAR (365 * TOD_SECONDS_PER_DAY)
105
106/**
107 *  This constant represents the number of millisecond in a second.
108 */
109#define TOD_MILLISECONDS_PER_SECOND     (uint32_t)1000
110
111/**
112 *  This constant represents the number of microseconds in a second.
113 */
114#define TOD_MICROSECONDS_PER_SECOND     (uint32_t)1000000
115
116/**
117 *  This constant represents the number of nanoseconds in a second.
118 */
119#define TOD_NANOSECONDS_PER_SECOND      (uint32_t)1000000000
120
121/**
122 *  This constant represents the number of nanoseconds in a mircosecond.
123 */
124#define TOD_NANOSECONDS_PER_MICROSECOND (uint32_t)1000
125
126/**@}*/
127
128/**
129 *  Seconds from January 1, 1970 to January 1, 1988.  Used to account for
130 *  differences between POSIX API and RTEMS core. The timespec format time
131 *  is kept in POSIX compliant form.
132 */
133#define TOD_SECONDS_1970_THROUGH_1988 \
134  (((1987 - 1970 + 1)  * TOD_SECONDS_PER_NON_LEAP_YEAR) + \
135  (4 * TOD_SECONDS_PER_DAY))
136
137/**
138 * @brief Seconds from 1970-01-01T00:00:00Z to 2400-01-01T00:00:00Z.
139 *
140 * This is the latest time of day which should be set by _TOD_Set().  The year
141 * 2400 was chosen to guarantee a defined CLOCK_REALTIME within the range of a
142 * system uptime of about 114 years.
143 */
144#define TOD_SECONDS_1970_THROUGH_2400 13569465600
145
146/**
147 *  @brief Earliest year to which an time of day can be initialized.
148 *
149 *  The following constant define the earliest year to which an
150 *  time of day can be initialized.  This is considered the
151 *  epoch.
152 */
153#define TOD_BASE_YEAR 1988
154
155/**
156 *  @brief Latest year to which a time of day can be initialized.
157 *
158 *  The following constant defines the latest year to which an
159 *  RTEMS time of day can be set using rtems_clock_set().
160 *
161 *  32 bits can accept as latest point in time 2106-Feb-7 6:28:15
162 *  but to simplify the implementation, is was decided to only
163 *  check that the year is not greater than the year of this constant.
164 *  The year 2099 was chosen because all years evenly divisible by 4 from 1988
165 *  to 2099 are leap years.  In this time frame, years evenly divisible by 100
166 *  are no leap years unless they are evenly divisible by 400.  Thus the year
167 *  2000 is a leap year.
168 *
169 *  The internal CLOCK_REALTIME can run centuries longer but in
170 *  contrast to the POSIX API, the RTEMS Classic API does not
171 *  support this for efficiency reasons.
172 */
173#define TOD_LATEST_YEAR 2099
174
175/**
176 * @addtogroup RTEMSScoreTOD
177 *
178 * This handler encapsulates functionality used to manage time of day.
179 *
180 * @{
181 */
182
183/**
184 *  @brief TOD control.
185 */
186typedef struct {
187  /**
188   *  @brief Indicates if the time of day is set.
189   *
190   *  This is true if the application has set the current
191   *  time of day, and false otherwise.
192   */
193  bool is_set;
194} TOD_Control;
195
196/**
197 * @brief TOD Management information
198 */
199extern TOD_Control _TOD;
200
201/**
202 * @brief This array contains the number of days in all months up to the month
203 *   indicated by the index of the second dimension.
204 *
205 * The first dimension should be 0 for leap years, and 1 otherwise.
206 */
207extern const uint16_t _TOD_Days_to_date[ 2 ][ 13 ];
208
209/**
210 * @brief Locks the time of day mutex.
211 */
212void _TOD_Lock( void );
213
214/**
215 * @brief Unlocks the time of day mutex.
216 */
217void _TOD_Unlock( void );
218
219/**
220 * @brief Checks if api mutex is owner of the time of day mutex.
221 *
222 * @retval true It is owner of the time of day mutex.
223 * @retval false It is not owner of the time of day mutex.
224 */
225#if defined(RTEMS_DEBUG)
226bool _TOD_Is_owner( void );
227#endif
228
229/**
230 * @brief Acquires the lock context for the timecounter.
231 *
232 * @param lock_context The lock to acquire.
233 */
234static inline void _TOD_Acquire( ISR_lock_Context *lock_context )
235{
236  _Timecounter_Acquire( lock_context );
237}
238
239/**
240 * @brief Releases the lock context for the timecounter.
241 *
242 * @param lock_context The lock to release.
243 */
244static inline void _TOD_Release( ISR_lock_Context *lock_context )
245{
246  _Timecounter_Release( lock_context );
247}
248
249/**
250 * @brief Maps the year to the leap year index.
251 *
252 * @param year is the year to map.
253 *
254 * @retval 0 The year is a leap year.
255 *
256 * @retval 1 The year is not a leap year.
257 */
258static inline size_t _TOD_Get_leap_year_index( uint32_t year )
259{
260  _Assert( year % 4 != 0 || year % 100 != 0 || year % 400 == 0 );
261  return ( ( year % 4 ) + 3 ) / 4;
262}
263
264/**
265 * @brief Checks the time point is a valid new time of day for _TOD_Set().
266 *
267 * @param tod the time of day to check.
268 *
269 * @retval STATUS_SUCCESSFUL The time of day is valid.
270 *
271 * @retval STATUS_INVALID_NUMBER The time of day is invalid.
272 */
273Status_Control _TOD_Is_valid_new_time_of_day( const struct timespec *tod );
274
275/**
276 * @brief Sets the time of day.
277 *
278 * The caller must be the owner of the TOD lock.
279 *
280 * @param tod The new time of day in timespec format representing
281 *   the time since UNIX Epoch.  The new time of day shall be valid according
282 *   to _TOD_Is_valid_new_time_of_day().
283 * @param lock_context The ISR lock context used for the corresponding
284 *   _TOD_Acquire().  The caller must be the owner of the TOD lock.  This
285 *   function will release the TOD lock.
286 *
287 * @retval STATUS_SUCCESSFUL Successful operation.
288 * @retval other Some error occurred.
289 */
290Status_Control _TOD_Set(
291  const struct timespec *tod,
292  ISR_lock_Context      *lock_context
293);
294
295/**
296 * @brief Gets the current time in the timespec format.
297 *
298 * @param[out] time The value gathered by the request.
299 */
300static inline void _TOD_Get(
301  struct timespec *tod
302)
303{
304  _Timecounter_Nanotime( tod );
305}
306
307/**
308 * @brief Gets the system uptime with potential accuracy to the nanosecond.
309 *
310 * This routine returns the system uptime with potential accuracy
311 * to the nanosecond.
312 *
313 * The initial uptime value is undefined.
314 *
315 * @param[out] time Is a pointer to the uptime after the method call.
316 */
317static inline void _TOD_Get_uptime(
318  Timestamp_Control *time
319)
320{
321  *time = _Timecounter_Sbinuptime();
322}
323
324/**
325 * @brief Gets the system uptime with potential accuracy to the nanosecond.
326 *
327 * The initial uptime value is zero.
328 *
329 * @param[out] time Is a pointer to the uptime after the method call.
330 */
331static inline void _TOD_Get_zero_based_uptime(
332  Timestamp_Control *time
333)
334{
335  *time = _Timecounter_Sbinuptime() - SBT_1S;
336}
337
338/**
339 * @brief Gets the system uptime with potential accuracy to the nanosecond.
340 *
341 * The initial uptime value is zero.
342 *
343 * @param[out] time Is a pointer to the uptime after the method call.
344 */
345static inline void _TOD_Get_zero_based_uptime_as_timespec(
346  struct timespec *time
347)
348{
349  _Timecounter_Nanouptime( time );
350  --time->tv_sec;
351}
352
353/**
354 * @brief Returns Number of seconds Since RTEMS epoch.
355 *
356 * The following contains the number of seconds from 00:00:00
357 * January 1, TOD_BASE_YEAR until the current time of day.
358 *
359 * @return The number of seconds since RTEMS epoch.
360 */
361static inline uint32_t _TOD_Seconds_since_epoch( void )
362{
363  return (uint32_t) _Timecounter_Time_second;
364}
365
366/**
367 *  @brief Gets number of ticks in a second.
368 */
369#define TOD_TICKS_PER_SECOND _Watchdog_Ticks_per_second
370
371/**
372 * @brief This routine returns a timeval based upon the internal timespec
373 *      format TOD.
374 *
375 * @param[out] time The timeval to be filled in by the method.
376 */
377static inline void _TOD_Get_timeval(
378  struct timeval *time
379)
380{
381  _Timecounter_Microtime( time );
382}
383
384/**
385 * @brief Adjusts the Time of Time.
386 *
387 * This method is used to adjust the current time of day by the
388 * specified amount.
389 *
390 * @param delta is the amount to adjust.
391 *
392 * @retval STATUS_SUCCESSFUL Successful operation.
393 * @retval other Some error occurred.
394 */
395Status_Control _TOD_Adjust(
396  const struct timespec *delta
397);
398
399/**
400 * @brief Check if the TOD is Set
401 *
402 * @retval true The time is set.
403 * @retval false The time is not set.
404 */
405static inline bool _TOD_Is_set( void )
406{
407  return _TOD.is_set;
408}
409
410/** @} */
411
412/**
413 * @defgroup RTEMSScoreTODHooks Time of Day Handler Action Hooks
414 *
415 * @ingroup RTEMSScoreTOD
416 *
417 * @brief This group contains the implementation to support Time of Day Handler
418 *   action hooks.
419 *
420 * The following support registering a hook which is invoked
421 * when the TOD is set. These can be used by a paravirtualized
422 * BSP to mirror time changes to the hosting environment or a
423 * regular BSP to program a real-time clock when the RTEMS TOD
424 * is set.
425 *
426 * @{
427 */
428
429/**
430 *  @brief Possible actions where a registered hook could be invoked
431 */
432typedef enum {
433  /**
434   *  @brief Constant to indicate the TOD is being set.
435   */
436  TOD_ACTION_SET_CLOCK
437} TOD_Action;
438
439/**
440 * @brief Structure to manage each TOD action hook
441 */
442typedef struct TOD_Hook {
443  /** This is the chain node portion of an object. */
444  Chain_Node Node;
445
446  /** This is the TOD action hook that is invoked. */
447  Status_Control ( *handler )( TOD_Action, const struct timespec * );
448} TOD_Hook;
449
450/**
451 * @brief Set of registered methods for TOD Actions
452 */
453extern Chain_Control _TOD_Hooks;
454
455/**
456 * @brief Add a TOD Action Hook
457 *
458 * This method is used to add a hook to the TOD action set.
459 *
460 * @brief hook is the action hook to register.
461 */
462void _TOD_Hook_Register(
463  TOD_Hook *hook
464);
465
466/**
467 * @brief Remove a TOD Action Hook
468 *
469 * This method is used to remove a hook from the TOD action set.
470 *
471 * @brief hook is the action hook to unregister.
472 */
473void _TOD_Hook_Unregister(
474  TOD_Hook *hook
475);
476
477/**
478 * @brief Run the TOD Action Hooks
479 *
480 * This method is used to invoke the set of TOD action hooks.
481 *
482 * @brief action The action which triggered this run.
483 * @brief tod The current time of day.
484 *
485 * @retval STATUS_SUCCESSFUL Successful operation.
486 * @retval other Some error occurred.
487 */
488Status_Control _TOD_Hook_Run(
489  TOD_Action             action,
490  const struct timespec *tod
491);
492
493
494/** @} */
495
496#ifdef __cplusplus
497}
498#endif
499
500#endif
501/* end of include file */
Note: See TracBrowser for help on using the repository browser.