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    /// Creates a new software timer.
89    ///
90    /// # Parameters
91    ///
92    /// * `name` - Timer name for debugging
93    /// * `timer_period_in_ticks` - Timer period in ticks
94    /// * `auto_reload` - `true` for periodic, `false` for one-shot
95    /// * `param` - Optional parameter passed to callback
96    /// * `callback` - Function called when timer expires
97    ///
98    /// # Returns
99    ///
100    /// * `Ok(Self)` - Successfully created timer
101    /// * `Err(Error)` - Creation failed
102    ///
103    /// # Examples
104    ///
105    /// ```ignore
106    /// use osal_rs::os::{Timer, TimerFn};
107    /// 
108    /// let timer = Timer::new(
109    ///     "my_timer",
110    ///     1000,
111    ///     false,
112    ///     None,
113    ///     |_timer, _param| Ok(None)
114    /// ).unwrap();
115    /// ```
116    fn new<F>(name: &str, timer_period_in_ticks: TickType, auto_reload: bool, param: Option<TimerParam>, callback: F) -> Result<Self>
117    where
118        Self: Sized,
119        F: Fn(Box<dyn Timer>, Option<TimerParam>) -> Result<TimerParam> + Send + Sync + Clone + 'static;
120
121    /// Starts or restarts the timer.
122    ///
123    /// If the timer is already running, it is reset to its full period.
124    ///
125    /// # Parameters
126    ///
127    /// * `ticks_to_wait` - Max ticks to wait if command queue is full
128    ///
129    /// # Returns
130    ///
131    /// * `True` - Command sent successfully
132    /// * `False` - Failed to send command
133    ///
134    /// # Examples
135    ///
136    /// ```ignore
137    /// timer.start(100);  // Start with 100 tick timeout
138    /// ```
139    fn start(&self, ticks_to_wait: TickType) -> OsalRsBool;
140    
141    /// Stops the timer.
142    ///
143    /// The timer will not expire until started again.
144    ///
145    /// # Parameters
146    ///
147    /// * `ticks_to_wait` - Max ticks to wait if command queue is full
148    ///
149    /// # Returns
150    ///
151    /// * `True` - Command sent successfully
152    /// * `False` - Failed to send command
153    ///
154    /// # Examples
155    ///
156    /// ```ignore
157    /// timer.stop(100);
158    /// ```
159    fn stop(&self, ticks_to_wait: TickType)  -> OsalRsBool;
160    
161    /// Resets the timer to its full period.
162    ///
163    /// If the timer is running, it restarts from the beginning.
164    /// If stopped, it starts the timer.
165    ///
166    /// # Parameters
167    ///
168    /// * `ticks_to_wait` - Max ticks to wait if command queue is full
169    ///
170    /// # Returns
171    ///
172    /// * `True` - Command sent successfully
173    /// * `False` - Failed to send command
174    ///
175    /// # Examples
176    ///
177    /// ```ignore
178    /// timer.reset(100);  // Restart timer
179    /// ```
180    fn reset(&self, ticks_to_wait: TickType) -> OsalRsBool;
181    
182    /// Changes the timer period.
183    ///
184    /// The new period takes effect immediately if the timer is running.
185    ///
186    /// # Parameters
187    ///
188    /// * `new_period_in_ticks` - New timer period in ticks
189    /// * `new_period_ticks` - Max ticks to wait if command queue is full
190    ///
191    /// # Returns
192    ///
193    /// * `True` - Command sent successfully
194    /// * `False` - Failed to send command
195    ///
196    /// # Examples
197    ///
198    /// ```ignore
199    /// // Change period to 500 ticks
200    /// timer.change_period(500, 100);
201    /// ```
202    fn change_period(&self, new_period_in_ticks: TickType, new_period_ticks: TickType) -> OsalRsBool;
203    
204    /// Deletes the timer and frees its resources.
205    ///
206    /// The timer must be stopped before deletion.
207    ///
208    /// # Parameters
209    ///
210    /// * `ticks_to_wait` - Max ticks to wait if command queue is full
211    ///
212    /// # Returns
213    ///
214    /// * `True` - Command sent successfully
215    /// * `False` - Failed to send command
216    ///
217    /// # Examples
218    ///
219    /// ```ignore
220    /// let mut timer = Timer::new(...).unwrap();
221    /// timer.stop(100);
222    /// timer.delete(100);
223    /// ```
224    fn delete(&mut self, ticks_to_wait: TickType) -> OsalRsBool;
225}