freertos_rs/
delays.rs

1use crate::base::*;
2use crate::task::*;
3use crate::shim::*;
4use crate::units::*;
5
6/// Delay the current task by the given duration, minus the
7/// time that was spent processing the last wakeup loop.
8pub struct TaskDelay {
9    last_wake_time: FreeRtosTickType,
10}
11
12impl TaskDelay {
13    /// Create a new helper, marking the current time as the start of the
14    /// next measurement.
15    pub fn new() -> TaskDelay {
16        TaskDelay { last_wake_time: FreeRtosUtils::get_tick_count() }
17    }
18
19    /// Delay the execution of the current task by the given duration,
20    /// minus the time spent in this task since the last delay.
21    pub fn delay_until<D: DurationTicks>(&mut self, delay: D) {
22        unsafe {
23            freertos_rs_vTaskDelayUntil(&mut self.last_wake_time as *mut FreeRtosTickType,
24                                        delay.to_ticks());
25        }
26    }
27}
28
29/// Periodic delay timer.
30///
31/// Use inside a polling loop, for example: the loop polls this instance every second.
32/// The method `should_run` will return true once 30 seconds or more has elapsed
33/// and it will then reset the timer for that period.
34pub struct TaskDelayPeriodic {
35    last_wake_time: FreeRtosTickType,
36    period_ticks: FreeRtosTickType,
37}
38
39impl TaskDelayPeriodic {
40    /// Create a new timer with the set period.
41    pub fn new<D: DurationTicks>(period: D) -> TaskDelayPeriodic {
42        let l = FreeRtosUtils::get_tick_count();
43
44        TaskDelayPeriodic {
45            last_wake_time: l,
46            period_ticks: period.to_ticks(),
47        }
48    }
49
50    /// Has the set period passed? If it has, resets the internal timer.
51    pub fn should_run(&mut self) -> bool {
52        let c = FreeRtosUtils::get_tick_count();
53        if (c - self.last_wake_time) < (self.period_ticks) {
54            false
55        } else {
56            self.last_wake_time = c;
57            true
58        }
59    }
60
61    /// Set a new delay period
62    pub fn set_period<D: DurationTicks>(&mut self, period: D) {
63        self.period_ticks = period.to_ticks();
64    }
65
66    /// Reset the internal timer to zero.
67    pub fn reset(&mut self) {
68        self.last_wake_time = FreeRtosUtils::get_tick_count();
69    }
70}