Skip to content

Commit 33269b3

Browse files
committed
feat: selection policy in UART virtualizer
1 parent b9fd381 commit 33269b3

14 files changed

Lines changed: 348 additions & 107 deletions

File tree

boards/components/src/console.rs

Lines changed: 120 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
use capsules_core::console;
3939
use capsules_core::console_ordered::ConsoleOrdered;
4040

41+
use capsules_core::virtualizers::selection_policy::{InsertionFirstPolicy, SelectionPolicy};
4142
use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
4243
use capsules_core::virtualizers::virtual_uart::{MuxUart, UartDevice};
4344
use core::mem::MaybeUninit;
@@ -53,45 +54,97 @@ use capsules_core::console::DEFAULT_BUF_SIZE;
5354
#[macro_export]
5455
macro_rules! uart_mux_component_static {
5556
// Common logic for both branches
56-
($rx_buffer_len: expr) => {{
57+
($rx_buffer_len: expr, $P: ty) => {{
5758
use capsules_core::virtualizers::virtual_uart::MuxUart;
5859
use kernel::static_buf;
59-
let uart_mux = static_buf!(MuxUart<'static>);
60+
let uart_mux = static_buf!(MuxUart<'static, $P>);
6061
let rx_buf = static_buf!([u8; $rx_buffer_len]);
6162
(uart_mux, rx_buf)
6263
}};
63-
() => {
64-
$crate::uart_mux_component_static!(capsules_core::virtualizers::virtual_uart::RX_BUF_LEN);
65-
};
66-
($rx_buffer_len: literal) => {
67-
$crate::uart_mux_component_static!($rx_buffer_len);
64+
($P: ty) => {
65+
$crate::uart_mux_component_static!(
66+
capsules_core::virtualizers::virtual_uart::RX_BUF_LEN,
67+
$P
68+
)
6869
};
70+
// Added for backward compatibility
71+
() => {{
72+
use capsules_core::virtualizers::selection_policy::InsertionFirstPolicy;
73+
$crate::uart_mux_component_static!(
74+
capsules_core::virtualizers::virtual_uart::RX_BUF_LEN,
75+
InsertionFirstPolicy
76+
)
77+
}};
78+
($rx_buffer_len: literal) => {{
79+
use capsules_core::virtualizers::selection_policy::InsertionFirstPolicy;
80+
$crate::uart_mux_component_static!($rx_buffer_len, InsertionFirstPolicy)
81+
}};
6982
}
7083

71-
pub struct UartMuxComponent<const RX_BUF_LEN: usize> {
84+
pub struct UartMuxComponent<
85+
const RX_BUF_LEN: usize,
86+
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static = InsertionFirstPolicy,
87+
> {
7288
uart: &'static dyn uart::Uart<'static>,
7389
baud_rate: u32,
90+
selection_policy: P,
7491
}
7592

76-
impl<const RX_BUF_LEN: usize> UartMuxComponent<RX_BUF_LEN> {
93+
// Implemented for backward compatibility
94+
impl<const RX_BUF_LEN: usize> UartMuxComponent<RX_BUF_LEN, InsertionFirstPolicy> {
95+
/// Create a new MuxComponent with the [`InsertionFirstPolicy`] selection policy.
7796
pub fn new(
7897
uart: &'static dyn uart::Uart<'static>,
7998
baud_rate: u32,
80-
) -> UartMuxComponent<RX_BUF_LEN> {
81-
UartMuxComponent { uart, baud_rate }
99+
) -> UartMuxComponent<RX_BUF_LEN, InsertionFirstPolicy> {
100+
UartMuxComponent {
101+
uart,
102+
baud_rate,
103+
selection_policy: InsertionFirstPolicy,
104+
}
105+
}
106+
}
107+
108+
// Implemented to specify a custom selection policy
109+
impl<const RX_BUF_LEN: usize, P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static>
110+
UartMuxComponent<RX_BUF_LEN, P>
111+
{
112+
/// Create a new MuxComponent with a custom selection policy.
113+
/// It determines which device will be selected next
114+
/// from the list of devices in the virtualizer.
115+
///
116+
/// For the default implementation, please refer to `new` function
117+
/// which uses `InsertionFirstPolicy` selection polity.
118+
pub fn new_with_policy(
119+
uart: &'static dyn uart::Uart<'static>,
120+
baud_rate: u32,
121+
selection_policy: P,
122+
) -> UartMuxComponent<RX_BUF_LEN, P> {
123+
UartMuxComponent {
124+
uart,
125+
baud_rate,
126+
selection_policy,
127+
}
82128
}
83129
}
84130

85-
impl<const RX_BUF_LEN: usize> Component for UartMuxComponent<RX_BUF_LEN> {
131+
impl<const RX_BUF_LEN: usize, P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static>
132+
Component for UartMuxComponent<RX_BUF_LEN, P>
133+
{
86134
type StaticInput = (
87-
&'static mut MaybeUninit<MuxUart<'static>>,
135+
&'static mut MaybeUninit<MuxUart<'static, P>>,
88136
&'static mut MaybeUninit<[u8; RX_BUF_LEN]>,
89137
);
90-
type Output = &'static MuxUart<'static>;
138+
type Output = &'static MuxUart<'static, P>;
91139

92140
fn finalize(self, s: Self::StaticInput) -> Self::Output {
93141
let rx_buf = s.1.write([0; RX_BUF_LEN]);
94-
let uart_mux = s.0.write(MuxUart::new(self.uart, rx_buf, self.baud_rate));
142+
let uart_mux = s.0.write(MuxUart::new_with_policy(
143+
self.uart,
144+
rx_buf,
145+
self.baud_rate,
146+
self.selection_policy,
147+
));
95148
kernel::deferred_call::DeferredCallClient::register(uart_mux);
96149

97150
uart_mux.initialize();
@@ -105,37 +158,54 @@ impl<const RX_BUF_LEN: usize> Component for UartMuxComponent<RX_BUF_LEN> {
105158
#[macro_export]
106159
macro_rules! console_component_static {
107160
// Common logic for both branches
108-
($rx_buffer_len: expr, $tx_buffer_len: expr) => {{
161+
($rx_buffer_len: expr, $tx_buffer_len: expr, $P: ty) => {{
109162
use capsules_core::console::{Console, DEFAULT_BUF_SIZE};
110163
use capsules_core::virtualizers::virtual_uart::UartDevice;
111164
use kernel::static_buf;
112165
let read_buf = static_buf!([u8; $rx_buffer_len]);
113166
let write_buf = static_buf!([u8; $tx_buffer_len]);
114167
// Create virtual device for console.
115-
let console_uart = static_buf!(UartDevice);
168+
let console_uart = static_buf!(UartDevice<$P>);
116169
let console = static_buf!(Console<'static>);
117170
(write_buf, read_buf, console_uart, console)
118171
}};
119-
() => {
120-
$crate::console_component_static!(DEFAULT_BUF_SIZE, DEFAULT_BUF_SIZE);
172+
($rx_buffer_len: literal, $tx_buffer_len: literal, $P: ty) => {
173+
$crate::console_component_static!($rx_buffer_len, $tx_buffer_len, $P);
121174
};
122-
($rx_buffer_len: literal, $tx_buffer_len: literal) => {
123-
$crate::console_component_static!($rx_buffer_len, $tx_buffer_len);
175+
($rx_buffer_len: literal, $tx_buffer_len: literal) => {{
176+
use capsules_core::virtualizers::selection_policy::InsertionFirstPolicy;
177+
$crate::console_component_static!($rx_buffer_len, $tx_buffer_len, InsertionFirstPolicy)
178+
}};
179+
($P: ty) => {
180+
$crate::console_component_static!(DEFAULT_BUF_SIZE, DEFAULT_BUF_SIZE, $P);
124181
};
182+
() => {{
183+
use capsules_core::virtualizers::selection_policy::InsertionFirstPolicy;
184+
$crate::console_component_static!(DEFAULT_BUF_SIZE, DEFAULT_BUF_SIZE, InsertionFirstPolicy)
185+
}};
125186
}
126187

127-
pub struct ConsoleComponent<const RX_BUF_LEN: usize, const TX_BUF_LEN: usize> {
188+
pub struct ConsoleComponent<
189+
const RX_BUF_LEN: usize,
190+
const TX_BUF_LEN: usize,
191+
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
192+
> {
128193
board_kernel: &'static kernel::Kernel,
129194
driver_num: usize,
130-
uart_mux: &'static MuxUart<'static>,
195+
uart_mux: &'static MuxUart<'static, P>,
131196
}
132197

133-
impl<const RX_BUF_LEN: usize, const TX_BUF_LEN: usize> ConsoleComponent<RX_BUF_LEN, TX_BUF_LEN> {
198+
impl<
199+
const RX_BUF_LEN: usize,
200+
const TX_BUF_LEN: usize,
201+
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
202+
> ConsoleComponent<RX_BUF_LEN, TX_BUF_LEN, P>
203+
{
134204
pub fn new(
135205
board_kernel: &'static kernel::Kernel,
136206
driver_num: usize,
137-
uart_mux: &'static MuxUart,
138-
) -> ConsoleComponent<RX_BUF_LEN, TX_BUF_LEN> {
207+
uart_mux: &'static MuxUart<P>,
208+
) -> ConsoleComponent<RX_BUF_LEN, TX_BUF_LEN, P> {
139209
ConsoleComponent {
140210
board_kernel,
141211
driver_num,
@@ -144,13 +214,16 @@ impl<const RX_BUF_LEN: usize, const TX_BUF_LEN: usize> ConsoleComponent<RX_BUF_L
144214
}
145215
}
146216

147-
impl<const RX_BUF_LEN: usize, const TX_BUF_LEN: usize> Component
148-
for ConsoleComponent<RX_BUF_LEN, TX_BUF_LEN>
217+
impl<
218+
const RX_BUF_LEN: usize,
219+
const TX_BUF_LEN: usize,
220+
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
221+
> Component for ConsoleComponent<RX_BUF_LEN, TX_BUF_LEN, P>
149222
{
150223
type StaticInput = (
151224
&'static mut MaybeUninit<[u8; TX_BUF_LEN]>,
152225
&'static mut MaybeUninit<[u8; RX_BUF_LEN]>,
153-
&'static mut MaybeUninit<UartDevice<'static>>,
226+
&'static mut MaybeUninit<UartDevice<'static, P>>,
154227
&'static mut MaybeUninit<console::Console<'static>>,
155228
);
156229
type Output = &'static console::Console<'static>;
@@ -189,26 +262,33 @@ macro_rules! console_ordered_component_static {
189262
};};
190263
}
191264

192-
pub struct ConsoleOrderedComponent<A: 'static + time::Alarm<'static>> {
265+
pub struct ConsoleOrderedComponent<
266+
A: 'static + time::Alarm<'static>,
267+
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
268+
> {
193269
board_kernel: &'static kernel::Kernel,
194270
driver_num: usize,
195-
uart_mux: &'static MuxUart<'static>,
271+
uart_mux: &'static MuxUart<'static, P>,
196272
alarm_mux: &'static MuxAlarm<'static, A>,
197273
atomic_size: usize,
198274
retry_timer: u32,
199275
write_timer: u32,
200276
}
201277

202-
impl<A: 'static + time::Alarm<'static>> ConsoleOrderedComponent<A> {
278+
impl<
279+
A: 'static + time::Alarm<'static>,
280+
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
281+
> ConsoleOrderedComponent<A, P>
282+
{
203283
pub fn new(
204284
board_kernel: &'static kernel::Kernel,
205285
driver_num: usize,
206-
uart_mux: &'static MuxUart<'static>,
286+
uart_mux: &'static MuxUart<'static, P>,
207287
alarm_mux: &'static MuxAlarm<'static, A>,
208288
atomic_size: usize,
209289
retry_timer: u32,
210290
write_timer: u32,
211-
) -> ConsoleOrderedComponent<A> {
291+
) -> ConsoleOrderedComponent<A, P> {
212292
ConsoleOrderedComponent {
213293
board_kernel,
214294
driver_num,
@@ -221,11 +301,15 @@ impl<A: 'static + time::Alarm<'static>> ConsoleOrderedComponent<A> {
221301
}
222302
}
223303

224-
impl<A: 'static + time::Alarm<'static>> Component for ConsoleOrderedComponent<A> {
304+
impl<
305+
A: 'static + time::Alarm<'static>,
306+
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
307+
> Component for ConsoleOrderedComponent<A, P>
308+
{
225309
type StaticInput = (
226310
&'static mut MaybeUninit<VirtualMuxAlarm<'static, A>>,
227311
&'static mut MaybeUninit<[u8; DEFAULT_BUF_SIZE]>,
228-
&'static mut MaybeUninit<UartDevice<'static>>,
312+
&'static mut MaybeUninit<UartDevice<'static, P>>,
229313
&'static mut MaybeUninit<ConsoleOrdered<'static, VirtualMuxAlarm<'static, A>>>,
230314
);
231315
type Output = &'static ConsoleOrdered<'static, VirtualMuxAlarm<'static, A>>;

boards/components/src/debug_writer.rs

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
// Author: Brad Campbell <bradjc@virginia.edu>
2828
// Last modified: 11/07/2019
2929

30+
use capsules_core::virtualizers::selection_policy::SelectionPolicy;
3031
use capsules_core::virtualizers::virtual_uart::{MuxUart, UartDevice};
3132
use capsules_system::debug_writer::uart_debug_writer::UartDebugWriter;
3233
use core::mem::MaybeUninit;
@@ -55,17 +56,29 @@ const DEBUG_BUFFER_SPLIT: usize = 64;
5556
/// quick succession.
5657
#[macro_export]
5758
macro_rules! debug_writer_component_static {
58-
($BUF_SIZE_KB:expr) => {{
59-
let uart = kernel::static_buf!(capsules_core::virtualizers::virtual_uart::UartDevice);
59+
($BUF_SIZE_KB:expr, $P: ty) => {{
60+
let uart = kernel::static_buf!(capsules_core::virtualizers::virtual_uart::UartDevice<$P>);
6061
let ring = kernel::static_buf!(kernel::collections::ring_buffer::RingBuffer<'static, u8>);
6162
let buffer = kernel::static_buf!([u8; 1024 * $BUF_SIZE_KB]);
6263
let debug =
6364
kernel::static_buf!(capsules_system::debug_writer::uart_debug_writer::UartDebugWriter);
6465

6566
(uart, ring, buffer, debug)
6667
};};
68+
($P: ty) => {{
69+
$crate::debug_writer_component_static!($crate::debug_writer::DEFAULT_DEBUG_BUFFER_KBYTE, $P)
70+
};};
71+
($BUF_SIZE_KB:expr) => {{
72+
$crate::debug_writer_component_static!(
73+
$BUF_SIZE_KB,
74+
capsules_core::virtualizers::selection_policy::InsertionFirstPolicy
75+
)
76+
};};
6777
() => {{
68-
$crate::debug_writer_component_static!($crate::debug_writer::DEFAULT_DEBUG_BUFFER_KBYTE)
78+
$crate::debug_writer_component_static!(
79+
$crate::debug_writer::DEFAULT_DEBUG_BUFFER_KBYTE,
80+
capsules_core::virtualizers::selection_policy::InsertionFirstPolicy
81+
)
6982
};};
7083
}
7184

@@ -92,20 +105,27 @@ macro_rules! debug_writer_no_mux_component_static {
92105

93106
// Allow dead code because we need the `Chip` type but don't use `chip`.
94107
#[allow(dead_code)]
95-
pub struct DebugWriterComponent<const BUF_SIZE_BYTES: usize, C: SetDebugWriterCapability> {
96-
uart_mux: &'static MuxUart<'static>,
108+
pub struct DebugWriterComponent<
109+
const BUF_SIZE_BYTES: usize,
110+
C: SetDebugWriterCapability,
111+
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
112+
> {
113+
uart_mux: &'static MuxUart<'static, P>,
97114
marker: core::marker::PhantomData<[u8; BUF_SIZE_BYTES]>,
98115
capability: C,
99116
}
100117

101-
impl<const BUF_SIZE_BYTES: usize, C: SetDebugWriterCapability>
102-
DebugWriterComponent<BUF_SIZE_BYTES, C>
118+
impl<
119+
const BUF_SIZE_BYTES: usize,
120+
C: SetDebugWriterCapability,
121+
SP: SelectionPolicy<&'static UartDevice<'static, SP>> + 'static,
122+
> DebugWriterComponent<BUF_SIZE_BYTES, C, SP>
103123
{
104124
/// Create a debug writer component while binding the global variable used
105125
/// by debug.rs to the main thread.
106126
#[cfg(target_has_atomic = "ptr")]
107127
pub fn new<P: kernel::platform::chip::ThreadIdProvider>(
108-
uart_mux: &'static MuxUart,
128+
uart_mux: &'static MuxUart<SP>,
109129
capability: C,
110130
) -> Self {
111131
kernel::debug::initialize_debug_writer_wrapper::<P>();
@@ -137,7 +157,11 @@ impl<const BUF_SIZE_BYTES: usize, C: SetDebugWriterCapability>
137157
/// })
138158
/// .finalize(components::debug_writer_component_static!());
139159
/// ```
140-
pub fn new_unsafe<F>(uart_mux: &'static MuxUart, capability: C, bind_debug_global: F) -> Self
160+
pub fn new_unsafe<F>(
161+
uart_mux: &'static MuxUart<SP>,
162+
capability: C,
163+
bind_debug_global: F,
164+
) -> Self
141165
where
142166
F: FnOnce(),
143167
{
@@ -154,11 +178,14 @@ impl<const BUF_SIZE_BYTES: usize, C: SetDebugWriterCapability>
154178
pub struct Capability;
155179
unsafe impl capabilities::ProcessManagementCapability for Capability {}
156180

157-
impl<const BUF_SIZE_BYTES: usize, C: SetDebugWriterCapability> Component
158-
for DebugWriterComponent<BUF_SIZE_BYTES, C>
181+
impl<
182+
const BUF_SIZE_BYTES: usize,
183+
C: SetDebugWriterCapability,
184+
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
185+
> Component for DebugWriterComponent<BUF_SIZE_BYTES, C, P>
159186
{
160187
type StaticInput = (
161-
&'static mut MaybeUninit<UartDevice<'static>>,
188+
&'static mut MaybeUninit<UartDevice<'static, P>>,
162189
&'static mut MaybeUninit<RingBuffer<'static, u8>>,
163190
&'static mut MaybeUninit<[u8; BUF_SIZE_BYTES]>,
164191
&'static mut MaybeUninit<UartDebugWriter>,

0 commit comments

Comments
 (0)