Skip to content

Commit

Permalink
Merge #633
Browse files Browse the repository at this point in the history
633: fix #628 r=jonas-schievink a=spookyvision

open questions:

also make this honor the env var?
```rust
// print/src/main.rs:28
const READ_BUFFER_SIZE: usize = 1024;
```
(answered: no, irrelevant)

---

add some hints in the app template?
(answered: yes)

Co-authored-by: Anatol Ulrich <anatol.ulrich@ferrous-systems.com>
Co-authored-by: Jonas Schievink <jonas.schievink@ferrous-systems.com>
  • Loading branch information
3 people authored Nov 25, 2021
2 parents e4d0149 + b441edb commit 964c8e7
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 17 deletions.
4 changes: 4 additions & 0 deletions firmware/defmt-rtt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ The fastest way to get started with `defmt` is to use our [app-template] to set

For more details about the framework check the book at https://defmt.ferrous-systems.com

## Customization

The RTT buffer size (default: 1024) can be configured with the `DEFMT_RTT_BUFFER_SIZE` environment variable in a tight memory situation. Use a power of 2 for best performance.

## Support

`defmt-rtt` is part of the [Knurling] project, [Ferrous Systems]' effort at
Expand Down
21 changes: 21 additions & 0 deletions firmware/defmt-rtt/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use std::{env, path::PathBuf};

fn main() {
println!("cargo:rerun-if-env-changed=DEFMT_RTT_BUFFER_SIZE");

let size = env::var("DEFMT_RTT_BUFFER_SIZE")
.map(|s| {
s.parse()
.expect("could not parse DEFMT_RTT_BUFFER_SIZE as usize")
})
.unwrap_or(1024_usize);

let out_dir_path = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let out_file_path = out_dir_path.join("consts.rs");

std::fs::write(
out_file_path,
format!("pub(crate) const BUF_SIZE: usize = {};", size),
)
.unwrap();
}
22 changes: 11 additions & 11 deletions firmware/defmt-rtt/src/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use core::{
sync::atomic::{AtomicUsize, Ordering},
};

use crate::{MODE_BLOCK_IF_FULL, MODE_MASK, SIZE};
use crate::{consts::BUF_SIZE, MODE_BLOCK_IF_FULL, MODE_MASK};

#[repr(C)]
pub(crate) struct Channel {
Expand Down Expand Up @@ -45,9 +45,9 @@ impl Channel {
let available = if read > write {
read - write - 1
} else if read == 0 {
SIZE - write - 1
BUF_SIZE - write - 1
} else {
SIZE - write
BUF_SIZE - write
};

if available == 0 {
Expand All @@ -58,9 +58,9 @@ impl Channel {
let len = bytes.len().min(available);

unsafe {
if cursor + len > SIZE {
if cursor + len > BUF_SIZE {
// split memcpy
let pivot = SIZE - cursor;
let pivot = BUF_SIZE - cursor;
ptr::copy_nonoverlapping(bytes.as_ptr(), self.buffer.add(cursor), pivot);
ptr::copy_nonoverlapping(bytes.as_ptr().add(pivot), self.buffer, len - pivot);
} else {
Expand All @@ -69,21 +69,21 @@ impl Channel {
}
}
self.write
.store(write.wrapping_add(len) % SIZE, Ordering::Release);
.store(write.wrapping_add(len) % BUF_SIZE, Ordering::Release);

len
}

fn nonblocking_write(&self, bytes: &[u8]) -> usize {
let write = self.write.load(Ordering::Acquire);
let cursor = write;
// NOTE truncate at SIZE to avoid more than one "wrap-around" in a single `write` call
let len = bytes.len().min(SIZE);
// NOTE truncate atBUF_SIZE to avoid more than one "wrap-around" in a single `write` call
let len = bytes.len().min(BUF_SIZE);

unsafe {
if cursor + len > SIZE {
if cursor + len > BUF_SIZE {
// split memcpy
let pivot = SIZE - cursor;
let pivot = BUF_SIZE - cursor;
ptr::copy_nonoverlapping(bytes.as_ptr(), self.buffer.add(cursor), pivot);
ptr::copy_nonoverlapping(bytes.as_ptr().add(pivot), self.buffer, len - pivot);
} else {
Expand All @@ -92,7 +92,7 @@ impl Channel {
}
}
self.write
.store(write.wrapping_add(len) % SIZE, Ordering::Release);
.store(write.wrapping_add(len) % BUF_SIZE, Ordering::Release);

len
}
Expand Down
2 changes: 2 additions & 0 deletions firmware/defmt-rtt/src/consts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// see `build.rs` for contents
include!(concat!(env!("OUT_DIR"), "/consts.rs"));
14 changes: 8 additions & 6 deletions firmware/defmt-rtt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ use cortex_m::{interrupt, register};

use crate::channel::Channel;

mod consts;

/// RTT buffer size. Default: 1024; can be customized by setting the `DEFMT_RTT_BUFFER_SIZE` environment variable.
/// Use a power of 2 for best performance.
use crate::consts::BUF_SIZE;

#[defmt::global_logger]
struct Logger;

Expand Down Expand Up @@ -94,10 +100,6 @@ const MODE_BLOCK_IF_FULL: usize = 2;
/// Don't block if the RTT buffer is full. Truncate data to output as much as fits.
const MODE_NON_BLOCKING_TRIM: usize = 1;

// TODO make configurable
// NOTE use a power of 2 for best performance
const SIZE: usize = 1024;

// make sure we only get shared references to the header/channel (avoid UB)
/// # Safety
/// `Channel` API is not re-entrant; this handle should not be held from different execution
Expand All @@ -115,7 +117,7 @@ unsafe fn handle() -> &'static Channel {
up_channel: Channel {
name: NAME as *const _ as *const u8,
buffer: unsafe { &mut BUFFER as *mut _ as *mut u8 },
size: SIZE,
size: BUF_SIZE,
write: AtomicUsize::new(0),
read: AtomicUsize::new(0),
flags: AtomicUsize::new(MODE_NON_BLOCKING_TRIM),
Expand All @@ -124,7 +126,7 @@ unsafe fn handle() -> &'static Channel {

#[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 mut BUFFER: [u8; BUF_SIZE] = [0; BUF_SIZE];

static NAME: &[u8] = b"defmt\0";

Expand Down

0 comments on commit 964c8e7

Please sign in to comment.