Skip to content

Commit 03d36e2

Browse files
Send data loss events
1 parent 42fbe45 commit 03d36e2

2 files changed

Lines changed: 89 additions & 17 deletions

File tree

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,53 @@
1-
use core::sync::atomic::Ordering;
2-
31
use crate::cortex::rtt_minimal::rtt_write_core;
2+
use core::sync::atomic::Ordering;
3+
use rustmeter_beacon_core::{protocol::raw_writers::event_ids, time_delta::TimeDelta};
44

5-
// TODO: Move Dropped Events Counter to rtt_minimal::rtt_write_core and core-specific dropped counters
6-
static DROPPED_EVENTS_COUNTER: portable_atomic::AtomicU32 = portable_atomic::AtomicU32::new(0);
5+
// static mut okay because accessed in critical section
6+
static mut DROPPED_EVENTS_COUNTER: [u32; 2] = [0, 0];
77

88
#[unsafe(no_mangle)]
9-
// #[unsafe(link_section = ".iram1")] ESP32
109
#[unsafe(link_section = ".data")]
1110
fn write_tracing_data(data: &[u8]) {
1211
let core_id = crate::core_id::get_current_core_id() as usize;
1312
let idx = if core_id > 1 { 0 } else { core_id as usize };
1413

1514
// Write to Buffer
1615
cortex_m::interrupt::free(|_| {
17-
let written = rtt_write_core(idx, data);
18-
if written.is_none() {
19-
DROPPED_EVENTS_COUNTER.fetch_add(1, Ordering::Relaxed);
16+
// Check for dropped events
17+
let dropped_events = unsafe { DROPPED_EVENTS_COUNTER[idx] };
18+
if dropped_events > 0 {
19+
// Create dropped events event
20+
let mut buffer = [0u8; 12];
21+
buffer[0] = event_ids::DATA_LOSS_EVENT << 3;
22+
buffer[1..5].copy_from_slice(&dropped_events.to_le_bytes());
23+
let timestamp = TimeDelta::from_now();
24+
let pos = timestamp.write_bytes_mut(&mut buffer[5..]);
25+
26+
// Try to write dropped events data
27+
match rtt_write_core(idx, &buffer[..5 + pos]) {
28+
Some(_) => {
29+
// Successfully written, reset counter
30+
unsafe {
31+
DROPPED_EVENTS_COUNTER[idx] = 0;
32+
}
33+
}
34+
None => {
35+
// Still cannot write, increment counter
36+
unsafe {
37+
DROPPED_EVENTS_COUNTER[idx] += 1;
38+
}
39+
}
40+
}
41+
42+
// do not send actual data this round because we took TimeDelta::now() and it would be inconsistent
43+
} else {
44+
// No dropped events, try to write actual data
45+
let written = rtt_write_core(idx, data);
46+
if written.is_none() {
47+
unsafe {
48+
DROPPED_EVENTS_COUNTER[idx] += 1;
49+
}
50+
}
2051
}
2152
});
2253
}

rustmeter-beacon/rustmeter-beacon-target/src/espressif/tracing_esp.rs

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,18 @@ use embassy_sync::{
1111
blocking_mutex::{Mutex, raw::CriticalSectionRawMutex},
1212
pipe::{Pipe, TryWriteError},
1313
};
14-
use rustmeter_beacon_core::{buffer::BufferWriter, protocol::EventPayload, time_delta::TimeDelta};
14+
use rustmeter_beacon_core::{
15+
buffer::BufferWriter,
16+
protocol::{EventPayload, raw_writers::event_ids},
17+
time_delta::TimeDelta,
18+
};
1519

1620
use crate::{
17-
NUM_CORES, espressif::local_critical_section::{enter_local_critical_section, exit_local_critical_section}, ringbuffer::{AtomicRingBuffer, SimpleRingBuffer}
21+
NUM_CORES,
22+
espressif::local_critical_section::{
23+
enter_local_critical_section, exit_local_critical_section,
24+
},
25+
ringbuffer::{AtomicRingBuffer, SimpleRingBuffer},
1826
};
1927

2028
const BUFFER_SIZE: usize = 4096;
@@ -28,7 +36,8 @@ static TRACE_BUFFERS: [PerCoreSync<AtomicRingBuffer<BUFFER_SIZE>>; NUM_CORES] =
2836
static NEW_DATA_SIGNAL: embassy_sync::signal::Signal<CriticalSectionRawMutex, ()> =
2937
embassy_sync::signal::Signal::new();
3038

31-
static DROPPED_EVENTS_COUNTER: portable_atomic::AtomicU32 = portable_atomic::AtomicU32::new(0);
39+
// static mut okay because accessed in critical section
40+
static mut DROPPED_EVENTS_COUNTER: [u32; 2] = [0, 0];
3241

3342
pub fn get_tracing_buffers_and_signaller() -> (
3443
&'static [PerCoreSync<AtomicRingBuffer<BUFFER_SIZE>>; NUM_CORES],
@@ -45,15 +54,47 @@ fn write_tracing_data(data: &[u8]) {
4554

4655
// Enter local critical section
4756
let prev_interrupt_state = enter_local_critical_section();
48-
49-
// Write to Buffer
5057
let buf = unsafe { &mut *TRACE_BUFFERS[core_id].get() };
51-
if let Some(free) = buf.push_slice_fast(data) {
52-
if free < (buf.capacity() * 3 / 4) {
53-
NEW_DATA_SIGNAL.signal(());
58+
59+
let dropped_events = unsafe { DROPPED_EVENTS_COUNTER[idx] };
60+
if dropped_events > 0 {
61+
// Create dropped events event
62+
let mut buffer = [0u8; 12];
63+
buffer[0] = event_ids::DATA_LOSS_EVENT << 3;
64+
buffer[1..5].copy_from_slice(&dropped_events.to_le_bytes());
65+
let timestamp = TimeDelta::from_now();
66+
let pos = timestamp.write_bytes_mut(&mut buffer[5..]);
67+
68+
// Try to write dropped events data
69+
match buf.push_slice_fast(&buffer[..5 + pos]) {
70+
Some(_) => {
71+
// Successfully written, reset counter
72+
unsafe {
73+
DROPPED_EVENTS_COUNTER[idx] = 0;
74+
}
75+
}
76+
None => {
77+
// Still cannot write, increment counter
78+
unsafe {
79+
DROPPED_EVENTS_COUNTER[idx] += 1;
80+
}
81+
}
5482
}
83+
84+
NEW_DATA_SIGNAL.signal(()); // signal because we added data
85+
86+
// do not send actual data this round because we took TimeDelta::now() and it would be inconsistent
5587
} else {
56-
DROPPED_EVENTS_COUNTER.fetch_add(1, Ordering::Relaxed);
88+
// write actual data
89+
if let Some(free) = buf.push_slice_fast(data) {
90+
if free < (buf.capacity() * 3 / 4) {
91+
NEW_DATA_SIGNAL.signal(()); // signal when buffer is less than 75% free <=> 25% used
92+
}
93+
} else {
94+
unsafe {
95+
DROPPED_EVENTS_COUNTER[idx] += 1;
96+
}
97+
}
5798
}
5899

59100
// Exit local critical section

0 commit comments

Comments
 (0)