1use capsules_core::process_console::{self, ProcessConsole};
22use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
23use capsules_core::virtualizers::virtual_uart::{MuxUart, UartDevice};
24use core::mem::MaybeUninit;
25use kernel::capabilities;
26use kernel::component::Component;
27use kernel::hil;
28use kernel::hil::time::Alarm;
29use kernel::process::ProcessPrinter;
30
31#[macro_export]
32macro_rules! process_console_component_static {
33 ($A: ty, $COMMAND_HISTORY_LEN: expr $(,)?) => {{
34 let alarm = kernel::static_buf!(capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>);
35 let uart = kernel::static_buf!(capsules_core::virtualizers::virtual_uart::UartDevice);
36 let pconsole = kernel::static_buf!(
37 capsules_core::process_console::ProcessConsole<
38 $COMMAND_HISTORY_LEN,
39 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>,
40 components::process_console::Capability,
41 >
42 );
43
44 let write_buffer = kernel::static_buf!([u8; capsules_core::process_console::WRITE_BUF_LEN]);
45 let read_buffer = kernel::static_buf!([u8; capsules_core::process_console::READ_BUF_LEN]);
46 let queue_buffer = kernel::static_buf!([u8; capsules_core::process_console::QUEUE_BUF_LEN]);
47 let command_buffer = kernel::static_buf!([u8; capsules_core::process_console::COMMAND_BUF_LEN]);
48 let command_history_buffer = kernel::static_buf!(
49 [capsules_core::process_console::Command; $COMMAND_HISTORY_LEN]
50 );
51
52 (
53 alarm,
54 uart,
55 write_buffer,
56 read_buffer,
57 queue_buffer,
58 command_buffer,
59 command_history_buffer,
60 pconsole,
61 )
62 };};
63 ($A: ty $(,)?) => {{
64 $crate::process_console_component_static!($A, { capsules_core::process_console::DEFAULT_COMMAND_HISTORY_LEN })
65 };};
66}
67
68pub struct ProcessConsoleComponent<const COMMAND_HISTORY_LEN: usize, A: 'static + Alarm<'static>> {
69 board_kernel: &'static kernel::Kernel,
70 uart_mux: &'static MuxUart<'static>,
71 alarm_mux: &'static MuxAlarm<'static, A>,
72 process_printer: &'static dyn ProcessPrinter,
73 reset_function: Option<fn() -> !>,
74}
75
76impl<const COMMAND_HISTORY_LEN: usize, A: 'static + Alarm<'static>>
77 ProcessConsoleComponent<COMMAND_HISTORY_LEN, A>
78{
79 pub fn new(
80 board_kernel: &'static kernel::Kernel,
81 uart_mux: &'static MuxUart,
82 alarm_mux: &'static MuxAlarm<'static, A>,
83 process_printer: &'static dyn ProcessPrinter,
84 reset_function: Option<fn() -> !>,
85 ) -> ProcessConsoleComponent<COMMAND_HISTORY_LEN, A> {
86 ProcessConsoleComponent {
87 board_kernel,
88 uart_mux,
89 alarm_mux,
90 process_printer,
91 reset_function,
92 }
93 }
94}
95
96extern "C" {
99 static _estack: u8;
100 static _sstack: u8;
101 static _stext: u8;
102 static _srodata: u8;
103 static _etext: u8;
104 static _srelocate: u8;
105 static _erelocate: u8;
106 static _szero: u8;
107 static _ezero: u8;
108}
109
110pub struct Capability;
111unsafe impl capabilities::ProcessManagementCapability for Capability {}
112unsafe impl capabilities::ProcessStartCapability for Capability {}
113
114impl<const COMMAND_HISTORY_LEN: usize, A: 'static + Alarm<'static>> Component
115 for ProcessConsoleComponent<COMMAND_HISTORY_LEN, A>
116{
117 type StaticInput = (
118 &'static mut MaybeUninit<VirtualMuxAlarm<'static, A>>,
119 &'static mut MaybeUninit<UartDevice<'static>>,
120 &'static mut MaybeUninit<[u8; capsules_core::process_console::WRITE_BUF_LEN]>,
121 &'static mut MaybeUninit<[u8; capsules_core::process_console::READ_BUF_LEN]>,
122 &'static mut MaybeUninit<[u8; capsules_core::process_console::QUEUE_BUF_LEN]>,
123 &'static mut MaybeUninit<[u8; capsules_core::process_console::COMMAND_BUF_LEN]>,
124 &'static mut MaybeUninit<[capsules_core::process_console::Command; COMMAND_HISTORY_LEN]>,
125 &'static mut MaybeUninit<
126 ProcessConsole<'static, COMMAND_HISTORY_LEN, VirtualMuxAlarm<'static, A>, Capability>,
127 >,
128 );
129 type Output = &'static process_console::ProcessConsole<
130 'static,
131 COMMAND_HISTORY_LEN,
132 VirtualMuxAlarm<'static, A>,
133 Capability,
134 >;
135
136 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
137 let console_uart = static_buffer.1.write(UartDevice::new(self.uart_mux, true));
139 console_uart.setup();
140
141 let kernel_addresses = process_console::KernelAddresses {
144 stack_start: core::ptr::addr_of!(_sstack),
145 stack_end: core::ptr::addr_of!(_estack),
146 text_start: core::ptr::addr_of!(_stext),
147 text_end: core::ptr::addr_of!(_etext),
148 read_only_data_start: core::ptr::addr_of!(_srodata),
149 relocations_start: core::ptr::addr_of!(_srelocate),
150 relocations_end: core::ptr::addr_of!(_erelocate),
151 bss_start: core::ptr::addr_of!(_szero),
152 bss_end: core::ptr::addr_of!(_ezero),
153 };
154
155 let console_alarm = static_buffer.0.write(VirtualMuxAlarm::new(self.alarm_mux));
156 console_alarm.setup();
157
158 let write_buffer = static_buffer
159 .2
160 .write([0; capsules_core::process_console::WRITE_BUF_LEN]);
161 let read_buffer = static_buffer
162 .3
163 .write([0; capsules_core::process_console::READ_BUF_LEN]);
164 let queue_buffer = static_buffer
165 .4
166 .write([0; capsules_core::process_console::QUEUE_BUF_LEN]);
167 let command_buffer = static_buffer
168 .5
169 .write([0; capsules_core::process_console::COMMAND_BUF_LEN]);
170 let command_history_buffer = static_buffer
171 .6
172 .write([capsules_core::process_console::Command::default(); COMMAND_HISTORY_LEN]);
173
174 let console = static_buffer.7.write(ProcessConsole::new(
175 console_uart,
176 console_alarm,
177 self.process_printer,
178 write_buffer,
179 read_buffer,
180 queue_buffer,
181 command_buffer,
182 command_history_buffer,
183 self.board_kernel,
184 kernel_addresses,
185 self.reset_function,
186 Capability,
187 ));
188 hil::uart::Transmit::set_transmit_client(console_uart, console);
189 hil::uart::Receive::set_receive_client(console_uart, console);
190 console_alarm.set_alarm_client(console);
191
192 console
193 }
194}