Skip to content
This repository was archived by the owner on May 18, 2022. It is now read-only.

Commit 4a901dc

Browse files
Send logging output through a BBQueue
This makes logging quite a bit faster, so we have a chance of hitting the T_IFS timing properly now. Note that logging still is really slow (125µs for a short message), so this might not help that much.
1 parent c26f239 commit 4a901dc

3 files changed

Lines changed: 58 additions & 8 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ panic-semihosting = "0.5.1"
2323
bitflags = "1.0.4"
2424
uuid = { version = "0.7.2", default-features = false }
2525
ux = { version = "0.1.3", default-features = false }
26+
bbqueue = "0.3.2"
2627

2728
[profile.dev]
2829
opt-level = "s"

src/logger.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use {crate::ble::time::Timer, core::fmt};
1+
use {crate::ble::time::Timer, bbqueue::Producer, core::fmt};
22

33
/// A `fmt::Write` adapter that prints a timestamp before each line.
44
pub struct StampedLogger<T: Timer, L: fmt::Write> {
@@ -27,3 +27,33 @@ impl<T: Timer, L: fmt::Write> fmt::Write for StampedLogger<T, L> {
2727
Ok(())
2828
}
2929
}
30+
31+
/// A `fmt::Write` sink that writes to a `BBQueue`.
32+
///
33+
/// The sink will panic when the `BBQueue` doesn't have enough space to the data. This is to ensure
34+
/// that we never block or drop data.
35+
pub struct BbqLogger {
36+
p: Producer,
37+
}
38+
39+
impl BbqLogger {
40+
pub fn new(p: Producer) -> Self {
41+
Self { p }
42+
}
43+
}
44+
45+
impl fmt::Write for BbqLogger {
46+
fn write_str(&mut self, s: &str) -> fmt::Result {
47+
let mut bytes = s.as_bytes();
48+
49+
while !bytes.is_empty() {
50+
let mut grant = self.p.grant_max(bytes.len()).expect("log buffer overflow");
51+
let size = grant.buf().len();
52+
grant.buf().copy_from_slice(&bytes[..size]);
53+
bytes = &bytes[size..];
54+
self.p.commit(size, grant);
55+
}
56+
57+
Ok(())
58+
}
59+
}

src/main.rs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ use {
1818
},
1919
time::{Duration, Timer},
2020
},
21-
logger::StampedLogger,
21+
logger::{BbqLogger, StampedLogger},
2222
radio::{BleRadio, PacketBuffer},
2323
timer::BleTimer,
2424
},
25+
bbqueue::{bbq, BBQueue, Consumer},
2526
byteorder::{ByteOrder, LittleEndian},
2627
core::fmt::Write,
2728
cortex_m_semihosting::hprintln,
@@ -35,7 +36,7 @@ use {
3536
rtfm::app,
3637
};
3738

38-
type Logger = StampedLogger<timer::StampSource<pac::TIMER0>, Uarte<UARTE0>>;
39+
type Logger = StampedLogger<timer::StampSource<pac::TIMER0>, BbqLogger>;
3940

4041
/// Whether to broadcast a beacon or to establish a proper connection.
4142
///
@@ -51,6 +52,8 @@ const APP: () = {
5152
static mut RADIO: BleRadio = ();
5253
static mut BEACON: Beacon = ();
5354
static mut BEACON_TIMER: pac::TIMER1 = ();
55+
static mut SERIAL: Uarte<UARTE0> = ();
56+
static mut LOG_SINK: Consumer = ();
5457

5558
#[init(resources = [BLE_TX_BUF, BLE_RX_BUF])]
5659
fn init() {
@@ -133,11 +136,11 @@ const APP: () = {
133136
.unwrap();
134137

135138
let log_stamper = ble_timer.create_stamp_source();
136-
let mut ll = LinkLayer::with_logger(
137-
device_address,
138-
ble_timer,
139-
StampedLogger::new(serial, log_stamper),
140-
);
139+
let logq = bbq!(2048).unwrap();
140+
let (tx, rx) = logq.split();
141+
let logger = StampedLogger::new(BbqLogger::new(tx), log_stamper);
142+
143+
let mut ll = LinkLayer::with_logger(device_address, ble_timer, logger);
141144

142145
if !TEST_BEACON {
143146
// Send advertisement and set up regular interrupt
@@ -155,6 +158,8 @@ const APP: () = {
155158
BLE = ll;
156159
BEACON = beacon;
157160
BEACON_TIMER = device.TIMER1;
161+
SERIAL = serial;
162+
LOG_SINK = rx;
158163
}
159164

160165
#[interrupt(resources = [RADIO, BLE])]
@@ -187,4 +192,18 @@ const APP: () = {
187192

188193
resources.BEACON.broadcast(&mut *resources.RADIO);
189194
}
195+
196+
#[idle(resources = [LOG_SINK, SERIAL])]
197+
fn idle() -> ! {
198+
// Drain the logging buffer through the serial connection
199+
loop {
200+
if let Ok(grant) = resources.LOG_SINK.read() {
201+
for chunk in grant.buf().chunks(255) {
202+
resources.SERIAL.write(chunk).unwrap();
203+
}
204+
205+
resources.LOG_SINK.release(grant.buf().len(), grant);
206+
}
207+
}
208+
}
190209
};

0 commit comments

Comments
 (0)