Skip to main content

TimerFn

Trait TimerFn 

Source
pub trait TimerFn {
    // Required methods
    fn start(&self, ticks_to_wait: TickType) -> OsalRsBool;
    fn stop(&self, ticks_to_wait: TickType) -> OsalRsBool;
    fn reset(&self, ticks_to_wait: TickType) -> OsalRsBool;
    fn change_period(
        &self,
        new_period_in_ticks: TickType,
        ticks_to_wait: TickType,
    ) -> OsalRsBool;
    fn delete(&mut self, ticks_to_wait: TickType) -> OsalRsBool;
}
Expand description

Software timer for delayed and periodic callbacks.

Timers run callbacks in the timer service task context, not ISR context. They can be one-shot or auto-reloading (periodic).

§Timer Lifecycle

  1. Creation: Timer::new() with name, period, auto-reload flag, and callback
  2. Start: start() begins the timer countdown
  3. Expiration: Callback executes when period elapses
  4. Auto-reload: If enabled, timer automatically restarts
  5. Management: Use stop(), reset(), change_period() to control
  6. Cleanup: delete() frees resources

§Command Queue

Timer operations (start, stop, etc.) send commands to a queue processed by the timer service task. The ticks_to_wait parameter controls how long to wait if the queue is full.

§Callback Constraints

  • Keep callbacks short (< 1ms ideally)
  • Avoid blocking operations (delays, mutex waits, etc.)
  • Don’t call APIs that might block indefinitely
  • Use task notifications or queues to defer work to tasks

§Examples

§One-shot Timer

use osal_rs::os::Timer;
use core::time::Duration;
 
let timer = Timer::new(
    "alarm",
    Duration::from_secs(5),
    false,  // One-shot
    None,
    |_timer, _param| {
        println!("Alarm!");
        trigger_alarm();
        Ok(None)
    }
).unwrap();
 
timer.start(0);
// Expires once after 5 seconds

§Periodic Timer

use std::sync::Arc;

let counter = Arc::new(0u32);
let periodic = Timer::new(
    "counter",
    Duration::from_millis(100),
    true,  // Auto-reload
    Some(counter.clone()),
    |_timer, param| {
        if let Some(p) = param {
            if let Some(count) = p.downcast_ref::<u32>() {
                println!("Count: {}", count);
                return Ok(Arc::new(*count + 1));
            }
        }
        Ok(Arc::new(0u32))
    }
).unwrap();
 
periodic.start(0);
// Runs every 100ms until stopped

Required Methods§

Source

fn start(&self, ticks_to_wait: TickType) -> OsalRsBool

Starts or restarts the timer.

If the timer is already running, this command resets it to its full period (equivalent to calling reset()). If stopped, the timer begins counting down from its period.

§Parameters
  • ticks_to_wait - Maximum ticks to wait if command queue is full:
    • 0: Return immediately if queue full
    • n: Wait up to n ticks
    • TickType::MAX: Wait forever
§Returns
  • True - Command sent successfully to timer service
  • False - Failed to send command (queue full, timeout)
§Timing

The timer begins counting after the command is processed by the timer service task, not immediately when this function returns.

§Examples
use osal_rs::os::Timer;

// Start immediately, don't wait
if timer.start(0).into() {
    println!("Timer started");
}

// Wait up to 100 ticks for command queue
timer.start(100);
Source

fn stop(&self, ticks_to_wait: TickType) -> OsalRsBool

Stops the timer.

The timer will not expire until started again with start() or reset(). For periodic timers, this stops the automatic reloading.

§Parameters
  • ticks_to_wait - Maximum ticks to wait if command queue is full:
    • 0: Return immediately if queue full
    • n: Wait up to n ticks
    • TickType::MAX: Wait forever
§Returns
  • True - Command sent successfully to timer service
  • False - Failed to send command (queue full, timeout)
§State

If the timer is already stopped, this command has no effect but still returns True.

