components/
virtual_scheduler_timer.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2025.
4
5//! Components for creating a virtual scheduler timer.
6
7use crate::virtual_scheduler_timer::hil::time;
8use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
9use capsules_system::virtual_scheduler_timer::VirtualSchedulerTimer;
10use core::mem::MaybeUninit;
11use kernel::component::Component;
12use kernel::hil;
13
14// Setup static space for the objects.
15#[macro_export]
16macro_rules! virtual_scheduler_timer_component_static {
17    ($A: ty $(,)?) => {{
18        let alarm = kernel::static_buf!(
19            capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>
20        );
21        let scheduler_timer = kernel::static_buf!(
22            capsules_system::virtual_scheduler_timer::VirtualSchedulerTimer<
23                capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>,
24            >
25        );
26
27        (alarm, scheduler_timer)
28    };};
29}
30
31pub type VirtualSchedulerTimerComponentType<A> = VirtualSchedulerTimer<VirtualMuxAlarm<'static, A>>;
32
33pub struct VirtualSchedulerTimerComponent<A: 'static + time::Alarm<'static>> {
34    mux_alarm: &'static MuxAlarm<'static, A>,
35}
36
37impl<A: 'static + time::Alarm<'static>> VirtualSchedulerTimerComponent<A> {
38    pub fn new(mux_alarm: &'static MuxAlarm<'static, A>) -> Self {
39        Self { mux_alarm }
40    }
41}
42
43impl<A: 'static + time::Alarm<'static>> Component for VirtualSchedulerTimerComponent<A> {
44    type StaticInput = (
45        &'static mut MaybeUninit<VirtualMuxAlarm<'static, A>>,
46        &'static mut MaybeUninit<VirtualSchedulerTimer<VirtualMuxAlarm<'static, A>>>,
47    );
48    type Output = &'static VirtualSchedulerTimer<VirtualMuxAlarm<'static, A>>;
49
50    fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
51        let systick_virtual_alarm = static_buffer.0.write(VirtualMuxAlarm::new(self.mux_alarm));
52        systick_virtual_alarm.setup();
53
54        let scheduler_timer = static_buffer
55            .1
56            .write(VirtualSchedulerTimer::new(systick_virtual_alarm));
57
58        scheduler_timer
59    }
60}
61
62#[macro_export]
63macro_rules! virtual_scheduler_timer_no_mux_component_static {
64    ($A: ty $(,)?) => {{
65        let scheduler_timer = kernel::static_buf!(
66            capsules_system::virtual_scheduler_timer::VirtualSchedulerTimer<$A>
67        );
68
69        scheduler_timer
70    };};
71}
72
73pub type VirtualSchedulerTimerNoMuxComponentType<A> = VirtualSchedulerTimer<A>;
74
75pub struct VirtualSchedulerTimerNoMuxComponent<A: 'static + time::Alarm<'static>> {
76    alarm: &'static A,
77}
78
79impl<A: 'static + time::Alarm<'static>> VirtualSchedulerTimerNoMuxComponent<A> {
80    pub fn new(alarm: &'static A) -> Self {
81        Self { alarm }
82    }
83}
84
85impl<A: 'static + time::Alarm<'static>> Component for VirtualSchedulerTimerNoMuxComponent<A> {
86    type StaticInput = &'static mut MaybeUninit<VirtualSchedulerTimer<A>>;
87    type Output = &'static VirtualSchedulerTimer<A>;
88
89    fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
90        let scheduler_timer = static_buffer.write(VirtualSchedulerTimer::new(self.alarm));
91
92        scheduler_timer
93    }
94}