|
24 | 24 | //! by non-constant values). Similarly, the `fugit` crate offers constructors that aim to result
|
25 | 25 | //! in constants when possible, avoiding costly division operations.
|
26 | 26 |
|
27 |
| -use zephyr_sys::k_timeout_t; |
| 27 | +use zephyr_sys::{k_timeout_t, k_ticks_t}; |
| 28 | + |
| 29 | +use core::fmt::Debug; |
28 | 30 |
|
29 | 31 | // The system ticks, is mostly a constant, but there are some boards that use a dynamic tick
|
30 | 32 | // frequency, and thus need to read this at runtime.
|
@@ -70,14 +72,20 @@ pub struct Timeout(pub k_timeout_t);
|
70 | 72 | // From allows methods to take a time of various types and convert it into a Zephyr timeout.
|
71 | 73 | impl From<Duration> for Timeout {
|
72 | 74 | fn from(value: Duration) -> Timeout {
|
73 |
| - Timeout(k_timeout_t { ticks: value.ticks() as i64 }) |
| 75 | + let ticks: k_ticks_t = checked_cast(value.ticks()); |
| 76 | + debug_assert_ne!(ticks, crate::sys::K_FOREVER.ticks); |
| 77 | + debug_assert_ne!(ticks, crate::sys::K_NO_WAIT.ticks); |
| 78 | + Timeout(k_timeout_t { ticks }) |
74 | 79 | }
|
75 | 80 | }
|
76 | 81 |
|
77 | 82 | #[cfg(CONFIG_TIMEOUT_64BIT)]
|
78 | 83 | impl From<Instant> for Timeout {
|
79 | 84 | fn from(value: Instant) -> Timeout {
|
80 |
| - Timeout(k_timeout_t { ticks: -1 - 1 - (value.ticks() as i64) }) |
| 85 | + let ticks: k_ticks_t = checked_cast(value.ticks()); |
| 86 | + debug_assert_ne!(ticks, crate::sys::K_FOREVER.ticks); |
| 87 | + debug_assert_ne!(ticks, crate::sys::K_NO_WAIT.ticks); |
| 88 | + Timeout(k_timeout_t { ticks: -1 - 1 - ticks }) |
81 | 89 | }
|
82 | 90 | }
|
83 | 91 |
|
@@ -110,3 +118,18 @@ pub fn sleep<T>(timeout: T) -> Duration
|
110 | 118 | let rest = unsafe { crate::raw::k_sleep(timeout.0) };
|
111 | 119 | Duration::millis(rest as Tick)
|
112 | 120 | }
|
| 121 | + |
| 122 | +/// Convert from the Tick time type, which is unsigned, to the `k_ticks_t` type. When debug |
| 123 | +/// assertions are enabled, it will panic on overflow. |
| 124 | +fn checked_cast<I, O>(tick: I) -> O |
| 125 | +where |
| 126 | + I: TryInto<O>, |
| 127 | + I::Error: Debug, |
| 128 | + O: Default, |
| 129 | +{ |
| 130 | + if cfg!(debug_assertions) { |
| 131 | + tick.try_into().expect("Overflow in time conversion") |
| 132 | + } else { |
| 133 | + tick.try_into().unwrap_or(O::default()) |
| 134 | + } |
| 135 | +} |
0 commit comments