@@ -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
1620use 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
2028const BUFFER_SIZE : usize = 4096 ;
@@ -28,7 +36,8 @@ static TRACE_BUFFERS: [PerCoreSync<AtomicRingBuffer<BUFFER_SIZE>>; NUM_CORES] =
2836static 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
3342pub 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