osal_rs/traits/
timer.rs

1/***************************************************************************
2 *
3 * osal-rs
4 * Copyright (C) 2023/2026 Antonio Salsi <passy.linux@zresa.it>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 *
18 ***************************************************************************/
19
20//! Software timer trait for delayed and periodic callbacks.
21//!
22//! Timers execute callback functions in the context of a timer service task,
23//! enabling delayed operations and periodic tasks without dedicated threads.
24
25use core::any::Any;
26
27use alloc::{boxed::Box, sync::Arc};
28
29use crate::os::types::TickType;
30use crate::utils::{OsalRsBool, Result};
31
32/// Type-erased parameter for timer callbacks.
33///
34/// Allows passing arbitrary data to timer callback functions.
35pub type TimerParam = Arc<dyn Any + Send + Sync>;
36
37/// Timer callback function pointer type.
38///
39/// Callbacks receive the timer handle and optional parameter,
40/// and can return an updated parameter value.
41pub type TimerFnPtr = dyn Fn(Box<dyn Timer>, Option<TimerParam>) -> Result<TimerParam> + Send + Sync + 'static;
42
43/// Software timer for delayed and periodic callbacks.
44///
45/// Timers run callbacks in the timer service task context, not ISR context.
46/// They can be one-shot or auto-reloading (periodic).
47///
48/// # Examples
49///
50/// ## One-shot Timer
51///
52/// ```ignore
53/// use osal_rs::os::{Timer, TimerFn};
54/// use core::time::Duration;
55/// 
56/// let timer = Timer::new(
57///     "one_shot",
58///     Duration::from_secs(5),
59///     false,  // One-shot
60///     None,
61///     |_timer, _param| {
62///         println!("Timer expired!");
63///         Ok(None)
64///     }
65/// ).unwrap();
66/// 
67/// timer.start(0);
68/// ```
69///
70/// ## Periodic Timer
71///
72/// ```ignore
73/// let periodic = Timer::new(
74///     "periodic",
75///     Duration::from_millis(100),
76///     true,  // Auto-reload
77///     None,
78///     |_timer, _param| {
79///         println!("Tick!");
80///         Ok(None)
81///     }
82/// ).unwrap();
83/// 
84/// periodic.start(0);
85/// // Runs every 100ms until stopped
86/// ```
87pub trait Timer {
88    /// Starts or restarts the timer.
89    ///
90    /// If the timer is already running, it is reset to its full period.
91    ///
92    /// # Parameters
93    ///
94    /// * `ticks_to_wait` - Max ticks to wait if command queue is full
95    ///
96    /// # Returns
97    ///
98    /// * `True` - Command sent successfully
99    /// * `False` - Failed to send command
100    ///
101    /// # Examples
102    ///
103    /// ```ignore
104    /// timer.start(100);  // Start with 100 tick timeout
105    /// ```
106    fn start(&self, ticks_to_wait: TickType) -> OsalRsBool;
107    
108    /// Stops the timer.
109    ///
110    /// The timer will not expire until started again.
111    ///
112    /// # Parameters
113    ///
114    /// * `ticks_to_wait` - Max ticks to wait if command queue is full
115    ///
116    /// # Returns
117    ///
118    /// * `True` - Command sent successfully
119    /// * `False` - Failed to send command
120    ///
121    /// # Examples
122    ///
123    /// ```ignore
124    /// timer.stop(100);
125    /// ```
126    fn stop(&self, ticks_to_wait: TickType)  -> OsalRsBool;
127    
128    /// Resets the timer to its full period.
129    ///
130    /// If the timer is running, it restarts from the beginning.
131    /// If stopped, it starts the timer.
132    ///
133    /// # Parameters
134    ///
135    /// * `ticks_to_wait` - Max ticks to wait if command queue is full
136    ///
137    /// # Returns
138    ///
139    /// * `True` - Command sent successfully
140    /// * `False` - Failed to send command
141    ///
142    /// # Examples
143    ///
144    /// ```ignore
145    /// timer.reset(100);  // Restart timer
146    /// ```
147    fn reset(&self, ticks_to_wait: TickType) -> OsalRsBool;
148    
149    /// Changes the timer period.
150    ///
151    /// The new period takes effect immediately if the timer is running.
152    ///
153    /// # Parameters
154    ///
155    /// * `new_period_in_ticks` - New timer period in ticks
156    /// * `new_period_ticks` - Max ticks to wait if command queue is full
157    ///
158    /// # Returns
159    ///
160    /// * `True` - Command sent successfully
161    /// * `False` - Failed to send command
162    ///
163    /// # Examples
164    ///
165    /// ```ignore
166    /// // Change period to 500 ticks
167    /// timer.change_period(500, 100);
168    /// ```
169    fn change_period(&self, new_period_in_ticks: TickType, new_period_ticks: TickType) -> OsalRsBool;
170    
171    /// Deletes the timer and frees its resources.
172    ///
173    /// The timer must be stopped before deletion.
174    ///
175    /// # Parameters
176    ///
177    /// * `ticks_to_wait` - Max ticks to wait if command queue is full
178    ///
179    /// # Returns
180    ///
181    /// * `True` - Command sent successfully
182    /// * `False` - Failed to send command
183    ///
184    /// # Examples
185    ///
186    /// ```ignore
187    /// let mut timer = Timer::new(...).unwrap();
188    /// timer.stop(100);
189    /// timer.delete(100);
190    /// ```
191    fn delete(&mut self, ticks_to_wait: TickType) -> OsalRsBool;
192}