1 /*- 2 * Copyright (c) 2017 Mark Johnston <markj@FreeBSD.org> 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice unmodified, this list of conditions, and the following 9 * disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #ifndef _LINUXKPI_LINUX_HRTIMER_H_ 27 #define _LINUXKPI_LINUX_HRTIMER_H_ 28 29 #include "sys/types.h" 30 #include "los_base.h" 31 #include "los_task.h" 32 33 #ifdef __cplusplus 34 #if __cplusplus 35 extern "C" { 36 #endif /* __cplusplus */ 37 #endif /* __cplusplus */ 38 39 40 /** 41 * @ingroup hr_swtmr 42 * Define the number of timer cycles in 1us. 43 */ 44 #define HRTIMER_PERUS (OS_SYS_CLOCK / 1000000.0) 45 46 /** 47 * @ingroup hr_swtmr 48 * Define s64 as a signed long integer. 49 */ 50 typedef signed long long s64; 51 52 /** 53 * @ingroup hr_swtmr 54 * Define s32 as a signed long integer. 55 */ 56 typedef signed int s32; 57 58 /** 59 * @ingroup hr_swtmr 60 * Define u64 as an unsigned long integer. 61 */ 62 typedef unsigned long long u64; 63 64 /** 65 * @ingroup hr_swtmr 66 * Structure of the scheduled time. 67 */ 68 union ktime { 69 s64 tv64; /**< Scheduled time for 64-bit CPU systems. */ 70 struct { 71 s32 sec, usec; /**< Scheduled time for 32-bit CPU systems. */ 72 } tv; 73 }; 74 75 /** 76 * @ingroup hr_swtmr 77 * Structure of a node in a high-resolution timer queue. 78 */ 79 struct timerqueue_node { 80 unsigned int node; /**< Not in use temporarily. */ 81 }; 82 83 /** 84 * @ingroup hr_swtmr 85 * Enumerative structure of the high-resolution timer mode arguments. 86 */ 87 enum hrtimer_mode { 88 HRTIMER_MODE_ABS = 0x0, /**< Time value is absolute. */ 89 HRTIMER_MODE_REL = 0x1, /**< Time value is relative to now. */ 90 HRTIMER_MODE_PINNED = 0x2, /**< Timer is bound to CPU. */ 91 }; 92 93 /** 94 * @ingroup hr_swtmr 95 * Enumerative structure of the return type of a high-resolution timer timeout callback function. 96 */ 97 enum hrtimer_restart { 98 HRTIMER_NORESTART, /**< The timer will not be restarted.*/ 99 HRTIMER_RESTART /**< The timer must be restarted.*/ 100 }; 101 struct hrtimer; 102 103 /** 104 * @ingroup hr_swtmr 105 * Define the function handler type of a high-resolution timer timeout callback function. 106 */ 107 typedef enum hrtimer_restart (*Handler)(struct hrtimer *); 108 109 /** 110 * @ingroup hr_swtmr 111 * Structure of parameters of a high-resolution timer API. 112 */ 113 struct hrtimer { 114 union ktime _softexpires; /**< Structure of the scheduled time. */ 115 Handler function; /**< Timeout callback function. */ 116 unsigned long state; /**< Timer working state. Not in use temporarily. */ 117 #ifdef CONFIG_TIMER_STATS 118 int start_pid; /**< ID of the task that invokes a high-resolution timer. 119 Not in use temporarily. */ 120 void *start_site; /**< Function that invokes a high-resolution timer. Not in use temporarily. */ 121 #define START_TASK_NAME_LEN 16 122 char start_comm[START_TASK_NAME_LEN]; /**< Name of the task that invokes a high-resolution timer. 123 Not in use temporarily. */ 124 #endif 125 }; 126 127 /** 128 * @ingroup hr_swtmr 129 * Parameter structure of the nodes of a high-resolution timer timeout callback function. 130 */ 131 struct handler_list_node { 132 struct handler_list_node *pstNext; /**< Pointer to the next node. */ 133 Handler pfnHandler; /**< Timeout callback function. */ 134 union ktime _softexpires; /**< Structure of the scheduled time. */ 135 }; 136 137 /** 138 * @ingroup hr_swtmr 139 * Parameter structure of a high-resolution timer node. 140 */ 141 struct hrtimer_list_node { 142 struct hrtimer_list_node *pstNext; /**< Pointer to the next node. */ 143 struct handler_list_node *HandlerHead; /**< Pointer to the node queue of a timeout callback function. */ 144 unsigned int set_time_reload; /**< Count of timers. */ 145 union ktime _softexpires; /**< Structure of the scheduled time. */ 146 }; 147 148 #define hrtimer_init(timer, clockID, mode) \ 149 linux_hrtimer_init(timer, clockID, mode) 150 151 #define hrtimer_create(timer, time, handler) \ 152 linux_hrtimer_create(timer, time, handler) 153 154 #define hrtimer_start(timer, time, mode) \ 155 linux_hrtimer_start(timer, time, mode) 156 157 #define hrtimer_cancel(timer) \ 158 linux_hrtimer_cancel(timer) 159 160 #define hrtimer_forward(timer, interval) \ 161 linux_hrtimer_forward(timer, interval) 162 163 #define hrtimer_is_queued(timer) \ 164 linux_hrtimer_is_queued(timer) 165 166 /** 167 * @ingroup hr_swtmr 168 * @brief Initialize a high-resolution timer. 169 * 170 * @par Description: 171 * This API is used to initialize a high-resolution timer to the given clock. 172 * @attention 173 * <ul> 174 * <li>The pointer to the high-resolution timer structure to be initialized must not be null.</li> 175 * </ul> 176 * 177 * @param timer [IN] Pointer to the high-resolution timer structure. 178 * @param clockID [IN] This parameter is not supported, so users can pass in any integer. 179 * @param mode [IN] Mode setting is currently not supported by Huawei LiteOS. 180 * 181 * @retval None. 182 * @par Dependency: 183 * <ul> 184 * <li>hrtimer.h: the header file that contains the API declaration.</li> 185 * </ul> 186 * @see None. 187 */ 188 void linux_hrtimer_init(struct hrtimer *timer, clockid_t clockID, enum hrtimer_mode mode); 189 190 /** 191 * @ingroup hr_swtmr 192 * @brief Create a high-resolution timer. 193 * 194 * @par Description: 195 * This API is used to create a high-resolution timer node and initialize timer parameters. 196 * @attention 197 * <ul> 198 * <li>The passed-in pointer to the high-resolution timer structure must not be null.</li> 199 * <li>The value of the scheduled time cannot be zero.</li> 200 * </ul> 201 * 202 * @param timer [IN] Pointer to the high-resolution timer structure. 203 * @param time [IN] Structure of the scheduled time. 204 * @param handler [IN] Pointer to the timeout callback function. 205 * 206 * @retval -1 The high-resolution timer fails to be created because the pointer to 207 * the high-resolution timer structure is null. 208 * @retval 0 The high-resolution timer is successfully created. 209 * @par Dependency: 210 * <ul> 211 * <li>hrtimer.h: the header file that contains the API declaration.</li> 212 * </ul> 213 * @see None. 214 */ 215 int linux_hrtimer_create(struct hrtimer *timer, union ktime time, Handler handler); 216 217 /** 218 * @ingroup hr_swtmr 219 * @brief Start a high-resolution timer. 220 * 221 * @par Description: 222 * This API is used to add a high-resolution timer node to the global linked list and start timing. 223 * @attention 224 * <ul> 225 * <li>The passed-in pointer to the high-resolution timer structure must not be null.</li> 226 * <li>The value of the scheduled time cannot be zero.</li> 227 * </ul> 228 * 229 * @param timer [IN] Pointer to the high-resolution timer structure. 230 * @param time [IN] Structure of the scheduled time. 231 * @param mode [IN] Mode setting is currently not supported by Huawei LiteOS. 232 * 233 * @retval -1 The high-resolution timer fails to be started. 234 * @retval 0 The high-resolution timer is successfully started. 235 * @retval 1 The high-resolution timer node is already in the linked list. 236 Only the scheduled time will be updated and a new timer node will not be created. 237 * @par Dependency: 238 * <ul> 239 * <li>hrtimer.h: the header file that contains the API declaration.</li> 240 * </ul> 241 * @see hrtimer_cancel 242 */ 243 int linux_hrtimer_start(struct hrtimer *timer, union ktime time, const enum hrtimer_mode mode); 244 245 /** 246 * @ingroup hr_swtmr 247 * @brief Delete an existing high-resolution timer. 248 * 249 * @par Description: 250 * This API is used to delete an existing high-resolution timer. The timeout callback function applied in 251 * an existing high-resolution timer is deleted first. If the timeout callback function linked list is not null 252 * after the function is deleted, the timer will not be deleted. If the timeout callback function linked list is null 253 * after the function is deleted, the timer will be deleted. 254 * @attention 255 * <ul> 256 * <li>If the pointer to the high-resolution timer is null or the timer node does not exist, 257 * the high-resolution timer fails to be deleted.</li> 258 * </ul> 259 * 260 * @param timer [IN] Pointer to the high-resolution timer structure to be deleted. 261 * 262 * @retval -1 The high-resolution timer fails to be deleted. 263 * @retval 0 The timer to be deleted does not exist. 264 * @retval 1 The timer is in scheduled state. 265 * @par Dependency: 266 * <ul> 267 * <li>hrtimer.h: the header file that contains the API declaration.</li> 268 * </ul> 269 * @see hrtimer_start 270 */ 271 int linux_hrtimer_cancel(struct hrtimer *timer); 272 273 /** 274 * @ingroup hr_swtmr 275 * @brief Forward the expiry of an existing high-resolution timer. 276 * 277 * @par Description: 278 * This API is used to change the scheduled time of an existing high-resolution timer to 279 * the time specified by the passed-in parameter. 280 * @attention 281 * <ul> 282 * <li>If the timer does not exist, create a timer.</li> 283 * <li>The value of the scheduled time cannot be zero.</li> 284 * </ul> 285 * 286 * @param timer [IN] Pointer to the high-resolution timer structure. 287 * @param interval [IN] Structure of the interval to forward. 288 * 289 * @retval 0 The timer expiry fails to be forwarded. 290 * @retval Timer value The timer expiry is successfully forwarded. 291 * @par Dependency: 292 * <ul> 293 * <li>hitimer.h: the header file that contains the API declaration.</li> 294 * </ul> 295 * @see None. 296 */ 297 u64 linux_hrtimer_forward(struct hrtimer *timer, union ktime interval); 298 299 /** 300 * @ingroup hr_swtmr 301 * @brief Check whether a specified high-resolution timer exists. 302 * 303 * @par Description: 304 * This API is used to determine whether a specified high-resolution timer exists by 305 * querying the global linked list of timer nodes. 306 * @attention 307 * <ul> 308 * <li>None.</li> 309 * </ul> 310 * 311 * @param timer [IN] Pointer to the high-resolution timer structure to be checked. 312 * 313 * @retval #LOS_NOK 1: The queried timer does not exist. 314 * @retval #LOS_OK 0: The queried timer exists. 315 * @retval #-1 The value of the parameter timer is NULL. 316 * @par Dependency 317 * <ul> 318 * <li>hrtimer.h: the header file that contains the API declaration.</li> 319 * </ul> 320 * @see None. 321 */ 322 int linux_hrtimer_is_queued(struct hrtimer *timer); 323 324 #ifdef __cplusplus 325 #if __cplusplus 326 } 327 #endif /* __cplusplus */ 328 #endif /* __cplusplus */ 329 330 #endif /* _LINUXKPI_LINUX_HRTIMER_H */ 331