Mistake on this page?
Report an issue in GitHub or email us
TickerDataClock.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_TICKERDATACLOCK_H
18 #define MBED_TICKERDATACLOCK_H
19 
20 #include <chrono>
21 #include "hal/ticker_api.h"
22 
23 namespace mbed {
24 /**
25  * \defgroup drivers_TickerDataClock TickerDataClock class
26  * \ingroup drivers-public-api-ticker
27  * @{
28  */
29 
30 /**
31  * A partial implementation of a C++11 Clock representing a HAL ticker.
32  *
33  * This class allows us to create chrono time_points for objects like Timer,
34  * with the limitation that the tickers are not singletons. This means:
35  *
36  * * the now() function is not static - this will limit
37  * use with some algorithms,
38  * * there is no distinction between time_points for different
39  * tickers
40  *
41  * This "pseudo-Clock" approach has been endorsed by Howard Hinnant
42  * (designer of Chrono) here:
43  * https://stackoverflow.com/questions/56400313/why-does-the-c-standard-require-the-clocknow-function-to-be-static
44  *
45  * TickerDataClock::time_point values should only be used with mbed APIs specifically taking
46  * them, not passed to generic templated chrono algorithms, and it is up to the user to use them
47  * in conjunction with the correct TickerDataClock.
48  *
49  * operators for `->` and conversion to `ticker_data_t *` are provided allowing
50  * TickerDataClock to be easily substituted in place of a `ticker_data_t *`.
51  */
53 public:
54  /** Construct a TickerDataClock referring to a ticker_data_t */
55  constexpr TickerDataClock(const ticker_data_t *ticker) : _ticker(ticker)
56  {
57  }
58 
59  /* duration is C++11 standard microseconds, so representation will be 64-bit signed integer */
60  using duration = std::chrono::microseconds;
61  using rep = duration::rep;
62  using period = duration::period;
63  using time_point = std::chrono::time_point<TickerDataClock>;
64  static const bool is_steady = false;
65 
66  /** Initialize a ticker and set the event handler
67  *
68  * @param handler A handler to be set
69  */
70  void set_handler(ticker_event_handler handler)
71  {
72  return ticker_set_handler(_ticker, handler);
73  }
74 
75  /** Remove an event from the queue
76  *
77  * @param obj The event object to be removed from the queue
78  */
80  {
81  ticker_remove_event(_ticker, obj);
82  }
83 
84  /** Insert an event to the queue
85  *
86  * The event will be executed in timestamp - ticker_read_us() us.
87  *
88  * @note If an event is inserted with a timestamp less than the current
89  * timestamp then the event will be scheduled immediately resulting in
90  * an instant call to event handler.
91  *
92  * @param obj The event object to be inserted to the queue
93  * @param timestamp The event's timestamp
94  * @param id The event object
95  */
96  void insert_event(ticker_event_t *obj, time_point timestamp, uint32_t id)
97  {
98  ticker_insert_event_us(_ticker, obj, timestamp.time_since_epoch().count(), id);
99  }
100 
101  /** Read the current (absolute) ticker's timestamp
102  *
103  * @warning Return an absolute timestamp counting from the initialization of the
104  * ticker.
105  *
106  * @return The current timestamp
107  */
108  time_point now() const
109  {
110  return time_point(duration(ticker_read_us(_ticker)));
111  }
112 
113  /** Read the next event's timestamp
114  *
115  * @param timestamp The timestamp object.
116  * @return 1 if timestamp is pending event, 0 if there's no event pending
117  */
118  int get_next_timestamp(time_point *timestamp) const
119  {
120  us_timestamp_t t;
121  int ret = ticker_get_next_timestamp_us(_ticker, &t);
122  *timestamp = time_point(duration(t));
123  return ret;
124  }
125 
126  /** Suspend this ticker
127  *
128  * When suspended reads will always return the same time and no
129  * events will be dispatched. When suspended the common layer
130  * will only ever call the interface function clear_interrupt()
131  * and that is only if ticker_irq_handler is called.
132  *
133  */
134  void suspend()
135  {
136  ticker_suspend(_ticker);
137  }
138 
139  /** Resume this ticker
140  *
141  * When resumed the ticker will ignore any time that has passed
142  * and continue counting up where it left off.
143  */
144  void resume()
145  {
146  ticker_resume(_ticker);
147  }
148 
149  constexpr const ticker_data_t *operator->() const
150  {
151  return _ticker;
152  }
153  constexpr operator const ticker_data_t *() const
154  {
155  return _ticker;
156  }
157 
158 private:
159  const ticker_data_t *const _ticker;
160 };
161 
162 inline TickerDataClock::time_point get_time_point(const ticker_event_t &event)
163 {
164  return TickerDataClock::time_point{TickerDataClock::duration{event.timestamp}};
165 }
166 
167 /** @}*/
168 
169 }
170 #endif /* MBED_TICKERDATACLOCK_H */
void ticker_insert_event_us(const ticker_data_t *const ticker, ticker_event_t *obj, us_timestamp_t timestamp, uint32_t id)
Insert an event to the queue.
void ticker_resume(const ticker_data_t *const ticker)
Resume this ticker.
int ticker_get_next_timestamp_us(const ticker_data_t *const ticker, us_timestamp_t *timestamp)
Read the next event&#39;s timestamp.
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:144
constexpr TickerDataClock(const ticker_data_t *ticker)
Construct a TickerDataClock referring to a ticker_data_t.
A partial implementation of a C++11 Clock representing a HAL ticker.
time_point now() const
Read the current (absolute) ticker&#39;s timestamp.
void remove_event(ticker_event_t *obj)
Remove an event from the queue.
Ticker&#39;s event structure.
Definition: ticker_api.h:43
void set_handler(ticker_event_handler handler)
Initialize a ticker and set the event handler.
us_timestamp_t ticker_read_us(const ticker_data_t *const ticker)
Read the current (absolute) ticker&#39;s timestamp.
void insert_event(ticker_event_t *obj, time_point timestamp, uint32_t id)
Insert an event to the queue.
void ticker_remove_event(const ticker_data_t *const ticker, ticker_event_t *obj)
Remove an event from the queue.
void ticker_suspend(const ticker_data_t *const ticker)
Suspend this ticker.
void resume()
Resume this ticker.
void suspend()
Suspend this ticker.
Definition: ATHandler.h:46
int get_next_timestamp(time_point *timestamp) const
Read the next event&#39;s timestamp.
void ticker_set_handler(const ticker_data_t *const ticker, ticker_event_handler handler)
Initialize a ticker and set the event handler.
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.