components/
debug_writer.rs1use capsules_core::virtualizers::virtual_uart::{MuxUart, UartDevice};
31use capsules_system::debug_writer::uart_debug_writer::UartDebugWriter;
32use core::mem::MaybeUninit;
33use kernel::capabilities;
34use kernel::capabilities::SetDebugWriterCapability;
35use kernel::collections::ring_buffer::RingBuffer;
36use kernel::component::Component;
37use kernel::hil;
38use kernel::hil::uart;
39
40pub const DEFAULT_DEBUG_BUFFER_KBYTE: usize = 2;
46
47const DEBUG_BUFFER_SPLIT: usize = 64;
50
51#[macro_export]
57macro_rules! debug_writer_component_static {
58 ($BUF_SIZE_KB:expr) => {{
59 let uart = kernel::static_buf!(capsules_core::virtualizers::virtual_uart::UartDevice);
60 let ring = kernel::static_buf!(kernel::collections::ring_buffer::RingBuffer<'static, u8>);
61 let buffer = kernel::static_buf!([u8; 1024 * $BUF_SIZE_KB]);
62 let debug =
63 kernel::static_buf!(capsules_system::debug_writer::uart_debug_writer::UartDebugWriter);
64
65 (uart, ring, buffer, debug)
66 };};
67 () => {{
68 $crate::debug_writer_component_static!($crate::debug_writer::DEFAULT_DEBUG_BUFFER_KBYTE)
69 };};
70}
71
72#[macro_export]
78macro_rules! debug_writer_no_mux_component_static {
79 ($BUF_SIZE_KB:expr) => {{
80 let ring = kernel::static_buf!(kernel::collections::ring_buffer::RingBuffer<'static, u8>);
81 let buffer = kernel::static_buf!([u8; 1024 * $BUF_SIZE_KB]);
82 let debug =
83 kernel::static_buf!(capsules_system::debug_writer::uart_debug_writer::UartDebugWriter);
84
85 (ring, buffer, debug)
86 };};
87 () => {{
88 use $crate::debug_writer::DEFAULT_DEBUG_BUFFER_KBYTE;
89 $crate::debug_writer_no_mux_component_static!(DEFAULT_DEBUG_BUFFER_KBYTE)
90 };};
91}
92
93#[allow(dead_code)]
95pub struct DebugWriterComponent<const BUF_SIZE_BYTES: usize, C: SetDebugWriterCapability> {
96 uart_mux: &'static MuxUart<'static>,
97 marker: core::marker::PhantomData<[u8; BUF_SIZE_BYTES]>,
98 capability: C,
99}
100
101impl<const BUF_SIZE_BYTES: usize, C: SetDebugWriterCapability>
102 DebugWriterComponent<BUF_SIZE_BYTES, C>
103{
104 #[cfg(target_has_atomic = "ptr")]
107 pub fn new<P: kernel::platform::chip::ThreadIdProvider>(
108 uart_mux: &'static MuxUart,
109 capability: C,
110 ) -> Self {
111 kernel::debug::initialize_debug_writer_wrapper::<P>();
112
113 Self {
114 uart_mux,
115 marker: core::marker::PhantomData,
116 capability,
117 }
118 }
119
120 pub fn new_unsafe<F>(uart_mux: &'static MuxUart, capability: C, bind_debug_global: F) -> Self
141 where
142 F: FnOnce(),
143 {
144 bind_debug_global();
145
146 Self {
147 uart_mux,
148 marker: core::marker::PhantomData,
149 capability,
150 }
151 }
152}
153
154pub struct Capability;
155unsafe impl capabilities::ProcessManagementCapability for Capability {}
156
157impl<const BUF_SIZE_BYTES: usize, C: SetDebugWriterCapability> Component
158 for DebugWriterComponent<BUF_SIZE_BYTES, C>
159{
160 type StaticInput = (
161 &'static mut MaybeUninit<UartDevice<'static>>,
162 &'static mut MaybeUninit<RingBuffer<'static, u8>>,
163 &'static mut MaybeUninit<[u8; BUF_SIZE_BYTES]>,
164 &'static mut MaybeUninit<UartDebugWriter>,
165 );
166 type Output = ();
167
168 fn finalize(self, s: Self::StaticInput) -> Self::Output {
169 let buf = s.2.write([0; BUF_SIZE_BYTES]);
170
171 let (output_buf, internal_buf) = buf.split_at_mut(DEBUG_BUFFER_SPLIT);
172
173 let debugger_uart = s.0.write(UartDevice::new(self.uart_mux, false));
175 debugger_uart.setup();
176 let ring_buffer = s.1.write(RingBuffer::new(internal_buf));
177 let debugger =
178 s.3.write(UartDebugWriter::new(debugger_uart, output_buf, ring_buffer));
179 hil::uart::Transmit::set_transmit_client(debugger_uart, debugger);
180
181 kernel::debug::set_debug_writer_wrapper(debugger, self.capability);
182 }
183}
184
185#[allow(dead_code)]
187pub struct DebugWriterNoMuxComponent<
188 U: uart::Uart<'static> + uart::Transmit<'static> + 'static,
189 const BUF_SIZE_BYTES: usize,
190 C: SetDebugWriterCapability,
191> {
192 uart: &'static U,
193 marker: core::marker::PhantomData<[u8; BUF_SIZE_BYTES]>,
194 capability: C,
195}
196
197impl<
198 U: uart::Uart<'static> + uart::Transmit<'static> + 'static,
199 const BUF_SIZE_BYTES: usize,
200 C: SetDebugWriterCapability,
201 > DebugWriterNoMuxComponent<U, BUF_SIZE_BYTES, C>
202{
203 pub fn new(uart: &'static U, capability: C) -> Self {
204 Self {
205 uart,
206 marker: core::marker::PhantomData,
207 capability,
208 }
209 }
210}
211
212impl<
213 U: uart::Uart<'static> + uart::Transmit<'static> + 'static,
214 const BUF_SIZE_BYTES: usize,
215 C: SetDebugWriterCapability,
216 > Component for DebugWriterNoMuxComponent<U, BUF_SIZE_BYTES, C>
217{
218 type StaticInput = (
219 &'static mut MaybeUninit<RingBuffer<'static, u8>>,
220 &'static mut MaybeUninit<[u8; BUF_SIZE_BYTES]>,
221 &'static mut MaybeUninit<UartDebugWriter>,
222 );
223 type Output = ();
224
225 fn finalize(self, s: Self::StaticInput) -> Self::Output {
226 let buf = s.1.write([0; BUF_SIZE_BYTES]);
227 let (output_buf, internal_buf) = buf.split_at_mut(DEBUG_BUFFER_SPLIT);
228
229 let ring_buffer = s.0.write(RingBuffer::new(internal_buf));
231 let debugger =
232 s.2.write(UartDebugWriter::new(self.uart, output_buf, ring_buffer));
233 hil::uart::Transmit::set_transmit_client(self.uart, debugger);
234
235 kernel::debug::set_debug_writer_wrapper(debugger, self.capability);
236
237 let _ = self.uart.configure(uart::Parameters {
238 baud_rate: 115200,
239 width: uart::Width::Eight,
240 stop_bits: uart::StopBits::One,
241 parity: uart::Parity::None,
242 hw_flow_control: false,
243 });
244 }
245}