Mistake on this page?
Report an issue in GitHub or email us
SysTimer.h
1 /* mbed Microcontroller Library
2  * Copyright (c) 2006-2019 ARM Limited
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #ifndef MBED_SYS_TIMER_H
18 #define MBED_SYS_TIMER_H
19 
20 #include "platform/NonCopyable.h"
21 #include "platform/mbed_atomic.h"
22 #include "drivers/TimerEvent.h"
23 #include "cmsis.h"
24 
25 extern "C" {
26 #if defined(TARGET_CORTEX_A)
27 #include "irq_ctrl.h"
28 #endif
29 }
30 
31 namespace mbed {
32 namespace internal {
33 
34 /**
35  * \defgroup mbed_SysTimer SysTimer class
36  * \ingroup platform-internal-api
37  * @{
38  */
39 
40 /**
41  * The SysTimer class is used to provide timing for system suspension, and
42  * the idle loop in TICKLESS mode.
43  *
44  * Template for speed for testing - only one instance will be used normally.
45  *
46  * @note SysTimer is not the part of Mbed API.
47  */
48 template <uint32_t US_IN_TICK, bool IRQ = true>
49 class SysTimer: private mbed::TimerEvent, private mbed::NonCopyable<SysTimer<US_IN_TICK, IRQ> > {
50 public:
51 
52  /**
53  * Default constructor uses LPTICKER if available (so the timer will
54  * continue to run in deep sleep), else USTICKER.
55  */
56  SysTimer();
57 
58  SysTimer(const ticker_data_t *data);
59 
60  ~SysTimer();
61 
62  /**
63  * Get the interrupt number for the tick
64  *
65  * @return interrupt number
66  */
67 #if TARGET_CORTEX_A
68  static IRQn_ID_t get_irq_number();
69 #elif TARGET_CORTEX_M
70  static IRQn_Type get_irq_number();
71 #endif
72 
73  /**
74  * Set the wake time
75  *
76  * Schedules an interrupt to cause wake-up in time for the event. Interrupt
77  * may be arranged early to account for latency. If the time has already
78  * passed, no interrupt will be scheduled.
79  *
80  * This is called from outside a critical section, as it is known to be
81  * a slow operation.
82  *
83  * If the wake time is already set, this is a no-op. But that check is racy,
84  * which means wake_time_set() should be rechecked after taking a critical
85  * section.
86  *
87  * As a side-effect, this clears the unacknowledged tick count - the caller
88  * is expected to use update_and_get_tick() after the suspend operation.
89  *
90  * @param at Wake up tick
91  * @warning If the ticker tick is already scheduled it needs to be cancelled first!
92  */
93  void set_wake_time(uint64_t at);
94 
95  /**
96  * Check whether the wake time has passed
97  *
98  * This is a fast operation, based on checking whether the wake interrupt
99  * has run.
100  *
101  * @return true if the specified wake tick has passed
102  */
103  bool wake_time_passed() const
104  {
105  return core_util_atomic_load_bool(&_wake_time_passed);
106  }
107 
108  /**
109  * Check whether wake timer is active
110  *
111  * @return true if the wake timer is active.
112  */
113  bool wake_time_set() const
114  {
115  return core_util_atomic_load_bool(&_wake_time_set);
116  }
117 
118  /**
119  * Cancel any pending wake
120  */
121  void cancel_wake();
122 
123  /**
124  * Schedule an os tick to fire
125  *
126  * Ticks will be rescheduled automatically every tick until cancel_tick is called.
127  *
128  * A tick will be fired immediately if there are any unacknowledged ticks.
129  *
130  * @warning If a tick is already scheduled it needs to be cancelled first!
131  */
132  void start_tick();
133 
134  /**
135  * Acknowledge an os tick
136  *
137  * This will queue another os tick immediately if the os is running slow
138  */
139  void acknowledge_tick();
140 
141  /**
142  * Prevent any more scheduled ticks from triggering
143  *
144  * If called from OS tick context, there may be remaining unacknowledged ticks.
145  */
146  void cancel_tick();
147 
148  /**
149  * Check whether ticker is active
150  *
151  * Each time the tick interrupt fires, it is automatically rescheduled,
152  * so this will remain true once the tick is started, except during
153  * processing.
154  *
155  * @return true if the ticker is active.
156  */
157  bool ticking() const
158  {
159  return core_util_atomic_load_bool(&_ticking);
160  }
161 
162  /**
163  * Check unacknowledged ticks
164  *
165  * Returns the count of how many times the OS timer has been queued minus
166  * the number of times is has been acknowledged.
167  *
168  * get_tick() - unacknowledged_ticks() should equal the OS's tick count,
169  * although such a calculation is not atomic if the ticker is currently running.
170  *
171  * @return number of unacknowledged ticks
172  */
174  {
175  return core_util_atomic_load_u8(&_unacknowledged_ticks);
176  }
177 
178  /** Get the current tick count
179  *
180  * This count is updated by the ticker interrupt, if the ticker interrupt
181  * is running. It the ticker interrupt is not running, update_and_get_tick()
182  * should be used instead.
183  *
184  * This indicates how many ticks have been generated by the tick interrupt.
185  * The os_timer should equal this number minus the number of unacknowledged ticks.
186  *
187  * @return The number of ticks since timer creation.
188  */
189  uint64_t get_tick() const;
190 
191  /** Update and get the current tick count
192  *
193  * This is a slow operation that reads the timer and adjusts for elapsed time.
194  * Can only be used when the ticker is not running, as there is no IRQ
195  * synchronization.
196  *
197  * This clears the unacknowledged tick counter - the caller is assumed to update
198  * their timer based on this return.
199  *
200  * @return The number of ticks since timer creation.
201  */
202  uint64_t update_and_get_tick();
203 
204  /**
205  * Returns time since last tick
206  *
207  * @return Relative time in microseconds
208  */
210 
211  /**
212  * Get the time
213  *
214  * Returns the instantaneous precision time from underlying timer.
215  * This is a slow operation so should not be called from critical sections.
216  *
217  * @return Current time in microseconds
218  */
219  us_timestamp_t get_time() const;
220 
221 protected:
222  virtual void handler();
223  void _increment_tick();
224  void _schedule_tick();
225  uint64_t _elapsed_ticks() const;
226  static void _set_irq_pending();
227  static void _clear_irq_pending();
228  us_timestamp_t _time_us;
229  uint64_t _tick;
230  uint8_t _unacknowledged_ticks;
231  bool _wake_time_set;
232  bool _wake_time_passed;
233  bool _wake_early;
234  bool _ticking;
235  bool _deep_sleep_locked;
236 };
237 
238 /** @} */
239 
240 }
241 }
242 
243 #endif
void cancel_wake()
Cancel any pending wake.
void set_wake_time(uint64_t at)
Get the interrupt number for the tick.
void start_tick()
Schedule an os tick to fire.
uint64_t get_tick() const
Get the current tick count.
us_timestamp_t get_time_since_tick() const
Returns time since last tick.
uint64_t us_timestamp_t
A us timestamp stored in a 64 bit integer.
Definition: ticker_api.h:39
Ticker&#39;s data structure.
Definition: ticker_api.h:93
SysTimer()
Default constructor uses LPTICKER if available (so the timer will continue to run in deep sleep)...
Prevents generation of copy constructor and copy assignment operator in derived classes.
Definition: NonCopyable.h:169
bool wake_time_passed() const
Check whether the wake time has passed.
Definition: SysTimer.h:103
bool wake_time_set() const
Check whether wake timer is active.
Definition: SysTimer.h:113
int unacknowledged_ticks() const
Check unacknowledged ticks.
Definition: SysTimer.h:173
uint64_t update_and_get_tick()
Update and get the current tick count.
MBED_FORCEINLINE uint8_t core_util_atomic_load_u8(const volatile uint8_t *valuePtr)
Atomic load.
The SysTimer class is used to provide timing for system suspension, and the idle loop in TICKLESS mod...
Definition: SysTimer.h:49
Base abstraction for timer interrupts.
Definition: TimerEvent.h:34
MBED_FORCEINLINE bool core_util_atomic_load_bool(const volatile bool *valuePtr)
Atomic load.
void cancel_tick()
Prevent any more scheduled ticks from triggering.
bool ticking() const
Check whether ticker is active.
Definition: SysTimer.h:157
void acknowledge_tick()
Acknowledge an os tick.
us_timestamp_t get_time() const
Get the time.
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.