Module avr_oxide::devices::wallclock

source ·
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();

Structs§