|
1 |
| -//! Components for Console, the generic serial interface, and for multiplexed access |
2 |
| -//! to UART. |
| 1 | +//! Components for Console and ConsoleOrdered. These are two alternative implementations of |
| 2 | +//! the serial console system call interface. Console allows prints of arbitrary length but does |
| 3 | +//! not have ordering or atomicity guarantees. ConsoleOrdered, in contrast, has limits on the |
| 4 | +//! maximum lengths of prints but provides a temporal ordering and ensures a print is atomic at |
| 5 | +//! least up to particular length (typically 200 bytes). Console is useful when userspace is |
| 6 | +//! printing large messages. ConsoleOrdered is useful when you are debugging and there are |
| 7 | +//! inter-related messages from the kernel and userspace, whose ordering is important to |
| 8 | +//! maintain. |
3 | 9 | //!
|
4 | 10 | //!
|
5 |
| -//! This provides two Components, `ConsoleComponent`, which implements a buffered |
6 |
| -//! read/write console over a serial port, and `UartMuxComponent`, which provides |
7 |
| -//! multiplexed access to hardware UART. As an example, the serial port used for |
8 |
| -//! console on Imix is typically USART3 (the DEBUG USB connector). |
| 11 | +//! This provides three Components, `ConsoleComponent` and |
| 12 | +//! `ConsoleOrderedComponent`, which implement a buffered read/write |
| 13 | +//! console over a serial port, and `UartMuxComponent`, which provides |
| 14 | +//! multiplexed access to hardware UART. As an example, the serial |
| 15 | +//! port used for console on Imix is typically USART3 (the DEBUG USB |
| 16 | +//! connector). |
9 | 17 | //!
|
10 | 18 | //! Usage
|
11 | 19 | //! -----
|
|
20 | 28 | // Last modified: 1/08/2020
|
21 | 29 |
|
22 | 30 | use capsules_core::console;
|
| 31 | +use capsules_core::console_ordered::ConsoleOrdered; |
| 32 | + |
| 33 | +use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm}; |
23 | 34 | use capsules_core::virtualizers::virtual_uart::{MuxUart, UartDevice};
|
24 | 35 | use core::mem::MaybeUninit;
|
25 | 36 | use kernel::capabilities;
|
26 | 37 | use kernel::component::Component;
|
27 | 38 | use kernel::create_capability;
|
28 | 39 | use kernel::hil;
|
| 40 | +use kernel::hil::time::{self, Alarm}; |
29 | 41 | use kernel::hil::uart;
|
30 | 42 |
|
31 | 43 | use capsules_core::console::DEFAULT_BUF_SIZE;
|
@@ -148,3 +160,66 @@ impl Component for ConsoleComponent {
|
148 | 160 | console
|
149 | 161 | }
|
150 | 162 | }
|
| 163 | +#[macro_export] |
| 164 | +macro_rules! console_ordered_component_static { |
| 165 | + ($A:ty $(,)?) => {{ |
| 166 | + let mux_alarm = kernel::static_buf!(VirtualMuxAlarm<'static, $A>); |
| 167 | + let console = kernel::static_buf!(ConsoleOrdered<'static, VirtualMuxAlarm<'static, $A>>); |
| 168 | + (mux_alarm, console) |
| 169 | + };}; |
| 170 | +} |
| 171 | + |
| 172 | +pub struct ConsoleOrderedComponent<A: 'static + time::Alarm<'static>> { |
| 173 | + board_kernel: &'static kernel::Kernel, |
| 174 | + driver_num: usize, |
| 175 | + alarm_mux: &'static MuxAlarm<'static, A>, |
| 176 | + atomic_size: usize, |
| 177 | + retry_timer: u32, |
| 178 | + write_timer: u32, |
| 179 | +} |
| 180 | + |
| 181 | +impl<A: 'static + time::Alarm<'static>> ConsoleOrderedComponent<A> { |
| 182 | + pub fn new( |
| 183 | + board_kernel: &'static kernel::Kernel, |
| 184 | + driver_num: usize, |
| 185 | + alarm_mux: &'static MuxAlarm<'static, A>, |
| 186 | + atomic_size: usize, |
| 187 | + retry_timer: u32, |
| 188 | + write_timer: u32, |
| 189 | + ) -> ConsoleOrderedComponent<A> { |
| 190 | + ConsoleOrderedComponent { |
| 191 | + board_kernel: board_kernel, |
| 192 | + driver_num: driver_num, |
| 193 | + alarm_mux: alarm_mux, |
| 194 | + atomic_size: atomic_size, |
| 195 | + retry_timer: retry_timer, |
| 196 | + write_timer: write_timer, |
| 197 | + } |
| 198 | + } |
| 199 | +} |
| 200 | + |
| 201 | +impl<A: 'static + time::Alarm<'static>> Component for ConsoleOrderedComponent<A> { |
| 202 | + type StaticInput = ( |
| 203 | + &'static mut MaybeUninit<VirtualMuxAlarm<'static, A>>, |
| 204 | + &'static mut MaybeUninit<ConsoleOrdered<'static, VirtualMuxAlarm<'static, A>>>, |
| 205 | + ); |
| 206 | + type Output = &'static ConsoleOrdered<'static, VirtualMuxAlarm<'static, A>>; |
| 207 | + |
| 208 | + fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output { |
| 209 | + let grant_cap = create_capability!(capabilities::MemoryAllocationCapability); |
| 210 | + |
| 211 | + let virtual_alarm1 = static_buffer.0.write(VirtualMuxAlarm::new(self.alarm_mux)); |
| 212 | + virtual_alarm1.setup(); |
| 213 | + |
| 214 | + let console = static_buffer.1.write(ConsoleOrdered::new( |
| 215 | + virtual_alarm1, |
| 216 | + self.board_kernel.create_grant(self.driver_num, &grant_cap), |
| 217 | + self.atomic_size, |
| 218 | + self.retry_timer, |
| 219 | + self.write_timer, |
| 220 | + )); |
| 221 | + |
| 222 | + virtual_alarm1.set_alarm_client(console); |
| 223 | + console |
| 224 | + } |
| 225 | +} |
0 commit comments