§Examples
use osal_rs::os::Timer;

// Stop the timer, wait up to 100 ticks
if timer.stop(100).into() {
    println!("Timer stopped");
}

// Later, restart it
timer.start(100);
Source

fn reset(&self, ticks_to_wait: TickType) -> OsalRsBool

Resets the timer to its full period.

If the timer is running, this restarts it from the beginning of its period. If the timer is stopped, this starts it. This is useful for implementing watchdog-style timers that must be periodically reset.

§Parameters
  • ticks_to_wait - Maximum ticks to wait if command queue is full:
    • 0: Return immediately if queue full
    • n: Wait up to n ticks
    • TickType::MAX: Wait forever
§Returns
  • True - Command sent successfully to timer service
  • False - Failed to send command (queue full, timeout)
§Use Cases
  • Watchdog timer: Reset timer to prevent timeout
  • Activity timer: Reset when activity detected
  • Timeout extension: Give more time before expiration
§Examples
use osal_rs::os::Timer;
use core::time::Duration;

// Watchdog timer pattern
let watchdog = Timer::new(
    "watchdog",
    Duration::from_secs(10),
    false,
    None,
    |_timer, _param| {
        println!("WATCHDOG TIMEOUT!");
        system_reset();
        Ok(None)
    }
).unwrap();

watchdog.start(0);

// In main loop: reset watchdog to prevent timeout
loop {
    do_work();
    watchdog.reset(0);  // "Feed" the watchdog
}
Source

fn change_period( &self, new_period_in_ticks: TickType, ticks_to_wait: TickType, ) -> OsalRsBool

Changes the timer period.

Updates the timer period. The new period takes effect immediately:

  • If the timer is running, it continues with the new period
  • The remaining time is adjusted proportionally
  • For periodic timers, future expirations use the new period
§Parameters
  • new_period_in_ticks - New timer period in ticks
  • ticks_to_wait - Maximum ticks to wait if command queue is full:
    • 0: Return immediately if queue full
    • n: Wait up to n ticks
    • TickType::MAX: Wait forever
§Returns
  • True - Command sent successfully to timer service
  • False - Failed to send command (queue full, timeout)
§Behavior
  • If timer has already expired and is auto-reload, the new period applies to the next expiration
  • If timer is stopped, the new period will be used when started
§Examples
use osal_rs::os::Timer;
use core::time::Duration;

let timer = Timer::new(
    "adaptive",
    Duration::from_millis(100),
    true,
    None,
    |_timer, _param| Ok(None)
).unwrap();

timer.start(0);

// Later, adjust the period based on system load
if system_busy() {
    // Slow down to 500ms
    timer.change_period(500, 100);
} else {
    // Speed up to 100ms
    timer.change_period(100, 100);
}
Source

fn delete(&mut self, ticks_to_wait: TickType) -> OsalRsBool

Deletes the timer and frees its resources.

Terminates the timer and releases its resources. After deletion, the timer handle becomes invalid and should not be used.

§Parameters
  • ticks_to_wait - Maximum ticks to wait if command queue is full:
    • 0: Return immediately if queue full
    • n: Wait up to n ticks
    • TickType::MAX: Wait forever
§Returns
  • True - Command sent successfully to timer service
  • False - Failed to send command (queue full, timeout)
§Safety
  • The timer should be stopped before deletion (recommended)
  • Do not use the timer handle after calling this
  • The timer is deleted asynchronously by the timer service task
§Best Practice

Stop the timer before deleting it to ensure clean shutdown:

timer.stop(100);
timer.delete(100);
§Examples
use osal_rs::os::Timer;
use core::time::Duration;

let mut timer = Timer::new(
    "temporary",
    Duration::from_secs(1),
    false,
    None,
    |_timer, _param| Ok(None)
).unwrap();

timer.start(0);
// ... use timer ...

// Clean shutdown
timer.stop(100);
if timer.delete(100).into() {
    println!("Timer deleted");
}

Implementors§