le_timer.h

Go to the documentation of this file.
1 /**
2  * @page c_timer Timer API
3  *
4  * @subpage le_timer.h "API Reference"
5  *
6  * <HR>
7  *
8  * This module provides an API for managing and using timers.
9  *
10  * @note
11  * This is an initial version of the API that only provides support for relative timers (e.g., expires
12  * in 10 seconds). Absolute timers allow a specific time/date to be used, and will be supported in a
13  * future version of this API.
14  *
15  *
16  * @section timer_objects Creating/Deleting Timer Objects
17  *
18  * Timers are created using le_timer_Create(). The timer name is used for diagnostic purposes only.
19  *
20  * The following attributes of the timer can be set:
21  * - le_timer_SetHandler()
22  * - le_timer_SetInterval() (or le_timer_SetMsInterval())
23  * - le_timer_SetRepeat()
24  * - le_timer_SetContextPtr()
25  *
26  * The following attributes of the timer can be retrieved:
27  * - le_timer_GetInterval() (or le_timer_GetMsInterval())
28  * - le_timer_GetContextPtr()
29  *
30  * The repeat count defaults to 1, so that the timer is initially a one-shot timer. All the other
31  * attributes must be explicitly set. At a minimum, the interval must be set before the timer can be
32  * used. Note that these attributes can only be set if the timer is not currently running; otherwise,
33  * an error will be returned.
34  *
35  * Timers must be explicitly deleted using le_timer_Delete(). If the timer is currently running,
36  * it'll be stopped before being deleted. If a timer uses le_timer_SetContextPtr(), and the
37  * context pointer is allocated memory, then the context pointer must be freed when deleting the timer.
38  * The following function can be used for this:
39  * @code
40  * static void DeleteTimerAndFreePtr(le_timer_Ref_t t)
41  * {
42  * le_timer_Stop( t );
43  * free( le_timer_GetContextPtr( t ) );
44  * le_timer_Delete( t ); // timer ref is now invalid
45  * }
46  * @endcode
47  * You can call this function anywhere, including in the timer handler.
48  *
49  * @section timer_usage Using Timers
50  *
51  * A timer is started using le_timer_Start(). If it's already running, then it won't be
52  * modified; instead an error will be returned. To restart a currently running timer, use
53  * le_timer_Restart().
54  *
55  * A timer is stopped using le_timer_Stop(). If it's not currently running, an error
56  * will be returned, and nothing more will be done.
57  *
58  * To determine if the timer is currently running, use le_timer_IsRunning().
59  *
60  * To find out how much time is remaining before the next expiry, call either
61  * le_timer_GetTimeRemaining() or le_timer_GetMsTimeRemaining().
62  *
63  * When a timer expires, if the timer expiry handler is set by le_timer_SetHandler(), the
64  * handler will be called with a reference to the expired timer. If additional data is required in the
65  * handler, le_timer_SetContextPtr() can be used to set the appropriate context before starting the
66  * timer, and le_timer_GetContextPtr() can be used to retrieve the context while in the handler.
67  * In addition, a suspended system will also wake up by default if the timer expires. If this behaviour
68  * is not desired, user can disable the wake up by passing false into le_timer_SetWakeup().
69  *
70  * The number of times that a timer has expired can be retrieved by le_timer_GetExpiryCount(). This
71  * count is independent of whether there is an expiry handler for the timer.
72  *
73  * @section le_timer_thread Thread Support
74  *
75  * A timer should only be used by the thread that created it. It's not safe for a thread to use
76  * or manipulate a timer that belongs to another thread. The timer expiry handler is called by the
77  * event loop of the thread that starts the timer.
78  *
79  * The call to the timer expiry handler may not occur immediately after the timer expires, depending
80  * on which other functions are called from the event loop. The amount of delay is entirely
81  * dependent on other work done in the event loop. For a repeating timer, if this delay is longer
82  * than the timer period, one or more timer expiries may be dropped. To reduce the likelihood of
83  * dropped expiries, the combined execution time of all handlers called from the event loop should
84  * ideally be less than the timer period.
85  *
86  * See @ref c_eventLoop for details on running the event loop of a thread.
87  *
88  * @section le_timer_suspend Suspend Support
89  *
90  * The timer runs even when system is suspended. <br>
91  * If the timer expires while the system is suspended, it will wake up the system.
92  *
93  * @section timer_errors Fatal Errors
94  *
95  * The process will exit under any of the following conditions:
96  * - If an invalid timer object is given to:
97  * - le_timer_Delete()
98  * - le_timer_SetHandler()
99  * - le_timer_SetInterval()
100  * - le_timer_GetInterval()
101  * - le_timer_SetMsInterval()
102  * - le_timer_GetMsInterval()
103  * - le_timer_SetRepeat()
104  * - le_timer_Start()
105  * - le_timer_Stop()
106  * - le_timer_Restart()
107  * - le_timer_SetContextPtr()
108  * - le_timer_GetContextPtr()
109  * - le_timer_GetExpiryCount()
110  * - le_timer_GetTimeRemaining()
111  * - le_timer_GetMsTimeRemaining()
112  * - le_timer_SetWakeup()
113  *
114  * @section timer_troubleshooting Troubleshooting
115  *
116  * Timers can be traced by enabling the log trace keyword "timers" in the "framework" component.
117  *
118  * See @ref c_log_controlling for more information.
119  *
120  * <HR>
121  *
122  * Copyright (C) Sierra Wireless Inc.
123  *
124  */
125 
126 //--------------------------------------------------------------------------------------------------
127 /**
128  * @file le_timer.h
129  *
130  * Legato @ref c_timer include file.
131  *
132  * Copyright (C) Sierra Wireless Inc.
133  *
134  */
135 //--------------------------------------------------------------------------------------------------
136 
137 #ifndef LEGATO_TIMER_INCLUDE_GUARD
138 #define LEGATO_TIMER_INCLUDE_GUARD
139 
140 
141 //--------------------------------------------------------------------------------------------------
142 /**
143  * Timer object. Created by le_timer_Create().
144  */
145 //--------------------------------------------------------------------------------------------------
146 typedef struct le_timer* le_timer_Ref_t;
147 
148 
149 //--------------------------------------------------------------------------------------------------
150 /**
151  * Prototype for timer expiry handler function.
152  *
153  * @param
154  * timerRef Timer that has expired
155  */
156 //--------------------------------------------------------------------------------------------------
157 typedef void (*le_timer_ExpiryHandler_t)
158 (
159  le_timer_Ref_t timerRef
160 );
161 
162 
163 #if LE_CONFIG_TIMER_NAMES_ENABLED
164 //--------------------------------------------------------------------------------------------------
165 /**
166  * Create the timer object.
167  *
168  * @param[in] nameStr Name of the timer.
169  *
170  * @return
171  * A reference to the timer object.
172  */
173 //--------------------------------------------------------------------------------------------------
175 (
176  const char *nameStr
177 );
178 #else /* if not LE_CONFIG_TIMER_NAMES_ENABLED */
179 /// @cond HIDDEN_IN_USER_DOCS
180 //--------------------------------------------------------------------------------------------------
181 /**
182  * Internal function used to implement le_timer_Create().
183  */
184 //--------------------------------------------------------------------------------------------------
185 le_timer_Ref_t _le_timer_Create(void);
186 /// @endcond
187 //--------------------------------------------------------------------------------------------------
188 /**
189  * Create the timer object.
190  *
191  * @param[in] nameStr Name of the timer.
192  *
193  * @return
194  * A reference to the timer object.
195  */
196 //--------------------------------------------------------------------------------------------------
198 (
199  const char *nameStr
200 )
201 {
202  LE_UNUSED(nameStr);
203  return _le_timer_Create();
204 }
205 #endif /* end LE_CONFIG_TIMER_NAMES_ENABLED */
206 
207 
208 //--------------------------------------------------------------------------------------------------
209 /**
210  * Delete the timer object.
211  *
212  * @note
213  * If an invalid timer object is given, the process exits.
214  */
215 //--------------------------------------------------------------------------------------------------
216 void le_timer_Delete
217 (
218  le_timer_Ref_t timerRef ///< [IN] Delete this timer object
219 );
220 
221 
222 //--------------------------------------------------------------------------------------------------
223 /**
224  * Set the timer expiry handler function.
225  *
226  * If the handler is NULL, then the previous handler will be removed.
227  *
228  * @return
229  * - LE_OK on success
230  * - LE_BUSY if the timer is currently running
231  *
232  * @note
233  * If an invalid timer object is given, the process exits.
234  */
235 //--------------------------------------------------------------------------------------------------
237 (
238  le_timer_Ref_t timerRef, ///< [IN] Set expiry handler for this timer object.
239  le_timer_ExpiryHandler_t handlerFunc ///< [IN] Handler function to call on expiry.
240 );
241 
242 
243 //--------------------------------------------------------------------------------------------------
244 /**
245  * Set the timer interval.
246  *
247  * Timer will expire after the interval has elapsed since it was last started or restarted.
248  *
249  * If the timer is running when the interval is changed and the new interval is shorter than the
250  * period of time since the timer last (re)started, the timer will expire immediately.
251  *
252  * @return
253  * - LE_OK on success
254  *
255  * @note
256  * If an invalid timer object is given, the process exits.
257  */
258 //--------------------------------------------------------------------------------------------------
260 (
261  le_timer_Ref_t timerRef, ///< [IN] Set interval for this timer object.
262  le_clk_Time_t interval ///< [IN] Timer interval.
263 );
264 
265 
266 //--------------------------------------------------------------------------------------------------
267 /**
268  * Get the timer interval.
269  *
270  * @return
271  * The timer interval. If it hasn't been set yet, {0, 0} will be returned.
272  *
273  * @note
274  * If an invalid timer object is given, the process exits.
275  */
276 //--------------------------------------------------------------------------------------------------
278 (
279  le_timer_Ref_t timerRef ///< [IN] Timer object.
280 );
281 
282 
283 //--------------------------------------------------------------------------------------------------
284 /**
285  * Set the timer interval using milliseconds.
286  *
287  * Timer will expire after the interval has elapsed since it was last started or restarted.
288  *
289  * If the timer is running when the interval is changed and the new interval is shorter than the
290  * period of time since the timer last (re)started, the timer will expire immediately.
291  *
292  * @return
293  * - LE_OK on success
294  *
295  * @note
296  * If an invalid timer object is given, the process exits.
297  */
298 //--------------------------------------------------------------------------------------------------
300 (
301  le_timer_Ref_t timerRef, ///< [IN] Set interval for this timer object.
302  uint32_t interval ///< [IN] Timer interval in milliseconds.
303 );
304 
305 
306 //--------------------------------------------------------------------------------------------------
307 /**
308  * Get the timer interval in milliseconds.
309  *
310  * @return
311  * The timer interval (ms). If it hasn't been set yet, 0 will be returned.
312  *
313  * @note
314  * If an invalid timer object is given, the process exits.
315  */
316 //--------------------------------------------------------------------------------------------------
317 uint32_t le_timer_GetMsInterval
318 (
319  le_timer_Ref_t timerRef ///< [IN] Timer object.
320 );
321 
322 
323 //--------------------------------------------------------------------------------------------------
324 /**
325  * Set how many times the timer will repeat.
326  *
327  * Timer will repeat the given number of times. A value of 0 means repeat indefinitely.
328  * The default is 1, so that a one-shot timer is the default.
329  *
330  * @return
331  * - LE_OK on success
332  * - LE_BUSY if the timer is currently running
333  *
334  * @note
335  * If an invalid timer object is given, the process exits.
336  */
337 //--------------------------------------------------------------------------------------------------
339 (
340  le_timer_Ref_t timerRef, ///< [IN] Set repeat count for this timer object
341  uint32_t repeatCount ///< [IN] Number of times the timer will repeat (0 = forever).
342 );
343 
344 
345 //--------------------------------------------------------------------------------------------------
346 /**
347  * Configure if timer expiry will wake up a suspended system.
348  *
349  * @return
350  * - LE_OK on success
351  * - LE_BUSY if the timer is currently running
352  *
353  * @note
354  * The default timer expiry behaviour will wake up the system.
355  * If an invalid timer object is given, the process exits.
356  */
357 //--------------------------------------------------------------------------------------------------
359 (
360  le_timer_Ref_t timerRef, ///< [IN] Disable system wake up for this timer object
361  bool wakeupEnabled ///< [IN] Flag to determine timer will wakeup or not
362 );
363 
364 
365 //--------------------------------------------------------------------------------------------------
366 /**
367  * Set context pointer for the timer.
368  *
369  * This can be used to pass data to the timer when it expires.
370  *
371  * @return
372  * - LE_OK on success
373  * - LE_BUSY if the timer is currently running
374  *
375  * @note
376  * If an invalid timer object is given, the process exits.
377  */
378 //--------------------------------------------------------------------------------------------------
380 (
381  le_timer_Ref_t timerRef, ///< [IN] Set context pointer for this timer object
382  void* contextPtr ///< [IN] Context Pointer.
383 );
384 
385 
386 //--------------------------------------------------------------------------------------------------
387 /**
388  * Get context pointer for the timer.
389  *
390  * This can be used when the timer expires to retrieve data that was previously set.
391  *
392  * @return
393  * Context pointer, which could be NULL if it was not set.
394  *
395  * @note
396  * If an invalid timer object is given, the process exits.
397  */
398 //--------------------------------------------------------------------------------------------------
400 (
401  le_timer_Ref_t timerRef ///< [IN] Get context pointer for this timer object
402 );
403 
404 
405 //--------------------------------------------------------------------------------------------------
406 /**
407  * Get the expiry count of a timer.
408  *
409  * The count is returned for currently running and idle timers. The expiry count
410  * is reset every time the timer is (re)started.
411  *
412  * @return
413  * Expiry count, or zero if the timer has never expired.
414  *
415  * @note
416  * If an invalid timer object is given, the process exits.
417  */
418 //--------------------------------------------------------------------------------------------------
420 (
421  le_timer_Ref_t timerRef ///< [IN] Get expiry count for this timer object
422 );
423 
424 
425 //--------------------------------------------------------------------------------------------------
426 /**
427  * Get the time remaining until the next scheduled expiry.
428  *
429  * @return
430  * Time remaining.
431  * {0, 0} if the timer is stopped or if it has reached its expiry time.
432  *
433  * @note
434  * If an invalid timer object is given, the process exits.
435  */
436 //--------------------------------------------------------------------------------------------------
438 (
439  le_timer_Ref_t timerRef ///< [IN] Get expiry count for this timer object
440 );
441 
442 
443 //--------------------------------------------------------------------------------------------------
444 /**
445  * Get the time remaining (in milliseconds) until the next scheduled expiry.
446  *
447  * @return
448  * Time remaining (in milliseconds).
449  * 0 if the timer is stopped or if it has reached its expiry time.
450  *
451  * @note
452  * If an invalid timer object is given, the process exits.
453  */
454 //--------------------------------------------------------------------------------------------------
456 (
457  le_timer_Ref_t timerRef ///< [IN] Get expiry count for this timer object
458 );
459 
460 
461 //--------------------------------------------------------------------------------------------------
462 /**
463  * Start the timer.
464  *
465  * Start the given timer. The timer must not be currently running.
466  *
467  * @return
468  * - LE_OK on success
469  * - LE_BUSY if the timer is already running
470  *
471  * @note
472  * If an invalid timer object is given, the process exits.
473  */
474 //--------------------------------------------------------------------------------------------------
476 (
477  le_timer_Ref_t timerRef ///< [IN] Start this timer object.
478 );
479 
480 
481 //--------------------------------------------------------------------------------------------------
482 /**
483  * Stop the timer.
484  *
485  * Stop the given timer. The timer must be running.
486  *
487  * @return
488  * - LE_OK on success
489  * - LE_FAULT if the timer is not currently running
490  *
491  * @note
492  * If an invalid timer object is given, the process exits.
493  */
494 //--------------------------------------------------------------------------------------------------
496 (
497  le_timer_Ref_t timerRef ///< [IN] Stop this timer object.
498 );
499 
500 
501 //--------------------------------------------------------------------------------------------------
502 /**
503  * Re-start the timer.
504  *
505  * Start the given timer. If the timer is currently running, it will be stopped and then started.
506  * If the timer is not currently running, it will be started.
507  *
508  * @note
509  * If an invalid timer object is given, the process exits.
510  */
511 //--------------------------------------------------------------------------------------------------
512 void le_timer_Restart
513 (
514  le_timer_Ref_t timerRef ///< [IN] (Re)start this timer object.
515 );
516 
517 
518 //--------------------------------------------------------------------------------------------------
519 /**
520  * Is the timer currently running?
521  *
522  * @note
523  * If an invalid timer object is given, the process exits.
524  */
525 //--------------------------------------------------------------------------------------------------
527 (
528  le_timer_Ref_t timerRef ///< [IN] Is this timer object currently running?
529 );
530 
531 
532 #endif // LEGATO_TIMER_INCLUDE_GUARD
533 
le_result_t le_timer_SetRepeat(le_timer_Ref_t timerRef, uint32_t repeatCount)
le_result_t le_timer_SetWakeup(le_timer_Ref_t timerRef, bool wakeupEnabled)
le_result_t
Definition: le_basics.h:46
#define LE_UNUSED(v)
Definition: le_basics.h:382
Definition: le_clock.h:98
le_result_t le_timer_Start(le_timer_Ref_t timerRef)
void le_timer_Delete(le_timer_Ref_t timerRef)
le_timer_Ref_t le_timer_Create(const char *nameStr)
struct le_timer * le_timer_Ref_t
Definition: le_timer.h:146
le_result_t le_timer_SetMsInterval(le_timer_Ref_t timerRef, uint32_t interval)
uint32_t le_timer_GetMsTimeRemaining(le_timer_Ref_t timerRef)
le_clk_Time_t le_timer_GetTimeRemaining(le_timer_Ref_t timerRef)
le_clk_Time_t le_timer_GetInterval(le_timer_Ref_t timerRef)
void * le_timer_GetContextPtr(le_timer_Ref_t timerRef)
le_result_t le_timer_SetInterval(le_timer_Ref_t timerRef, le_clk_Time_t interval)
le_result_t le_timer_SetHandler(le_timer_Ref_t timerRef, le_timer_ExpiryHandler_t handlerFunc)
le_result_t le_timer_Stop(le_timer_Ref_t timerRef)
bool le_timer_IsRunning(le_timer_Ref_t timerRef)
void le_timer_Restart(le_timer_Ref_t timerRef)
uint32_t le_timer_GetMsInterval(le_timer_Ref_t timerRef)
le_result_t le_timer_SetContextPtr(le_timer_Ref_t timerRef, void *contextPtr)
uint32_t le_timer_GetExpiryCount(le_timer_Ref_t timerRef)
void(* le_timer_ExpiryHandler_t)(le_timer_Ref_t timerRef)
Definition: le_timer.h:158
#define LE_DECLARE_INLINE
Definition: le_basics.h:333