1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#![no_std]
mod channel;
use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use cortex_m::{interrupt, register};
use crate::channel::Channel;
#[defmt::global_logger]
struct Logger;
static TAKEN: AtomicBool = AtomicBool::new(false);
static INTERRUPTS_ACTIVE: AtomicBool = AtomicBool::new(false);
static mut ENCODER: defmt::Encoder = defmt::Encoder::new();
unsafe impl defmt::Logger for Logger {
fn acquire() {
let primask = register::primask::read();
interrupt::disable();
if TAKEN.load(Ordering::Relaxed) {
panic!("defmt logger taken reentrantly")
}
TAKEN.store(true, Ordering::Relaxed);
INTERRUPTS_ACTIVE.store(primask.is_active(), Ordering::Relaxed);
unsafe { ENCODER.start_frame(do_write) }
}
unsafe fn flush() {
handle().flush();
}
unsafe fn release() {
ENCODER.end_frame(do_write);
TAKEN.store(false, Ordering::Relaxed);
if INTERRUPTS_ACTIVE.load(Ordering::Relaxed) {
interrupt::enable()
}
}
unsafe fn write(bytes: &[u8]) {
ENCODER.write(bytes, do_write);
}
}
fn do_write(bytes: &[u8]) {
unsafe { handle().write_all(bytes) }
}
#[repr(C)]
struct Header {
id: [u8; 16],
max_up_channels: usize,
max_down_channels: usize,
up_channel: Channel,
}
const MODE_MASK: usize = 0b11;
const MODE_BLOCK_IF_FULL: usize = 2;
const MODE_NON_BLOCKING_TRIM: usize = 1;
const SIZE: usize = 1024;
unsafe fn handle() -> &'static Channel {
#[no_mangle]
static mut _SEGGER_RTT: Header = Header {
id: *b"SEGGER RTT\0\0\0\0\0\0",
max_up_channels: 1,
max_down_channels: 0,
up_channel: Channel {
name: NAME as *const _ as *const u8,
buffer: unsafe { &mut BUFFER as *mut _ as *mut u8 },
size: SIZE,
write: AtomicUsize::new(0),
read: AtomicUsize::new(0),
flags: AtomicUsize::new(MODE_NON_BLOCKING_TRIM),
},
};
#[cfg_attr(target_os = "macos", link_section = ".uninit,defmt-rtt.BUFFER")]
#[cfg_attr(not(target_os = "macos"), link_section = ".uninit.defmt-rtt.BUFFER")]
static mut BUFFER: [u8; SIZE] = [0; SIZE];
static NAME: &[u8] = b"defmt\0";
&_SEGGER_RTT.up_channel
}