Expand description
A simple RTC device designed to keep wall-clock time. It generates events at a fixed frequency of 1Hz, using the reliable RTC clock generator rather than the MasterClock device’s generic Timers.
§Usage
Create the WallClock device using the with_timer()
method, ensuring you
pass in an AVR RTC device, rather than a generic timer.
The frequency of events is hard-coded at 1Hz (i.e. one per second) - the WallClock is intended to maintain clock time, not for precise or high-frequency measurements.
let wall_clock = StaticWrap::new(OxideWallClock::with_timer(avr_oxide::hardware::timer::rtc::instance()));
// An event handler every time the master clock ticks
wall_clock.borrow().on_tick(Box::new(move |_timerid, _duration|{
// Do something once a second
}));
supervisor.listen(wall_clock.borrow());
supervisor.run();
In addition to generating tick events, the WallClock also maintains a
counter of the time elapsed since the clock was first started. You can
access via the runtime()
method.
§Counter Overflow
The avr_oxide::time::Duration
type stores duration in seconds as a u32,
thus the maximum possible duration is (2^32)-1 seconds, or just over
136 years.
Thus while it is quite unlikely that an AVRoxide application will be
running for over a century it is not entirely impossible - the internal
counter may thus overflow in 136 years’ time. In the event that this
happens, the counter will wrap around to 1, and a flag will be set
indicating that the counter has overflowed (runtime_overflowed()
method
to access.) The application developer may thus detect this occurence
and choose to handle it in application specific ways.
The runtime_overflowed
flag may be cleared using the clear_runtime_overflow()
method, in which case it will be set again in another 136 years.
§Delay Events
The WallClock device can be used to efficiently schedule events which
should be triggered in the future. A closure can be passed to the
after_delay()
method, which will be executed after the given duration
has elapsed. Internally, WallClock uses a Delay Queue implementation,
meaning there is no limit to the number of such events which may be
scheduled (other than memory to allocate the queue elements.)
let wall_clock = StaticWrap::new(OxideWallClock::with_timer(avr_oxide::hardware::timer::rtc::instance()));
wall_clock.borrow().after_delay(Duration::from_secs(60), Box::new(move |_timerid|{
// Do something after a minute
}));
wall_clock.borrow().after_delay(Duration::from_secs(3600), Box::new(move |_timerid|{
// Do something in an hour
}));
supervisor.listen(wall_clock.borrow());
supervisor.run();
§Blocking API
A blocking wait()
API is also provided, which will block the calling
thread for the given duration. Note that the clock must be running -
i.e. the supervisor.listen_handle()
method was called already - before
you use the wait()
method, or you can expect to block forever, and that
this method depends on the main supervisor to be running. In other words,
this must be used in threads you have spawn()
ed, not the main thread.
let master_clock = StaticWrap::new(OxideWallClock::with_timer(avr_oxide::hardware::timer::rtc::instance()));
supervisor.listen(master_clock.borrow());
{
let master_clock = master_clock.borrow();
avr_oxide::thread::spawn(move||{
master_clock.wait(Duration::from_millis(3000));
0
});
}
supervisor.run();