1 /* 2 * coap_time.h -- Clock Handling 3 * 4 * Copyright (C) 2010-2023 Olaf Bergmann <bergmann@tzi.org> 5 * 6 * SPDX-License-Identifier: BSD-2-Clause 7 * 8 * This file is part of the CoAP library libcoap. Please see README for terms 9 * of use. 10 */ 11 12 /** 13 * @file coap_time.h 14 * @brief Clock Handling 15 */ 16 17 #ifndef COAP_TIME_H_ 18 #define COAP_TIME_H_ 19 20 /** 21 * @ingroup application_api 22 * @defgroup clock Clock Handling 23 * API for internal clock assess 24 * @{ 25 */ 26 27 #if defined(WITH_LWIP) 28 29 #include <stdint.h> 30 #include <lwip/sys.h> 31 32 /* lwIP provides ms in sys_now */ 33 #define COAP_TICKS_PER_SECOND 1000 34 35 typedef uint32_t coap_tick_t; 36 typedef uint32_t coap_time_t; 37 typedef int32_t coap_tick_diff_t; 38 39 COAP_STATIC_INLINE void coap_ticks_impl(coap_tick_t * t)40coap_ticks_impl(coap_tick_t *t) { 41 *t = sys_now(); 42 } 43 44 COAP_STATIC_INLINE void coap_clock_init_impl(void)45coap_clock_init_impl(void) { 46 } 47 48 #define coap_clock_init coap_clock_init_impl 49 #define coap_ticks coap_ticks_impl 50 51 COAP_STATIC_INLINE coap_time_t coap_ticks_to_rt(coap_tick_t t)52coap_ticks_to_rt(coap_tick_t t) { 53 return t / COAP_TICKS_PER_SECOND; 54 } 55 56 COAP_STATIC_INLINE uint64_t coap_ticks_to_rt_us(coap_tick_t t)57coap_ticks_to_rt_us(coap_tick_t t) { 58 return (uint64_t)t * 1000000 / COAP_TICKS_PER_SECOND; 59 } 60 61 #elif defined(WITH_CONTIKI) 62 63 #include "clock.h" 64 65 typedef clock_time_t coap_tick_t; 66 typedef clock_time_t coap_time_t; 67 68 /** 69 * This data type is used to represent the difference between two clock_tick_t 70 * values. This data type must have the same size in memory as coap_tick_t to 71 * allow wrapping. 72 */ 73 typedef int coap_tick_diff_t; 74 75 #define COAP_TICKS_PER_SECOND CLOCK_SECOND 76 77 COAP_STATIC_INLINE void coap_clock_init(void)78coap_clock_init(void) { 79 clock_init(); 80 } 81 82 COAP_STATIC_INLINE void coap_ticks(coap_tick_t * t)83coap_ticks(coap_tick_t *t) { 84 *t = clock_time(); 85 } 86 87 COAP_STATIC_INLINE coap_time_t coap_ticks_to_rt(coap_tick_t t)88coap_ticks_to_rt(coap_tick_t t) { 89 return t / COAP_TICKS_PER_SECOND; 90 } 91 92 COAP_STATIC_INLINE uint64_t coap_ticks_to_rt_us(coap_tick_t t)93coap_ticks_to_rt_us(coap_tick_t t) { 94 return (uint64_t)t * 1000000 / COAP_TICKS_PER_SECOND; 95 } 96 97 #elif defined(RIOT_VERSION) 98 #include <xtimer.h> 99 100 #ifdef XTIMER_HZ 101 #define COAP_TICKS_PER_SECOND (XTIMER_HZ) 102 #else /* XTIMER_HZ */ 103 #define COAP_TICKS_PER_SECOND (1000000U) 104 #endif /* XTIMER_HZ */ 105 106 typedef uint64_t coap_tick_t; 107 typedef int64_t coap_tick_diff_t; 108 typedef uint32_t coap_time_t; 109 110 static inline void coap_clock_init(void)111coap_clock_init(void) {} 112 113 static inline void coap_ticks(coap_tick_t * t)114coap_ticks(coap_tick_t *t) { 115 #ifdef MODULE_ZTIMER64_XTIMER_COMPAT 116 *t = xtimer_now_usec64(); 117 #else /* MODULE_ZTIMER64_XTIMER_COMPAT */ 118 *t = xtimer_now_usec(); 119 #endif /* MODULE_ZTIMER64_XTIMER_COMPAT */ 120 } 121 122 static inline coap_time_t coap_ticks_to_rt(coap_tick_t t)123coap_ticks_to_rt(coap_tick_t t) { 124 return t / 1000000UL; 125 } 126 127 static inline uint64_t coap_ticks_to_rt_us(coap_tick_t t)128coap_ticks_to_rt_us(coap_tick_t t) { 129 return t; 130 } 131 132 static inline coap_tick_t coap_ticks_from_rt_us(uint64_t t)133coap_ticks_from_rt_us(uint64_t t) { 134 return t / 1000000UL; 135 } 136 #else /* !WITH_LWIP && !WITH_CONTIKI && !RIOT_VERSION */ 137 138 #include <stdint.h> 139 140 /** 141 * This data type represents internal timer ticks with COAP_TICKS_PER_SECOND 142 * resolution. 143 */ 144 typedef uint64_t coap_tick_t; 145 146 /** 147 * CoAP time in seconds since epoch. 148 */ 149 typedef time_t coap_time_t; 150 151 /** 152 * This data type is used to represent the difference between two clock_tick_t 153 * values. This data type must have the same size in memory as coap_tick_t to 154 * allow wrapping. 155 */ 156 typedef int64_t coap_tick_diff_t; 157 158 /** Use ms resolution on POSIX systems */ 159 #define COAP_TICKS_PER_SECOND ((coap_tick_t)(1000U)) 160 161 /** 162 * Initializes the internal clock. 163 */ 164 void coap_clock_init(void); 165 166 /** 167 * Sets @p t to the internal time with COAP_TICKS_PER_SECOND resolution. 168 */ 169 void coap_ticks(coap_tick_t *t); 170 171 /** 172 * Helper function that converts coap ticks to wallclock time. On POSIX, this 173 * function returns the number of seconds since the epoch. On other systems, it 174 * may be the calculated number of seconds since last reboot or so. 175 * 176 * @param t Internal system ticks. 177 * 178 * @return The number of seconds that has passed since a specific reference 179 * point (seconds since epoch on POSIX). 180 */ 181 coap_time_t coap_ticks_to_rt(coap_tick_t t); 182 183 /** 184 * Helper function that converts coap ticks to POSIX wallclock time in us. 185 * 186 * @param t Internal system ticks. 187 * 188 * @return The number of seconds that has passed since a specific reference 189 * point (seconds since epoch on POSIX). 190 */ 191 uint64_t coap_ticks_to_rt_us(coap_tick_t t); 192 193 /** 194 * Helper function that converts POSIX wallclock time in us to coap ticks. 195 * 196 * @param t POSIX time is us 197 * 198 * @return coap ticks 199 */ 200 coap_tick_t coap_ticks_from_rt_us(uint64_t t); 201 #endif 202 203 /** 204 * Returns @c 1 if and only if @p a is less than @p b where less is defined on a 205 * signed data type. 206 */ 207 COAP_STATIC_INLINE int coap_time_lt(coap_tick_t a,coap_tick_t b)208coap_time_lt(coap_tick_t a, coap_tick_t b) { 209 return ((coap_tick_diff_t)(a - b)) < 0; 210 } 211 212 /** 213 * Returns @c 1 if and only if @p a is less than or equal @p b where less is 214 * defined on a signed data type. 215 */ 216 COAP_STATIC_INLINE int coap_time_le(coap_tick_t a,coap_tick_t b)217coap_time_le(coap_tick_t a, coap_tick_t b) { 218 return a == b || coap_time_lt(a,b); 219 } 220 221 /** @} */ 222 223 #endif /* COAP_TIME_H_ */ 224