3838use capsules_core:: console;
3939use capsules_core:: console_ordered:: ConsoleOrdered ;
4040
41+ use capsules_core:: virtualizers:: selection_policy:: { InsertionFirstPolicy , SelectionPolicy } ;
4142use capsules_core:: virtualizers:: virtual_alarm:: { MuxAlarm , VirtualMuxAlarm } ;
4243use capsules_core:: virtualizers:: virtual_uart:: { MuxUart , UartDevice } ;
4344use core:: mem:: MaybeUninit ;
@@ -53,45 +54,98 @@ use capsules_core::console::DEFAULT_BUF_SIZE;
5354#[ macro_export]
5455macro_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]
106160macro_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 > > ;
0 commit comments