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
35extern "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 */
50typedef signed long long s64;
51
52/**
53 * @ingroup hr_swtmr
54 * Define s32 as a signed long integer.
55 */
56typedef signed int s32;
57
58/**
59 * @ingroup hr_swtmr
60 * Define u64 as an unsigned long integer.
61 */
62typedef unsigned long long u64;
63
64/**
65 * @ingroup hr_swtmr
66 * Structure of the scheduled time.
67 */
68union 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 */
79struct 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 */
87enum 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 */
97enum hrtimer_restart {
98    HRTIMER_NORESTART,   /**< The timer will not be restarted.*/
99    HRTIMER_RESTART      /**< The timer must be restarted.*/
100};
101struct hrtimer;
102
103/**
104 * @ingroup hr_swtmr
105 * Define the function handler type of a high-resolution timer timeout callback function.
106 */
107typedef enum hrtimer_restart (*Handler)(struct hrtimer *);
108
109/**
110 * @ingroup hr_swtmr
111 * Structure of parameters of a high-resolution timer API.
112 */
113struct 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 */
131struct 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 */
141struct 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 */
188void 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 */
215int 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 */
243int 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 */
271int 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 */
297u64 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 */
322int 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