components/
segger_rtt.rs
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 pub rtt_memory: &'a mut SeggerRttMemory<'a>,
66}
67
68pub struct SeggerRttMemoryComponent {}
69
70impl SeggerRttMemoryComponent {
71 pub fn new() -> SeggerRttMemoryComponent {
72 SeggerRttMemoryComponent {}
73 }
74}
75
76impl Component for SeggerRttMemoryComponent {
77 type StaticInput = (
78 &'static mut MaybeUninit<SeggerRttMemory<'static>>,
79 &'static mut MaybeUninit<[VolatileCell<u8>; segger::rtt::DEFAULT_UP_BUFFER_LENGTH]>,
80 &'static mut MaybeUninit<[VolatileCell<u8>; segger::rtt::DEFAULT_DOWN_BUFFER_LENGTH]>,
81 );
82 type Output = SeggerRttMemoryRefs<'static>;
83
84 fn finalize(self, s: Self::StaticInput) -> Self::Output {
85 let name = b"Terminal\0";
86 let up_buffer_name = name;
87 let down_buffer_name = name;
88 let up_buffer =
89 s.1.write([const { VolatileCell::new(0) }; segger::rtt::DEFAULT_UP_BUFFER_LENGTH]);
90 let down_buffer =
91 s.2.write([const { VolatileCell::new(0) }; segger::rtt::DEFAULT_DOWN_BUFFER_LENGTH]);
92
93 let rtt_memory = s.0.write(SeggerRttMemory::new_raw(
94 up_buffer_name,
95 up_buffer,
96 down_buffer_name,
97 down_buffer,
98 ));
99 SeggerRttMemoryRefs { rtt_memory }
100 }
101}
102
103pub struct SeggerRttComponent<A: 'static + time::Alarm<'static>> {
104 mux_alarm: &'static MuxAlarm<'static, A>,
105 rtt_memory_refs: SeggerRttMemoryRefs<'static>,
106}
107
108impl<A: 'static + time::Alarm<'static>> SeggerRttComponent<A> {
109 pub fn new(
110 mux_alarm: &'static MuxAlarm<'static, A>,
111 rtt_memory_refs: SeggerRttMemoryRefs<'static>,
112 ) -> SeggerRttComponent<A> {
113 SeggerRttComponent {
114 mux_alarm,
115 rtt_memory_refs,
116 }
117 }
118}
119
120impl<A: 'static + time::Alarm<'static>> Component for SeggerRttComponent<A> {
121 type StaticInput = (
122 &'static mut MaybeUninit<VirtualMuxAlarm<'static, A>>,
123 &'static mut MaybeUninit<SeggerRtt<'static, VirtualMuxAlarm<'static, A>>>,
124 );
125 type Output = &'static SeggerRtt<'static, VirtualMuxAlarm<'static, A>>;
126
127 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
128 let virtual_alarm_rtt = static_buffer.0.write(VirtualMuxAlarm::new(self.mux_alarm));
129 virtual_alarm_rtt.setup();
130
131 let rtt = static_buffer.1.write(SeggerRtt::new(
133 virtual_alarm_rtt,
134 self.rtt_memory_refs.rtt_memory,
135 ));
136
137 virtual_alarm_rtt.set_alarm_client(rtt);
138
139 rtt
140 }
141}