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
- Creation:
Timer::new()with name, period, auto-reload flag, and callback - Start:
start()begins the timer countdown - Expiration: Callback executes when period elapses
- Auto-reload: If enabled, timer automatically restarts
- Management: Use
stop(),reset(),change_period()to control - 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 stoppedRequired Methods§
Sourcefn start(&self, ticks_to_wait: TickType) -> OsalRsBool
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 fulln: Wait up to n ticksTickType::MAX: Wait forever
§Returns
True- Command sent successfully to timer serviceFalse- 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);Sourcefn stop(&self, ticks_to_wait: TickType) -> OsalRsBool
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 fulln: Wait up to n ticksTickType::MAX: Wait forever
§Returns
True- Command sent successfully to timer serviceFalse- 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);Sourcefn reset(&self, ticks_to_wait: TickType) -> OsalRsBool
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 fulln: Wait up to n ticksTickType::MAX: Wait forever
§Returns
True- Command sent successfully to timer serviceFalse- 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
}Sourcefn change_period(
&self,
new_period_in_ticks: TickType,
ticks_to_wait: TickType,
) -> OsalRsBool
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 ticksticks_to_wait- Maximum ticks to wait if command queue is full:0: Return immediately if queue fulln: Wait up to n ticksTickType::MAX: Wait forever
§Returns
True- Command sent successfully to timer serviceFalse- 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);
}Sourcefn delete(&mut self, ticks_to_wait: TickType) -> OsalRsBool
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 fulln: Wait up to n ticksTickType::MAX: Wait forever
§Returns
True- Command sent successfully to timer serviceFalse- 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");
}