Skip to content

Commit

Permalink
Use defmt-rtt and panic-probe for evk boards
Browse files Browse the repository at this point in the history
The evk boards have a built in debug probe. When running firmware with probe-rs
defmt-rtt provides a very fast channel of low cost debug println's that everyone
finds really helpful.

Using panic-probe with defmt-rtt has a second benefit in allowing for programs to
inform probe-rs the firmware has exited cleanly. This can be used for writing samples
and tests that exit.

This also makes the imxrt-log defmt feature optional to the boards otherwise
the two implementations of the defmt logger cause duplicate symbols to show up.

Tested on an 1010evk and 1060evk.
  • Loading branch information
SpinFast committed Oct 25, 2023
1 parent cb44de6 commit 33195af
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 19 deletions.
1 change: 1 addition & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ rustflags = [
"-C", "link-arg=-Tdefmt.x",
"-C", "link-arg=-Tdevice.x",
"-C", "link-arg=-error-limit=0",
"-C", "link-arg=-nmagic",
]
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ required-features = ["board/imxrt-log"]
name = "rtic_logging"
required-features = ["board/imxrt-log"]

[[example]]
name = "rtic_defmt_rtt"

[[example]]
name = "hal_i2c_lcd1602"
required-features = ["board/lcd1602"]
19 changes: 15 additions & 4 deletions board/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ version = "0.2"
version = "0.3"
optional = true

# knurling-rs style defmt-rtt with panic-probe
[target.thumbv7em-none-eabihf.dependencies.defmt-rtt]
version = "0.4"
optional = true

[target.thumbv7em-none-eabihf.dependencies.panic-probe]
version = "0.3"
features = ["print-defmt"]
optional = true

# alternative rtt target with panic printing
[target.thumbv7em-none-eabihf.dependencies.rtt-target]
version = "0.3"
optional = true
Expand Down Expand Up @@ -80,17 +91,17 @@ imxrt1010evk = [
"imxrt-ral/imxrt1011",
"imxrt-hal/imxrt1010",
"imxrt1010evk-fcb",
"rtt-target",
"panic-rtt-target",
"defmt-rtt",
"panic-probe",
"imxrt-log",
]
imxrt1060evk = [
"imxrt-iomuxc/imxrt1060",
"imxrt-ral/imxrt1062",
"imxrt-hal/imxrt1060",
"imxrt1060evk-fcb",
"rtt-target",
"panic-rtt-target",
"defmt-rtt",
"panic-probe",
"imxrt-log",
]
teensy4 = [
Expand Down
3 changes: 0 additions & 3 deletions board/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
itcm: 1,
dtcm: 2,
})
.bss(Memory::Dtcm)
.data(Memory::Dtcm)
.uninit(Memory::Dtcm)
.build()?;
println!("cargo:rustc-cfg=board=\"imxrt1010evk\"");
println!("cargo:rustc-cfg=chip=\"imxrt1010\"");
Expand Down
14 changes: 9 additions & 5 deletions board/src/imxrt1010evk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,19 @@
//! that you populate and de-populate certain resistors. Compile-time
//! configurations are faster than working with 0402 resistors.
use defmt_rtt as _;

use crate::{hal, iomuxc::imxrt1010 as iomuxc, ral};

#[cfg(target_arch = "arm")]
use imxrt1010evk_fcb as _;
#[cfg(target_arch = "arm")]
use panic_rtt_target as _;

use panic_probe as _;

#[defmt::panic_handler]
fn panic() -> ! {
cortex_m::asm::udf();
}

