![]() |
|
|||
File indexing completed on 2025-05-11 08:24:13
0001 /* SPDX-License-Identifier: BSD-2-Clause */ 0002 0003 /** 0004 * @file 0005 * 0006 * @ingroup RTEMSScoreTOD 0007 * @ingroup RTEMSScoreTODHooks 0008 * 0009 * @brief This header file provides the interfaces of the 0010 * @ref RTEMSScoreTOD and the @ref RTEMSScoreTODHooks. 0011 */ 0012 0013 /* 0014 * COPYRIGHT (c) 1989-2009. 0015 * On-Line Applications Research Corporation (OAR). 0016 * 0017 * Redistribution and use in source and binary forms, with or without 0018 * modification, are permitted provided that the following conditions 0019 * are met: 0020 * 1. Redistributions of source code must retain the above copyright 0021 * notice, this list of conditions and the following disclaimer. 0022 * 2. Redistributions in binary form must reproduce the above copyright 0023 * notice, this list of conditions and the following disclaimer in the 0024 * documentation and/or other materials provided with the distribution. 0025 * 0026 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 0027 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0028 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 0029 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 0030 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 0031 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 0032 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 0033 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 0034 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 0035 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 0036 * POSSIBILITY OF SUCH DAMAGE. 0037 */ 0038 0039 #ifndef _RTEMS_SCORE_TODIMPL_H 0040 #define _RTEMS_SCORE_TODIMPL_H 0041 0042 #include <rtems/score/status.h> 0043 #include <rtems/score/timestamp.h> 0044 #include <rtems/score/timecounterimpl.h> 0045 #include <rtems/score/watchdog.h> 0046 #include <rtems/score/watchdogticks.h> 0047 0048 #include <sys/time.h> 0049 #include <time.h> 0050 0051 #ifdef __cplusplus 0052 extern "C" { 0053 #endif 0054 0055 /** 0056 * @defgroup RTEMSScoreTOD Time of Day Handler 0057 * 0058 * @ingroup RTEMSScore 0059 * 0060 * @brief This group contains the Time of Day Handler implementation. 0061 * 0062 * The following constants are related to the time of day and are 0063 * independent of RTEMS. 0064 * 0065 * @{ 0066 */ 0067 0068 /** 0069 * This constant represents the number of seconds in a minute. 0070 */ 0071 #define TOD_SECONDS_PER_MINUTE (uint32_t)60 0072 0073 /** 0074 * This constant represents the number of minutes per hour. 0075 */ 0076 #define TOD_MINUTES_PER_HOUR (uint32_t)60 0077 0078 /** 0079 * This constant represents the number of months in a year. 0080 */ 0081 #define TOD_MONTHS_PER_YEAR (uint32_t)12 0082 0083 /** 0084 * This constant represents the number of days in a non-leap year. 0085 */ 0086 #define TOD_DAYS_PER_YEAR (uint32_t)365 0087 0088 /** 0089 * This constant represents the number of hours per day. 0090 */ 0091 #define TOD_HOURS_PER_DAY (uint32_t)24 0092 0093 /** 0094 * This constant represents the number of seconds in a day which does 0095 * not include a leap second. 0096 */ 0097 #define TOD_SECONDS_PER_DAY (uint32_t) (TOD_SECONDS_PER_MINUTE * \ 0098 TOD_MINUTES_PER_HOUR * \ 0099 TOD_HOURS_PER_DAY) 0100 0101 /** 0102 * This constant represents the number of seconds in a non-leap year. 0103 */ 0104 #define TOD_SECONDS_PER_NON_LEAP_YEAR (365 * TOD_SECONDS_PER_DAY) 0105 0106 /** 0107 * This constant represents the number of millisecond in a second. 0108 */ 0109 #define TOD_MILLISECONDS_PER_SECOND (uint32_t)1000 0110 0111 /** 0112 * This constant represents the number of microseconds in a second. 0113 */ 0114 #define TOD_MICROSECONDS_PER_SECOND (uint32_t)1000000 0115 0116 /** 0117 * This constant represents the number of nanoseconds in a second. 0118 */ 0119 #define TOD_NANOSECONDS_PER_SECOND (uint32_t)1000000000 0120 0121 /** 0122 * This constant represents the number of nanoseconds in a mircosecond. 0123 */ 0124 #define TOD_NANOSECONDS_PER_MICROSECOND (uint32_t)1000 0125 0126 /**@}*/ 0127 0128 /** 0129 * Seconds from January 1, 1970 to January 1, 1988. Used to account for 0130 * differences between POSIX API and RTEMS core. The timespec format time 0131 * is kept in POSIX compliant form. 0132 */ 0133 #define TOD_SECONDS_1970_THROUGH_1988 \ 0134 (((1987 - 1970 + 1) * TOD_SECONDS_PER_NON_LEAP_YEAR) + \ 0135 (4 * TOD_SECONDS_PER_DAY)) 0136 0137 /** 0138 * @brief Seconds from 1970-01-01T00:00:00Z to 2400-01-01T00:00:00Z. 0139 * 0140 * This is the latest time of day which should be set by _TOD_Set(). The year 0141 * 2400 was chosen to guarantee a defined CLOCK_REALTIME within the range of a 0142 * system uptime of about 114 years. 0143 */ 0144 #define TOD_SECONDS_1970_THROUGH_2400 13569465600 0145 0146 /** 0147 * @brief Earliest year to which an time of day can be initialized. 0148 * 0149 * The following constant define the earliest year to which an 0150 * time of day can be initialized. This is considered the 0151 * epoch. 0152 */ 0153 #define TOD_BASE_YEAR 1988 0154 0155 /** 0156 * @brief Latest year to which a time of day can be initialized. 0157 * 0158 * The following constant defines the latest year to which an 0159 * RTEMS time of day can be set using rtems_clock_set(). 0160 * 0161 * 32 bits can accept as latest point in time 2106-Feb-7 6:28:15 0162 * but to simplify the implementation, is was decided to only 0163 * check that the year is not greater than the year of this constant. 0164 * The year 2099 was chosen because all years evenly divisible by 4 from 1988 0165 * to 2099 are leap years. In this time frame, years evenly divisible by 100 0166 * are no leap years unless they are evenly divisible by 400. Thus the year 0167 * 2000 is a leap year. 0168 * 0169 * The internal CLOCK_REALTIME can run centuries longer but in 0170 * contrast to the POSIX API, the RTEMS Classic API does not 0171 * support this for efficiency reasons. 0172 */ 0173 #define TOD_LATEST_YEAR 2099 0174 0175 /** 0176 * @addtogroup RTEMSScoreTOD 0177 * 0178 * This handler encapsulates functionality used to manage time of day. 0179 * 0180 * @{ 0181 */ 0182 0183 /** 0184 * @brief TOD control. 0185 */ 0186 typedef struct { 0187 /** 0188 * @brief Indicates if the time of day is set. 0189 * 0190 * This is true if the application has set the current 0191 * time of day, and false otherwise. 0192 */ 0193 bool is_set; 0194 } TOD_Control; 0195 0196 /** 0197 * @brief TOD Management information 0198 */ 0199 extern TOD_Control _TOD; 0200 0201 /** 0202 * @brief This array contains the number of days in all months up to the month 0203 * indicated by the index of the second dimension. 0204 * 0205 * The first dimension should be 0 for leap years, and 1 otherwise. 0206 */ 0207 extern const uint16_t _TOD_Days_to_date[ 2 ][ 13 ]; 0208 0209 /** 0210 * @brief Locks the time of day mutex. 0211 */ 0212 void _TOD_Lock( void ); 0213 0214 /** 0215 * @brief Unlocks the time of day mutex. 0216 */ 0217 void _TOD_Unlock( void ); 0218 0219 /** 0220 * @brief Checks if api mutex is owner of the time of day mutex. 0221 * 0222 * @retval true It is owner of the time of day mutex. 0223 * @retval false It is not owner of the time of day mutex. 0224 */ 0225 #if defined(RTEMS_DEBUG) 0226 bool _TOD_Is_owner( void ); 0227 #endif 0228 0229 /** 0230 * @brief Acquires the lock context for the timecounter. 0231 * 0232 * @param lock_context The lock to acquire. 0233 */ 0234 static inline void _TOD_Acquire( ISR_lock_Context *lock_context ) 0235 { 0236 _Timecounter_Acquire( lock_context ); 0237 } 0238 0239 /** 0240 * @brief Releases the lock context for the timecounter. 0241 * 0242 * @param lock_context The lock to release. 0243 */ 0244 static inline void _TOD_Release( ISR_lock_Context *lock_context ) 0245 { 0246 _Timecounter_Release( lock_context ); 0247 } 0248 0249 /** 0250 * @brief Maps the year to the leap year index. 0251 * 0252 * @param year is the year to map. 0253 * 0254 * @retval 0 The year is a leap year. 0255 * 0256 * @retval 1 The year is not a leap year. 0257 */ 0258 static inline size_t _TOD_Get_leap_year_index( uint32_t year ) 0259 { 0260 _Assert( year % 4 != 0 || year % 100 != 0 || year % 400 == 0 ); 0261 return ( ( year % 4 ) + 3 ) / 4; 0262 } 0263 0264 /** 0265 * @brief Checks the time point is a valid new time of day for _TOD_Set(). 0266 * 0267 * @param tod the time of day to check. 0268 * 0269 * @retval STATUS_SUCCESSFUL The time of day is valid. 0270 * 0271 * @retval STATUS_INVALID_NUMBER The time of day is invalid. 0272 */ 0273 Status_Control _TOD_Is_valid_new_time_of_day( const struct timespec *tod ); 0274 0275 /** 0276 * @brief Sets the time of day. 0277 * 0278 * The caller must be the owner of the TOD lock. 0279 * 0280 * @param tod The new time of day in timespec format representing 0281 * the time since UNIX Epoch. The new time of day shall be valid according 0282 * to _TOD_Is_valid_new_time_of_day(). 0283 * @param lock_context The ISR lock context used for the corresponding 0284 * _TOD_Acquire(). The caller must be the owner of the TOD lock. This 0285 * function will release the TOD lock. 0286 * 0287 * @retval STATUS_SUCCESSFUL Successful operation. 0288 * @retval other Some error occurred. 0289 */ 0290 Status_Control _TOD_Set( 0291 const struct timespec *tod, 0292 ISR_lock_Context *lock_context 0293 ); 0294 0295 /** 0296 * @brief Gets the current time in the timespec format. 0297 * 0298 * @param[out] time The value gathered by the request. 0299 */ 0300 static inline void _TOD_Get( 0301 struct timespec *tod 0302 ) 0303 { 0304 _Timecounter_Nanotime( tod ); 0305 } 0306 0307 /** 0308 * @brief Gets the system uptime with potential accuracy to the nanosecond. 0309 * 0310 * This routine returns the system uptime with potential accuracy 0311 * to the nanosecond. 0312 * 0313 * The initial uptime value is undefined. 0314 * 0315 * @param[out] time Is a pointer to the uptime after the method call. 0316 */ 0317 static inline void _TOD_Get_uptime( 0318 Timestamp_Control *time 0319 ) 0320 { 0321 *time = _Timecounter_Sbinuptime(); 0322 } 0323 0324 /** 0325 * @brief Gets the system uptime with potential accuracy to the nanosecond. 0326 * 0327 * The initial uptime value is zero. 0328 * 0329 * @param[out] time Is a pointer to the uptime after the method call. 0330 */ 0331 static inline void _TOD_Get_zero_based_uptime( 0332 Timestamp_Control *time 0333 ) 0334 { 0335 *time = _Timecounter_Sbinuptime() - SBT_1S; 0336 } 0337 0338 /** 0339 * @brief Gets the system uptime with potential accuracy to the nanosecond. 0340 * 0341 * The initial uptime value is zero. 0342 * 0343 * @param[out] time Is a pointer to the uptime after the method call. 0344 */ 0345 static inline void _TOD_Get_zero_based_uptime_as_timespec( 0346 struct timespec *time 0347 ) 0348 { 0349 _Timecounter_Nanouptime( time ); 0350 --time->tv_sec; 0351 } 0352 0353 /** 0354 * @brief Returns Number of seconds Since RTEMS epoch. 0355 * 0356 * The following contains the number of seconds from 00:00:00 0357 * January 1, TOD_BASE_YEAR until the current time of day. 0358 * 0359 * @return The number of seconds since RTEMS epoch. 0360 */ 0361 static inline uint32_t _TOD_Seconds_since_epoch( void ) 0362 { 0363 return (uint32_t) _Timecounter_Time_second; 0364 } 0365 0366 /** 0367 * @brief Gets number of ticks in a second. 0368 */ 0369 #define TOD_TICKS_PER_SECOND _Watchdog_Ticks_per_second 0370 0371 /** 0372 * @brief This routine returns a timeval based upon the internal timespec 0373 * format TOD. 0374 * 0375 * @param[out] time The timeval to be filled in by the method. 0376 */ 0377 static inline void _TOD_Get_timeval( 0378 struct timeval *time 0379 ) 0380 { 0381 _Timecounter_Microtime( time ); 0382 } 0383 0384 /** 0385 * @brief Check if the TOD is Set 0386 * 0387 * @retval true The time is set. 0388 * @retval false The time is not set. 0389 */ 0390 static inline bool _TOD_Is_set( void ) 0391 { 0392 return _TOD.is_set; 0393 } 0394 0395 /** @} */ 0396 0397 /** 0398 * @defgroup RTEMSScoreTODHooks Time of Day Handler Action Hooks 0399 * 0400 * @ingroup RTEMSScoreTOD 0401 * 0402 * @brief This group contains the implementation to support Time of Day Handler 0403 * action hooks. 0404 * 0405 * The following support registering a hook which is invoked 0406 * when the TOD is set. These can be used by a paravirtualized 0407 * BSP to mirror time changes to the hosting environment or a 0408 * regular BSP to program a real-time clock when the RTEMS TOD 0409 * is set. 0410 * 0411 * @{ 0412 */ 0413 0414 /** 0415 * @brief Possible actions where a registered hook could be invoked 0416 */ 0417 typedef enum { 0418 /** 0419 * @brief Constant to indicate the TOD is being set. 0420 */ 0421 TOD_ACTION_SET_CLOCK 0422 } TOD_Action; 0423 0424 /** 0425 * @brief Structure to manage each TOD action hook 0426 */ 0427 typedef struct TOD_Hook { 0428 /** This is the chain node portion of an object. */ 0429 Chain_Node Node; 0430 0431 /** This is the TOD action hook that is invoked. */ 0432 Status_Control ( *handler )( TOD_Action, const struct timespec * ); 0433 } TOD_Hook; 0434 0435 /** 0436 * @brief Set of registered methods for TOD Actions 0437 */ 0438 extern Chain_Control _TOD_Hooks; 0439 0440 /** 0441 * @brief Add a TOD Action Hook 0442 * 0443 * This method is used to add a hook to the TOD action set. 0444 * 0445 * @brief hook is the action hook to register. 0446 */ 0447 void _TOD_Hook_Register( 0448 TOD_Hook *hook 0449 ); 0450 0451 /** 0452 * @brief Remove a TOD Action Hook 0453 * 0454 * This method is used to remove a hook from the TOD action set. 0455 * 0456 * @brief hook is the action hook to unregister. 0457 */ 0458 void _TOD_Hook_Unregister( 0459 TOD_Hook *hook 0460 ); 0461 0462 /** 0463 * @brief Run the TOD Action Hooks 0464 * 0465 * This method is used to invoke the set of TOD action hooks. 0466 * 0467 * @brief action The action which triggered this run. 0468 * @brief tod The current time of day. 0469 * 0470 * @retval STATUS_SUCCESSFUL Successful operation. 0471 * @retval other Some error occurred. 0472 */ 0473 Status_Control _TOD_Hook_Run( 0474 TOD_Action action, 0475 const struct timespec *tod 0476 ); 0477 0478 0479 /** @} */ 0480 0481 #ifdef __cplusplus 0482 } 0483 #endif 0484 0485 #endif 0486 /* end of include file */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |