Mistake on this page?
Report an issue in GitHub or email us
mbed_os_timer.h
1 /*
2  * Copyright (c) 2006-2019, ARM Limited, All Rights Reserved
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License"); you may
6  * 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, WITHOUT
13  * 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_MBED_SLEEP_TIMER_H
18 #define MBED_MBED_SLEEP_TIMER_H
19 
20 #include <chrono>
21 #include "platform/internal/SysTimer.h"
22 
23 #if MBED_CONF_RTOS_PRESENT
24 extern "C" {
25 #include "rtx_lib.h"
26 }
27 #endif
28 
29 namespace mbed {
30 namespace internal {
31 
32 #if MBED_CONF_RTOS_PRESENT
33 using OsTimer = SysTimer<std::ratio<1, OS_TICK_FREQ>>;
34 #else
35 using OsTimer = SysTimer<std::milli>;
36 #endif
37 
38 /* A SysTimer is used to provide the timed sleep - this provides access to share it for
39  * other use, such as ticks. If accessed this way, it must not be in use when a sleep function below is called.
40  */
41 extern OsTimer *os_timer;
42 OsTimer *init_os_timer();
43 
44 /** A C++11 chrono TrivialClock for os_timer
45  *
46  * Due to the nature of OsTimer/SysTimer, this does not have a single `now` method, but has
47  * multiple ways to report the current state:
48  *
49  * High-res timeline -------------------------------------------------------------
50  * Ticks | a | b | b | b | c | c | c | c | c | d ^
51  * ^ ^ ^ os_timer->get_time()
52  * acknowledged_ticks() reported_ticks() now()
53  *
54  * (a) is time read from hardware by OsTimer, reported to the user of OsTimer, and acknowledged by that user.
55  * (b) is time read from hardware by OsTimer, reported to the user of OsTimer, but not yet acknowledged.
56  * (c) is time already elapsed in the hardware but yet to be read and processed as ticks by OsTimer.
57  * (d) is time already elapsed in the hardware that doesn't yet form a tick.
58  *
59  * Time is "reported" either by:
60  * * calls to the OsTimer's handler following start_tick - these must be acknowledged
61  * * the result of OsTimer::update_and_get_tick() / OsClock::now() - calling this implies acknowledgment.
62  *
63  * As such `now()` is used when the ticker is not in use - it processes ticks that would have been
64  * processed by the tick handler. If the ticker is in uses `reported_ticks` or `acknowleged_ticks` must be used.
65  *
66  * @note To fit better into the chrono framework, OsClock uses
67  * chrono::milliseconds as its representation, which makes it signed
68  * and at least 45 bits, so it will be int64_t or equivalent, unlike
69  * OsTimer which uses uint64_t rep.
70  */
71 struct OsClock {
72  /* Standard TrivialClock fields */
73  using period = OsTimer::period;
74  using rep = std::chrono::milliseconds::rep;
75  using duration = std::chrono::duration<rep, period>; // == std::chrono::milliseconds, if period is std::milli
76  using time_point = std::chrono::time_point<OsClock, duration>;
77  static constexpr bool is_steady = true;
78  // Read the hardware, and return the updated time_point.
79  // Initialize the timing system if necessary - this could be the first call.
80  // See SysTimer::update_and_get_tick for more details.
81  static time_point now()
82  {
83  // We are a real Clock with a well-defined epoch. As such we distinguish ourselves
84  // from the less-well-defined SysTimer pseudo-Clock. This means our time_points
85  // are not convertible, so need to fiddle here.
86  return time_point(init_os_timer()->update_and_get_tick().time_since_epoch());
87  }
88  // Return the current reported tick count, without update.
89  // Assumes timer has already been initialized, as ticker should have been in use to
90  // keep that tick count up-to-date. See SysTimer::get_tick for more details.
91  static time_point reported_ticks()
92  {
93  return time_point(os_timer->get_tick().time_since_epoch());
94  }
95  // Return the acknowledged tick count.
96  static time_point acknowledged_ticks()
97  {
98  return reported_ticks() - os_timer->unacknowledged_ticks();
99  }
100  // Slightly-optimised variant of OsClock::now() that assumes os_timer is initialised.
101  static time_point now_with_init_done()
102  {
103  return time_point(os_timer->update_and_get_tick().time_since_epoch());
104  }
105  static void set_wake_time(time_point wake_time)
106  {
107  return os_timer->set_wake_time(OsTimer::time_point(wake_time.time_since_epoch()));
108  }
109  /* Extension to
110  * make it easy to use 32-bit durations for some APIs, as we historically do */
111  using duration_u32 = std::chrono::duration<uint32_t, period>;
112 };
113 
114 /* time_point::max() is effectively "sleep forever" */
115 OsClock::time_point do_timed_sleep_absolute(OsClock::time_point wake_time, bool (*wake_predicate)(void *) = NULL, void *wake_predicate_handle = NULL);
116 
117 #if MBED_CONF_RTOS_PRESENT
118 /* Maximum sleep time is 2^32-1 ticks; timer is always set to achieve this */
119 /* Assumes that ticker has been in use prior to call, so restricted to RTOS use */
120 OsClock::duration_u32 do_timed_sleep_relative_to_acknowledged_ticks(OsClock::duration_u32 wake_delay, bool (*wake_predicate)(void *) = NULL, void *wake_predicate_handle = NULL);
121 #else
122 
123 void do_untimed_sleep(bool (*wake_predicate)(void *), void *wake_predicate_handle = NULL);
124 
125 /* duration_u32::max() delay is sleep forever */
126 
127 void do_timed_sleep_relative_or_forever(OsClock::duration_u32 wake_delay, bool (*wake_predicate)(void *) = NULL, void *wake_predicate_handle = NULL);
128 
129 #endif
130 
131 }
132 }
133 
134 #endif
A C++11 chrono TrivialClock for os_timer.
Definition: mbed_os_timer.h:71
Definition: ATHandler.h:46
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.