1.. _timers_v2:
2
3Timers
4######
5
6A :dfn:`timer` is a kernel object that measures the passage of time
7using the kernel's system clock. When a timer's specified time limit
8is reached it can perform an application-defined action,
9or it can simply record the expiration and wait for the application
10to read its status.
11
12.. contents::
13    :local:
14    :depth: 2
15
16Concepts
17********
18
19Any number of timers can be defined (limited only by available RAM). Each timer
20is referenced by its memory address.
21
22A timer has the following key properties:
23
24* A **duration** specifying the time interval before the timer
25  expires for the first time.  This is a :c:type:`k_timeout_t` value that
26  may be initialized via different units.
27
28* A **period** specifying the time interval between all timer
29  expirations after the first one, also a :c:type:`k_timeout_t`. It must be
30  non-negative.  A period of ``K_NO_WAIT`` (i.e. zero) or
31  ``K_FOREVER`` means that the timer is a one-shot timer that stops
32  after a single expiration. (For example then, if a timer is started
33  with a duration of 200 and a period of 75, it will first expire
34  after 200 ms and then every 75 ms after that.)
35
36* An **expiry function** that is executed each time the timer expires.
37  The function is executed by the system clock interrupt handler.
38  If no expiry function is required a ``NULL`` function can be specified.
39
40* A **stop function** that is executed if the timer is stopped prematurely
41  while running. The function is executed by the thread that stops the timer.
42  If no stop function is required a ``NULL`` function can be specified.
43
44* A **status** value that indicates how many times the timer has expired
45  since the status value was last read.
46
47A timer must be initialized before it can be used. This specifies its
48expiry function and stop function values, sets the timer's status to zero,
49and puts the timer into the **stopped** state.
50
51A timer is **started** by specifying a duration and a period.
52The timer's status is reset to zero, and then the timer enters
53the **running** state and begins counting down towards expiry.
54
55Note that the timer's duration and period parameters specify
56**minimum** delays that will elapse.  Because of internal system timer
57precision (and potentially runtime interactions like interrupt delay)
58it is possible that more time may have passed as measured by reads
59from the relevant system time APIs.  But at least this much time is
60guaranteed to have elapsed.
61
62When a running timer expires its status is incremented
63and the timer executes its expiry function, if one exists;
64If a thread is waiting on the timer, it is unblocked.
65If the timer's period is zero the timer enters the stopped state;
66otherwise, the timer restarts with a new duration equal to its period.
67
68A running timer can be stopped in mid-countdown, if desired.
69The timer's status is left unchanged, then the timer enters the stopped state
70and executes its stop function, if one exists.
71If a thread is waiting on the timer, it is unblocked.
72Attempting to stop a non-running timer is permitted,
73but has no effect on the timer since it is already stopped.
74
75A running timer can be restarted in mid-countdown, if desired.
76The timer's status is reset to zero, then the timer begins counting down
77using the new duration and period values specified by the caller.
78If a thread is waiting on the timer, it continues waiting.
79
80A timer's status can be read directly at any time to determine how many times
81the timer has expired since its status was last read.
82Reading a timer's status resets its value to zero.
83The amount of time remaining before the timer expires can also be read;
84a value of zero indicates that the timer is stopped.
85
86A thread may read a timer's status indirectly by **synchronizing**
87with the timer. This blocks the thread until the timer's status is non-zero
88(indicating that it has expired at least once) or the timer is stopped;
89if the timer status is already non-zero or the timer is already stopped
90the thread continues without waiting. The synchronization operation
91returns the timer's status and resets it to zero.
92
93.. note::
94    Only a single user should examine the status of any given timer,
95    since reading the status (directly or indirectly) changes its value.
96    Similarly, only a single thread at a time should synchronize
97    with a given timer. ISRs are not permitted to synchronize with timers,
98    since ISRs are not allowed to block.
99
100Implementation
101**************
102
103Defining a Timer
104================
105
106A timer is defined using a variable of type :c:struct:`k_timer`.
107It must then be initialized by calling :c:func:`k_timer_init`.
108
109The following code defines and initializes a timer.
110
111.. code-block:: c
112
113    struct k_timer my_timer;
114    extern void my_expiry_function(struct k_timer *timer_id);
115
116    k_timer_init(&my_timer, my_expiry_function, NULL);
117
118Alternatively, a timer can be defined and initialized at compile time
119by calling :c:macro:`K_TIMER_DEFINE`.
120
121The following code has the same effect as the code segment above.
122
123.. code-block:: c
124
125    K_TIMER_DEFINE(my_timer, my_expiry_function, NULL);
126
127Using a Timer Expiry Function
128=============================
129
130The following code uses a timer to perform a non-trivial action on a periodic
131basis. Since the required work cannot be done at the interrupt level,
132the timer's expiry function submits a work item to the
133:ref:`system workqueue <workqueues_v2>`, whose thread performs the work.
134
135.. code-block:: c
136
137    void my_work_handler(struct k_work *work)
138    {
139        /* do the processing that needs to be done periodically */
140        ...
141    }
142
143    K_WORK_DEFINE(my_work, my_work_handler);
144
145    void my_timer_handler(struct k_timer *dummy)
146    {
147        k_work_submit(&my_work);
148    }
149
150    K_TIMER_DEFINE(my_timer, my_timer_handler, NULL);
151
152    ...
153
154    /* start a periodic timer that expires once every second */
155    k_timer_start(&my_timer, K_SECONDS(1), K_SECONDS(1));
156
157Reading Timer Status
158====================
159
160The following code reads a timer's status directly to determine
161if the timer has expired or not.
162
163.. code-block:: c
164
165    K_TIMER_DEFINE(my_status_timer, NULL, NULL);
166
167    ...
168
169    /* start a one-shot timer that expires after 200 ms */
170    k_timer_start(&my_status_timer, K_MSEC(200), K_NO_WAIT);
171
172    /* do work */
173    ...
174
175    /* check timer status */
176    if (k_timer_status_get(&my_status_timer) > 0) {
177        /* timer has expired */
178    } else if (k_timer_remaining_get(&my_status_timer) == 0) {
179        /* timer was stopped (by someone else) before expiring */
180    } else {
181        /* timer is still running */
182    }
183
184Using Timer Status Synchronization
185==================================
186
187The following code performs timer status synchronization to allow a thread
188to do useful work while ensuring that a pair of protocol operations
189are separated by the specified time interval.
190
191.. code-block:: c
192
193    K_TIMER_DEFINE(my_sync_timer, NULL, NULL);
194
195    ...
196
197    /* do first protocol operation */
198    ...
199
200    /* start a one-shot timer that expires after 500 ms */
201    k_timer_start(&my_sync_timer, K_MSEC(500), K_NO_WAIT);
202
203    /* do other work */
204    ...
205
206    /* ensure timer has expired (waiting for expiry, if necessary) */
207    k_timer_status_sync(&my_sync_timer);
208
209    /* do second protocol operation */
210    ...
211
212.. note::
213    If the thread had no other work to do it could simply sleep
214    between the two protocol operations, without using a timer.
215
216Suggested Uses
217**************
218
219Use a timer to initiate an asynchronous operation after a specified
220amount of time.
221
222Use a timer to determine whether or not a specified amount of time has
223elapsed.  In particular, timers should be used when higher precision
224and/or unit control is required than that afforded by the simpler
225:c:func:`k_sleep` and :c:func:`k_usleep` calls.
226
227Use a timer to perform other work while carrying out operations
228involving time limits.
229
230.. note::
231   If a thread needs to measure the time required to perform an operation
232   it can read the :ref:`system clock or the hardware clock <kernel_timing>`
233   directly, rather than using a timer.
234
235Configuration Options
236*********************
237
238Related configuration options:
239
240* None
241
242API Reference
243*************
244
245.. doxygengroup:: timer_apis
246