Skip to content

Commit 16d7f0d

Browse files
bors[bot]Dirbaio
andauthored
Merge #689
689: defmt-rtt: Update to critical-section 1.0 r=Urhengulas a=Dirbaio This is a breaking change, because 1.0 no longer supplies any critical section implementation by default. The user has to opt-in to one instead (for example, by enabling the `critical-section-single-core` feature in `cortex-m`: rust-embedded/cortex-m#447). Thankfully it needs bumping only `defmt-rtt`, and not `defmt`. So it won't cause the painful ecosystem split like the `defmt 0.2 -> 0.3` update. TODO before merging: - [x] Wait for `critical-section 1.0` release rust-embedded/critical-section#19 Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
2 parents a8b0fdf + 3ad7b89 commit 16d7f0d

File tree

3 files changed

+28
-9
lines changed

3 files changed

+28
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10+
- [#689]: defmt-rtt: Update to critical-section 1.0
1011
- [#692]: Wrap const fn in const item to ensure compile-time-evaluation.
1112
- [#690]: Satisfy clippy
1213
- [#688]: Release `defmt-decoder 0.3.3`

firmware/defmt-rtt/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ version = "0.3.2"
1212

1313
[dependencies]
1414
defmt = { version = "0.3", path = "../../defmt" }
15-
critical-section = "0.2.5"
15+
critical-section = "1.0.0"

firmware/defmt-rtt/src/lib.rs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,25 @@
1717
//! is because the RTT buffer will fill up and writing will eventually halt the program execution.
1818
//!
1919
//! `defmt::flush` would also block forever in that case.
20+
//!
21+
//! # Critical section implementation
22+
//!
23+
//! This crate uses [`critical-section`](https://github.com/rust-embedded/critical-section) to ensure only one thread
24+
//! is writing to the buffer at a time. You must import a crate that provides a `critical-section` implementation
25+
//! suitable for the current target. See the `critical-section` README for details.
26+
//!
27+
//! For example, for single-core privileged-mode Cortex-M targets, you can add the following to your Cargo.toml.
28+
//!
29+
//! ```toml
30+
//! [dependencies]
31+
//! cortex-m = { version = "0.7.6", features = ["critical-section-single-core"]}
32+
//! ```
2033
2134
#![no_std]
2235

2336
mod channel;
2437

25-
use core::sync::atomic::{AtomicBool, AtomicU8, AtomicUsize, Ordering};
38+
use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
2639

2740
use crate::channel::Channel;
2841

@@ -37,13 +50,13 @@ struct Logger;
3750

3851
/// Global logger lock.
3952
static TAKEN: AtomicBool = AtomicBool::new(false);
40-
static INTERRUPTS_ACTIVE: AtomicU8 = AtomicU8::new(0);
53+
static mut CS_RESTORE: critical_section::RestoreState = critical_section::RestoreState::invalid();
4154
static mut ENCODER: defmt::Encoder = defmt::Encoder::new();
4255

4356
unsafe impl defmt::Logger for Logger {
4457
fn acquire() {
4558
// safety: Must be paired with corresponding call to release(), see below
46-
let token = unsafe { critical_section::acquire() };
59+
let restore = unsafe { critical_section::acquire() };
4760

4861
if TAKEN.load(Ordering::Relaxed) {
4962
panic!("defmt logger taken reentrantly")
@@ -52,9 +65,10 @@ unsafe impl defmt::Logger for Logger {
5265
// no need for CAS because interrupts are disabled
5366
TAKEN.store(true, Ordering::Relaxed);
5467

55-
INTERRUPTS_ACTIVE.store(token, Ordering::Relaxed);
68+
// safety: accessing the `static mut` is OK because we have acquired a critical section.
69+
unsafe { CS_RESTORE = restore };
5670

57-
// safety: accessing the `static mut` is OK because we have disabled interrupts.
71+
// safety: accessing the `static mut` is OK because we have acquired a critical section.
5872
unsafe { ENCODER.start_frame(do_write) }
5973
}
6074

@@ -64,16 +78,20 @@ unsafe impl defmt::Logger for Logger {
6478
}
6579

6680
unsafe fn release() {
67-
// safety: accessing the `static mut` is OK because we have disabled interrupts.
81+
// safety: accessing the `static mut` is OK because we have acquired a critical section.
6882
ENCODER.end_frame(do_write);
6983

7084
TAKEN.store(false, Ordering::Relaxed);
85+
86+
// safety: accessing the `static mut` is OK because we have acquired a critical section.
87+
let restore = CS_RESTORE;
88+
7189
// safety: Must be paired with corresponding call to acquire(), see above
72-
critical_section::release(INTERRUPTS_ACTIVE.load(Ordering::Relaxed));
90+
critical_section::release(restore);
7391
}
7492

7593
unsafe fn write(bytes: &[u8]) {
76-
// safety: accessing the `static mut` is OK because we have disabled interrupts.
94+
// safety: accessing the `static mut` is OK because we have acquired a critical section.
7795
ENCODER.write(bytes, do_write);
7896
}
7997
}

0 commit comments

Comments
 (0)