components/
debug_writer.rs
1use capsules_core::virtualizers::virtual_uart::{MuxUart, UartDevice};
31use core::mem::MaybeUninit;
32use kernel::capabilities;
33use kernel::capabilities::SetDebugWriterCapability;
34use kernel::collections::ring_buffer::RingBuffer;
35use kernel::component::Component;
36use kernel::hil;
37use kernel::hil::uart;
38
39pub const DEFAULT_DEBUG_BUFFER_KBYTE: usize = 2;
45
46const DEBUG_BUFFER_SPLIT: usize = 64;
49
50#[macro_export]
56macro_rules! debug_writer_component_static {
57 ($BUF_SIZE_KB:expr) => {{
58 let uart = kernel::static_buf!(capsules_core::virtualizers::virtual_uart::UartDevice);
59 let ring = kernel::static_buf!(kernel::collections::ring_buffer::RingBuffer<'static, u8>);
60 let buffer = kernel::static_buf!([u8; 1024 * $BUF_SIZE_KB]);
61 let debug = kernel::static_buf!(kernel::debug::DebugWriter);
62 let debug_wrapper = kernel::static_buf!(kernel::debug::DebugWriterWrapper);
63
64 (uart, ring, buffer, debug, debug_wrapper)
65 };};
66 () => {{
67 $crate::debug_writer_component_static!($crate::debug_writer::DEFAULT_DEBUG_BUFFER_KBYTE)
68 };};
69}
70
71#[macro_export]
77macro_rules! debug_writer_no_mux_component_static {
78 ($BUF_SIZE_KB:expr) => {{
79 let ring = kernel::static_buf!(kernel::collections::ring_buffer::RingBuffer<'static, u8>);
80 let buffer = kernel::static_buf!([u8; 1024 * $BUF_SIZE_KB]);
81 let debug = kernel::static_buf!(kernel::debug::DebugWriter);
82 let debug_wrapper = kernel::static_buf!(kernel::debug::DebugWriterWrapper);
83
84 (ring, buffer, debug, debug_wrapper)
85 };};
86 () => {{
87 use $crate::debug_writer::DEFAULT_DEBUG_BUFFER_KBYTE;
88 $crate::debug_writer_no_mux_component_static!(DEFAULT_DEBUG_BUFFER_KBYTE)
89 };};
90}
91
92pub struct DebugWriterComponent<const BUF_SIZE_BYTES: usize, C: SetDebugWriterCapability> {
93 uart_mux: &'static MuxUart<'static>,
94 marker: core::marker::PhantomData<[u8; BUF_SIZE_BYTES]>,
95 capability: C,
96}
97
98impl<const BUF_SIZE_BYTES: usize, C: SetDebugWriterCapability>
99 DebugWriterComponent<BUF_SIZE_BYTES, C>
100{
101 pub fn new(uart_mux: &'static MuxUart, capability: C) -> Self {
102 Self {
103 uart_mux,
104 marker: core::marker::PhantomData,
105 capability,
106 }
107 }
108}
109
110pub struct Capability;
111unsafe impl capabilities::ProcessManagementCapability for Capability {}
112
113impl<const BUF_SIZE_BYTES: usize, C: SetDebugWriterCapability> Component
114 for DebugWriterComponent<BUF_SIZE_BYTES, C>
115{
116 type StaticInput = (
117 &'static mut MaybeUninit<UartDevice<'static>>,
118 &'static mut MaybeUninit<RingBuffer<'static, u8>>,
119 &'static mut MaybeUninit<[u8; BUF_SIZE_BYTES]>,
120 &'static mut MaybeUninit<kernel::debug::DebugWriter>,
121 &'static mut MaybeUninit<kernel::debug::DebugWriterWrapper>,
122 );
123 type Output = ();
124
125 fn finalize(self, s: Self::StaticInput) -> Self::Output {
126 let buf = s.2.write([0; BUF_SIZE_BYTES]);
127
128 let (output_buf, internal_buf) = buf.split_at_mut(DEBUG_BUFFER_SPLIT);
129
130 let debugger_uart = s.0.write(UartDevice::new(self.uart_mux, false));
132 debugger_uart.setup();
133 let ring_buffer = s.1.write(RingBuffer::new(internal_buf));
134 let debugger = s.3.write(kernel::debug::DebugWriter::new(
135 debugger_uart,
136 output_buf,
137 ring_buffer,
138 ));
139 hil::uart::Transmit::set_transmit_client(debugger_uart, debugger);
140
141 let debug_wrapper = s.4.write(kernel::debug::DebugWriterWrapper::new(debugger));
142 kernel::debug::set_debug_writer_wrapper(debug_wrapper, self.capability);
143 }
144}
145
146pub struct DebugWriterNoMuxComponent<
147 U: uart::Uart<'static> + uart::Transmit<'static> + 'static,
148 const BUF_SIZE_BYTES: usize,
149 C: SetDebugWriterCapability,
150> {
151 uart: &'static U,
152 marker: core::marker::PhantomData<[u8; BUF_SIZE_BYTES]>,
153 capability: C,
154}
155
156impl<
157 U: uart::Uart<'static> + uart::Transmit<'static> + 'static,
158 const BUF_SIZE_BYTES: usize,
159 C: SetDebugWriterCapability,
160 > DebugWriterNoMuxComponent<U, BUF_SIZE_BYTES, C>
161{
162 pub fn new(uart: &'static U, capability: C) -> Self {
163 Self {
164 uart,
165 marker: core::marker::PhantomData,
166 capability,
167 }
168 }
169}
170
171impl<
172 U: uart::Uart<'static> + uart::Transmit<'static> + 'static,
173 const BUF_SIZE_BYTES: usize,
174 C: SetDebugWriterCapability,
175 > Component for DebugWriterNoMuxComponent<U, BUF_SIZE_BYTES, C>
176{
177 type StaticInput = (
178 &'static mut MaybeUninit<RingBuffer<'static, u8>>,
179 &'static mut MaybeUninit<[u8; BUF_SIZE_BYTES]>,
180 &'static mut MaybeUninit<kernel::debug::DebugWriter>,
181 &'static mut MaybeUninit<kernel::debug::DebugWriterWrapper>,
182 );
183 type Output = ();
184
185 fn finalize(self, s: Self::StaticInput) -> Self::Output {
186 let buf = s.1.write([0; BUF_SIZE_BYTES]);
187 let (output_buf, internal_buf) = buf.split_at_mut(DEBUG_BUFFER_SPLIT);
188
189 let ring_buffer = s.0.write(RingBuffer::new(internal_buf));
191 let debugger = s.2.write(kernel::debug::DebugWriter::new(
192 self.uart,
193 output_buf,
194 ring_buffer,
195 ));
196 hil::uart::Transmit::set_transmit_client(self.uart, debugger);
197
198 let debug_wrapper = s.3.write(kernel::debug::DebugWriterWrapper::new(debugger));
199 kernel::debug::set_debug_writer_wrapper(debug_wrapper, self.capability);
200
201 let _ = self.uart.configure(uart::Parameters {
202 baud_rate: 115200,
203 width: uart::Width::Eight,
204 stop_bits: uart::StopBits::One,
205 parity: uart::Parity::None,
206 hw_flow_control: false,
207 });
208 }
209}