1use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
25use core::mem::MaybeUninit;
26use kernel::component::Component;
27use kernel::hil::time::{self, Alarm};
28use kernel::utilities::cells::VolatileCell;
29use segger::rtt::{SeggerRtt, SeggerRttMemory};
30
31#[macro_export]
33macro_rules! segger_rtt_memory_component_static {
34 () => {{
35 let rtt_memory = kernel::static_named_buf!(segger::rtt::SeggerRttMemory, "_SEGGER_RTT");
36 let up_buffer = kernel::static_buf!(
37 [kernel::utilities::cells::VolatileCell<u8>; segger::rtt::DEFAULT_UP_BUFFER_LENGTH]
38 );
39 let down_buffer = kernel::static_buf!(
40 [kernel::utilities::cells::VolatileCell<u8>; segger::rtt::DEFAULT_DOWN_BUFFER_LENGTH]
41 );
42
43 (rtt_memory, up_buffer, down_buffer)
44 };};
45}
46
47#[macro_export]
48macro_rules! segger_rtt_component_static {
49 ($A:ty $(,)?) => {{
50 let alarm = kernel::static_buf!(
51 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>
52 );
53 let rtt = kernel::static_buf!(
54 segger::rtt::SeggerRtt<
55 'static,
56 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>,
57 >
58 );
59
60 (alarm, rtt)
61 };};
62}
63
64pub struct SeggerRttMemoryRefs<'a> {
65 rtt_memory: &'a mut SeggerRttMemory<'a>,
66}
67
68impl<'a> SeggerRttMemoryRefs<'a> {
69 pub unsafe fn get_rtt_memory_ptr(&mut self) -> *mut SeggerRttMemory<'a> {
70 core::ptr::from_mut(self.rtt_memory)
71 }
72}
73
74pub struct SeggerRttMemoryComponent {}
75
76impl SeggerRttMemoryComponent {
77 pub fn new() -> SeggerRttMemoryComponent {
78 SeggerRttMemoryComponent {}
79 }
80}
81
82impl Component for SeggerRttMemoryComponent {
83 type StaticInput = (
84 &'static mut MaybeUninit<SeggerRttMemory<'static>>,
85 &'static mut MaybeUninit<[VolatileCell<u8>; segger::rtt::DEFAULT_UP_BUFFER_LENGTH]>,
86 &'static mut MaybeUninit<[VolatileCell<u8>; segger::rtt::DEFAULT_DOWN_BUFFER_LENGTH]>,
87 );
88 type Output = SeggerRttMemoryRefs<'static>;
89
90 fn finalize(self, s: Self::StaticInput) -> Self::Output {
91 let name = b"Terminal\0";
92 let up_buffer_name = name;
93 let down_buffer_name = name;
94 let up_buffer =
95 s.1.write([const { VolatileCell::new(0) }; segger::rtt::DEFAULT_UP_BUFFER_LENGTH]);
96 let down_buffer =
97 s.2.write([const { VolatileCell::new(0) }; segger::rtt::DEFAULT_DOWN_BUFFER_LENGTH]);
98
99 let rtt_memory = s.0.write(SeggerRttMemory::new_raw(
100 up_buffer_name,
101 up_buffer,
102 down_buffer_name,
103 down_buffer,
104 ));
105 SeggerRttMemoryRefs { rtt_memory }
106 }
107}
108
109pub struct SeggerRttComponent<A: 'static + time::Alarm<'static>> {
110 mux_alarm: &'static MuxAlarm<'static, A>,
111 rtt_memory_refs: SeggerRttMemoryRefs<'static>,
112}
113
114impl<A: 'static + time::Alarm<'static>> SeggerRttComponent<A> {
115 pub fn new(
116 mux_alarm: &'static MuxAlarm<'static, A>,
117 rtt_memory_refs: SeggerRttMemoryRefs<'static>,
118 ) -> SeggerRttComponent<A> {
119 SeggerRttComponent {
120 mux_alarm,
121 rtt_memory_refs,
122 }
123 }
124}
125
126impl<A: 'static + time::Alarm<'static>> Component for SeggerRttComponent<A> {
127 type StaticInput = (
128 &'static mut MaybeUninit<VirtualMuxAlarm<'static, A>>,
129 &'static mut MaybeUninit<SeggerRtt<'static, VirtualMuxAlarm<'static, A>>>,
130 );
131 type Output = &'static SeggerRtt<'static, VirtualMuxAlarm<'static, A>>;
132
133 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
134 let virtual_alarm_rtt = static_buffer.0.write(VirtualMuxAlarm::new(self.mux_alarm));
135 virtual_alarm_rtt.setup();
136
137 let rtt = static_buffer.1.write(SeggerRtt::new(
139 virtual_alarm_rtt,
140 self.rtt_memory_refs.rtt_memory,
141 ));
142
143 virtual_alarm_rtt.set_alarm_client(rtt);
144
145 rtt
146 }
147}