Skip to content

Commit 1a37768

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

15 files changed

Lines changed: 379 additions & 110 deletions

File tree

boards/components/src/console.rs

Lines changed: 122 additions & 37 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,98 @@ 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);
68-
};
64+
($P: ty) => {{
65+
$crate::uart_mux_component_static!(
66+
capsules_core::virtualizers::virtual_uart::RX_BUF_LEN,
67+
$P
68+
)
69+
}};
70+
// By default, if no selection policy is provided we will use the `InsertionFirstPolicy`.
71+
// This option has been chosen as the default to maintain backwards compatibility.
72+
() => {{
73+
use capsules_core::virtualizers::selection_policy::InsertionFirstPolicy;
74+
$crate::uart_mux_component_static!(
75+
capsules_core::virtualizers::virtual_uart::RX_BUF_LEN,
76+
InsertionFirstPolicy
77+
)
78+
}};
79+
($rx_buffer_len: literal) => {{
80+
use capsules_core::virtualizers::selection_policy::InsertionFirstPolicy;
81+
$crate::uart_mux_component_static!($rx_buffer_len, InsertionFirstPolicy)
82+
}};
6983
}
7084

71-
pub struct UartMuxComponent<const RX_BUF_LEN: usize> {
85+
pub struct UartMuxComponent<
86+
const RX_BUF_LEN: usize,
87+
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static = InsertionFirstPolicy,
88+
> {
7289
uart: &'static dyn uart::Uart<'static>,
7390
baud_rate: u32,
91+
selection_policy: P,
7492
}
7593

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

85-
impl<const RX_BUF_LEN: usize> Component for UartMuxComponent<RX_BUF_LEN> {
132+
impl<const RX_BUF_LEN: usize, P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static>
133+
Component for UartMuxComponent<RX_BUF_LEN, P>
134+
{
86135
type StaticInput = (
87-
&'static mut MaybeUninit<MuxUart<'static>>,
136+
&'static mut MaybeUninit<MuxUart<'static, P>>,
88137
&'static mut MaybeUninit<[u8; RX_BUF_LEN]>,
89138
);
90-
type Output = &'static MuxUart<'static>;
139+
type Output = &'static MuxUart<'static, P>;
91140

92141
fn finalize(self, s: Self::StaticInput) -> Self::Output {
93142
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));
143+
let uart_mux = s.0.write(MuxUart::new_with_policy(
144+
self.uart,
145+
rx_buf,
146+
self.baud_rate,
147+
self.selection_policy,
148+
));
95149
kernel::deferred_call::DeferredCallClient::register(uart_mux);
96150

97151
uart_mux.initialize();
@@ -105,37 +159,54 @@ impl<const RX_BUF_LEN: usize> Component for UartMuxComponent<RX_BUF_LEN> {
105159
#[macro_export]
106160
macro_rules! console_component_static {
107161
// Common logic for both branches
108-
($rx_buffer_len: expr, $tx_buffer_len: expr) => {{
162+
($rx_buffer_len: expr, $tx_buffer_len: expr, $P: ty) => {{
109163
use capsules_core::console::{Console, DEFAULT_BUF_SIZE};
110164
use capsules_core::virtualizers::virtual_uart::UartDevice;
111165
use kernel::static_buf;
112166
let read_buf = static_buf!([u8; $rx_buffer_len]);
113167
let write_buf = static_buf!([u8; $tx_buffer_len]);
114168
// Create virtual device for console.
115-
let console_uart = static_buf!(UartDevice);
169+
let console_uart = static_buf!(UartDevice<$P>);
116170
let console = static_buf!(Console<'static>);
117171
(write_buf, read_buf, console_uart, console)
118172
}};
119-
() => {
120-
$crate::console_component_static!(DEFAULT_BUF_SIZE, DEFAULT_BUF_SIZE);
173+
($rx_buffer_len: literal, $tx_buffer_len: literal, $P: ty) => {
174+
$crate::console_component_static!($rx_buffer_len, $tx_buffer_len, $P);
121175
};
122-
($rx_buffer_len: literal, $tx_buffer_len: literal) => {
123-
$crate::console_component_static!($rx_buffer_len, $tx_buffer_len);
176+
($rx_buffer_len: literal, $tx_buffer_len: literal) => {{
177+
use capsules_core::virtualizers::selection_policy::InsertionFirstPolicy;
178+
$crate::console_component_static!($rx_buffer_len, $tx_buffer_len, InsertionFirstPolicy)
179+
}};
180+
($P: ty) => {
181+
$crate::console_component_static!(DEFAULT_BUF_SIZE, DEFAULT_BUF_SIZE, $P);
124182
};
183+
() => {{
184+
use capsules_core::virtualizers::selection_policy::InsertionFirstPolicy;
185+
$crate::console_component_static!(DEFAULT_BUF_SIZE, DEFAULT_BUF_SIZE, InsertionFirstPolicy)
186+
}};
125187
}
126188

127-
pub struct ConsoleComponent<const RX_BUF_LEN: usize, const TX_BUF_LEN: usize> {
189+
pub struct ConsoleComponent<
190+
const RX_BUF_LEN: usize,
191+
const TX_BUF_LEN: usize,
192+
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
193+
> {
128194
board_kernel: &'static kernel::Kernel,
129195
driver_num: usize,
130-
uart_mux: &'static MuxUart<'static>,
196+
uart_mux: &'static MuxUart<'static, P>,
131197
}
132198

133-
impl<const RX_BUF_LEN: usize, const TX_BUF_LEN: usize> ConsoleComponent<RX_BUF_LEN, TX_BUF_LEN> {
199+
impl<
200+
const RX_BUF_LEN: usize,
201+
const TX_BUF_LEN: usize,
202+
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
203+
> ConsoleComponent<RX_BUF_LEN, TX_BUF_LEN, P>
204+
{
134205
pub fn new(
135206
board_kernel: &'static kernel::Kernel,
136207
driver_num: usize,
137-
uart_mux: &'static MuxUart,
138-
) -> ConsoleComponent<RX_BUF_LEN, TX_BUF_LEN> {
208+
uart_mux: &'static MuxUart<P>,
209+
) -> ConsoleComponent<RX_BUF_LEN, TX_BUF_LEN, P> {
139210
ConsoleComponent {
140211
board_kernel,
141212
driver_num,
@@ -144,13 +215,16 @@ impl<const RX_BUF_LEN: usize, const TX_BUF_LEN: usize> ConsoleComponent<RX_BUF_L
144215
}
145216
}
146217

147-
impl<const RX_BUF_LEN: usize, const TX_BUF_LEN: usize> Component
148-
for ConsoleComponent<RX_BUF_LEN, TX_BUF_LEN>
218+
impl<
219+
const RX_BUF_LEN: usize,
220+
const TX_BUF_LEN: usize,
221+
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
222+
> Component for ConsoleComponent<RX_BUF_LEN, TX_BUF_LEN, P>
149223
{
150224
type StaticInput = (
151225
&'static mut MaybeUninit<[u8; TX_BUF_LEN]>,
152226
&'static mut MaybeUninit<[u8; RX_BUF_LEN]>,
153-
&'static mut MaybeUninit<UartDevice<'static>>,
227+
&'static mut MaybeUninit<UartDevice<'static, P>>,
154228
&'static mut MaybeUninit<console::Console<'static>>,
155229
);
156230
type Output = &'static console::Console<'static>;
@@ -189,26 +263,33 @@ macro_rules! console_ordered_component_static {
189263
};};
190264
}
191265

192-
pub struct ConsoleOrderedComponent<A: 'static + time::Alarm<'static>> {
266+
pub struct ConsoleOrderedComponent<
267+
A: 'static + time::Alarm<'static>,
268+
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
269+
> {
193270
board_kernel: &'static kernel::Kernel,
194271
driver_num: usize,
195-
uart_mux: &'static MuxUart<'static>,
272+
uart_mux: &'static MuxUart<'static, P>,
196273
alarm_mux: &'static MuxAlarm<'static, A>,
197274
atomic_size: usize,
198275
retry_timer: u32,
199276
write_timer: u32,
200277
}
201278

202-
impl<A: 'static + time::Alarm<'static>> ConsoleOrderedComponent<A> {
279+
impl<
280+
A: 'static + time::Alarm<'static>,
281+
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
282+
> ConsoleOrderedComponent<A, P>
283+
{
203284
pub fn new(
204285
board_kernel: &'static kernel::Kernel,
205286
driver_num: usize,
206-
uart_mux: &'static MuxUart<'static>,
287+
uart_mux: &'static MuxUart<'static, P>,
207288
alarm_mux: &'static MuxAlarm<'static, A>,
208289
atomic_size: usize,
209290
retry_timer: u32,
210291
write_timer: u32,
211-
) -> ConsoleOrderedComponent<A> {
292+
) -> ConsoleOrderedComponent<A, P> {
212293
ConsoleOrderedComponent {
213294
board_kernel,
214295
driver_num,
@@ -221,11 +302,15 @@ impl<A: 'static + time::Alarm<'static>> ConsoleOrderedComponent<A> {
221302
}
222303
}
223304

224-
impl<A: 'static + time::Alarm<'static>> Component for ConsoleOrderedComponent<A> {
305+
impl<
306+
A: 'static + time::Alarm<'static>,
307+
P: SelectionPolicy<&'static UartDevice<'static, P>> + 'static,
308+
> Component for ConsoleOrderedComponent<A, P>
309+
{
225310
type StaticInput = (
226311
&'static mut MaybeUninit<VirtualMuxAlarm<'static, A>>,
227312
&'static mut MaybeUninit<[u8; DEFAULT_BUF_SIZE]>,
228-
&'static mut MaybeUninit<UartDevice<'static>>,
313+
&'static mut MaybeUninit<UartDevice<'static, P>>,
229314
&'static mut MaybeUninit<ConsoleOrdered<'static, VirtualMuxAlarm<'static, A>>>,
230315
);
231316
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)