mod imxrt10xx {
pub mod clock;
Expand Down Expand Up @@ -148,9 +155,6 @@ pub struct Specifics {

impl Specifics {
pub(crate) fn new(_: &mut crate::Common) -> Self {
#[cfg(target_arch = "arm")]
rtt_target::rtt_init_print!();

let iomuxc = unsafe { ral::iomuxc::IOMUXC::instance() };
let mut iomuxc = super::convert_iomuxc(iomuxc);
configure_pins(&mut iomuxc);
Expand Down
14 changes: 9 additions & 5 deletions board/src/imxrt1060evk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@
//! exactly the same. I'm not sure if this is generally
//! true.)
use defmt_rtt as _;

use crate::{hal, iomuxc::imxrt1060 as iomuxc, ral};

use panic_probe as _;

#[defmt::panic_handler]
fn panic() -> ! {
cortex_m::asm::udf();
}

#[cfg(target_arch = "arm")]
use imxrt1060evk_fcb as _;
#[cfg(target_arch = "arm")]
use panic_rtt_target as _;

mod imxrt10xx {
pub(crate) mod clock;
Expand Down Expand Up @@ -131,9 +138,6 @@ pub struct Specifics {

impl Specifics {
pub(crate) fn new(_: &mut crate::Common) -> Self {
#[cfg(target_arch = "arm")]
rtt_target::rtt_init_print!();

// Manually configuring IOMUXC_SNVS pads, since there's no
// equivalent API in imxrt-iomuxc.
let iomuxc_snvs = unsafe { ral::iomuxc_snvs::IOMUXC_SNVS::instance() };
Expand Down
4 changes: 4 additions & 0 deletions board/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ pub mod logging {
pub enum Frontend {
/// Use the `log` crate.
Log,
#[cfg(feature = "imxrt-log/defmt")]
/// Use `defmt`.
Defmt,
}
Expand Down Expand Up @@ -329,9 +330,11 @@ pub mod logging {
imxrt_log::log::usbd(usbd, imxrt_log::Interrupts::Enabled).unwrap()
}
// Defmt frontends...
#[cfg(feature = "imxrt-log/defmt")]
(Frontend::Defmt, Backend::Lpuart) => {
imxrt_log::defmt::lpuart(lpuart, dma, imxrt_log::Interrupts::Enabled).unwrap()
}
#[cfg(feature = "imxrt-log/defmt")]
(Frontend::Defmt, Backend::Usbd) => {
imxrt_log::defmt::usbd(usbd, imxrt_log::Interrupts::Enabled).unwrap()
}
Expand All @@ -354,6 +357,7 @@ pub mod logging {
Frontend::Log => {
imxrt_log::log::lpuart(lpuart, dma_channel, imxrt_log::Interrupts::Enabled).unwrap()
}
#[cfg(feature = "imxrt-log/defmt")]
Frontend::Defmt => {
imxrt_log::defmt::lpuart(lpuart, dma_channel, imxrt_log::Interrupts::Enabled)
.unwrap()
Expand Down
91 changes: 91 additions & 0 deletions examples/rtic_defmt_rtt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//! Demonstrates defmt logging using RTT with RTIC.
#![no_std]
#![no_main]

#[rtic::app(device = board, peripherals = false, dispatchers = [BOARD_SWTASK0])]
mod app {

//
// Configure the demo below.
//

/// How frequently (milliseconds) should we make a log message?
///
/// Decrease this constant to log more frequently.
const MAKE_LOG_INTERVAL_MS: u32 = board::PIT_FREQUENCY / 1_000 * 250;

use imxrt_hal as hal;
//
// End configurations.
//

#[local]
struct Local {
/// Toggle when we make a log.
led: board::Led,
/// This timer tells us how frequently to generate
/// logs. It's always used.
make_log: hal::pit::Pit<2>,
}

#[shared]
struct Shared {}

#[init]
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
let mut cortex_m = cx.core;
let (
board::Common {
pit: (_, _, mut make_log, _),
..
},
board::Specifics { led, .. },
) = board::new();
cortex_m.DCB.enable_trace();
cortex_m::peripheral::DWT::unlock();
cortex_m.DWT.enable_cycle_counter();

make_log.set_load_timer_value(MAKE_LOG_INTERVAL_MS);
make_log.set_interrupt_enable(true);
make_log.enable();

(Shared {}, Local { led, make_log }, init::Monotonics())
}

#[task(binds = BOARD_PIT, local = [led, make_log, counter: u32 = 0], priority = 1)]
fn pit_interrupt(cx: pit_interrupt::Context) {
let pit_interrupt::LocalResources {
make_log,
led,
counter,
} = cx.local;

// Is it time for us to send a new log message?
if make_log.is_elapsed() {
led.toggle();
while make_log.is_elapsed() {
make_log.clear_elapsed();
}

let count = cycles(|| {
defmt::println!("Hello from defmt over RTT! The counter is {=u32}", counter)
});

defmt::println!(
"That last message took {=u32} cycles to be copied into the logging buffer",
count
);

*counter += 1;
}
}

/// Count the clock cycles required to execute `f`
fn cycles<F: FnOnce()>(f: F) -> u32 {
let start = cortex_m::peripheral::DWT::cycle_count();
f();
let end = cortex_m::peripheral::DWT::cycle_count();
end - start
}
}
5 changes: 3 additions & 2 deletions logging/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,10 @@ optional = true
workspace = true

[features]
default = ["defmt", "log", "lpuart", "usbd"]
default = ["log", "lpuart", "usbd"]
lpuart = ["imxrt-hal"]
usbd = ["dep:imxrt-usbd", "dep:usb-device", "dep:usbd-serial"]
defmt = ["dep:defmt"]

[dev-dependencies.cortex-m]
version = "0.7"
Expand All @@ -62,4 +63,4 @@ workspace = true

[package.metadata.docs.rs]
default-target = "thumbv7em-none-eabihf"
features = ["imxrt-ral/imxrt1062", "imxrt-hal/imxrt1060"]
features = ["defmt", "imxrt-ral/imxrt1062", "imxrt-hal/imxrt1060"]

0 comments on commit 33195af

Please sign in to comment.