From 3b5e7a9af30b7dacc8a8c882b9299f38ac066f46 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 22 Apr 2025 14:58:07 +0200 Subject: [PATCH] start switching to defmt --- .cargo/def-config.toml | 13 ++-- README.md | 28 +++++++-- bootloader/Cargo.toml | 12 ++-- bootloader/src/main.rs | 52 ++++++++-------- examples/embassy/Cargo.toml | 7 ++- examples/embassy/src/bin/async-gpio.rs | 57 ++++++++--------- examples/embassy/src/bin/async-uart-rx.rs | 16 ++--- examples/embassy/src/bin/async-uart-tx.rs | 12 ++-- .../embassy/src/bin/uart-echo-with-irq.rs | 14 +++-- examples/embassy/src/main.rs | 12 ++-- examples/rtic/Cargo.toml | 5 +- examples/rtic/src/bin/rtic-empty.rs | 9 +-- examples/rtic/src/main.rs | 9 +-- examples/simple/Cargo.toml | 7 ++- examples/simple/examples/adc.rs | 18 +++--- examples/simple/examples/blinky.rs | 10 +-- examples/simple/examples/dac-adc.rs | 14 +++-- examples/simple/examples/dma.rs | 22 ++++--- .../simple/examples/peb1-accelerometer.rs | 10 +-- examples/simple/examples/pwm.rs | 15 ++--- examples/simple/examples/rtt-log.rs | 12 ++-- examples/simple/examples/spi.rs | 10 +-- examples/simple/examples/timer-ticks.rs | 13 ++-- examples/simple/examples/uart.rs | 16 ++--- examples/simple/examples/wdt.rs | 11 ++-- examples/simple/src/main.rs | 2 +- flashloader/Cargo.toml | 10 +-- flashloader/image-loader.py | 61 +++++++++++++------ flashloader/requirements.txt | 4 +- flashloader/src/lib.rs | 9 --- flashloader/src/main.rs | 37 ++++++----- jlink-gdb-ram.sh | 5 ++ jlink-gdb.sh | 4 +- memory.x | 3 +- scripts/defmt-telnet.sh | 18 ++++++ 35 files changed, 317 insertions(+), 240 deletions(-) delete mode 100644 flashloader/src/lib.rs create mode 100755 jlink-gdb-ram.sh create mode 100755 scripts/defmt-telnet.sh diff --git a/.cargo/def-config.toml b/.cargo/def-config.toml index 6568a3f..11cf15a 100644 --- a/.cargo/def-config.toml +++ b/.cargo/def-config.toml @@ -2,18 +2,15 @@ # runner = "gdb-multiarch -q -x jlink/jlink.gdb" # runner = "arm-none-eabi-gdb -q -x jlink/jlink-reva.gdb" # runner = "gdb-multiarch -q -x jlink/jlink-reva.gdb" - -# Probe-rs is currently problematic, possibly because of the -# ROM protection? runner = "probe-rs run --chip VA416xx_RAM --protocol swd" rustflags = [ "-C", "link-arg=-Tlink.x", - # "-C", - # "linker=flip-link", - # "-C", - # "link-arg=-Tdefmt.x", + "-C", + "linker=flip-link", + "-C", + "link-arg=-Tdefmt.x", # This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x # See https://github.com/rust-embedded/cortex-m-quickstart/pull/95 "-C", @@ -37,4 +34,4 @@ ut = "test --target=x86_64-unknown-linux-gnu" genbin = "objcopy --release -- -O binary app.bin" [env] -DEFMT_LOG = "info" +DEFMT_LOG = "debug" diff --git a/README.md b/README.md index d468852..2cba213 100644 --- a/README.md +++ b/README.md @@ -74,8 +74,8 @@ probe-rs run --chip VA416xx_RAM --protocol jtag target/thumbv7em-none-eabihf/deb to flash and run the blinky program on the RAM. There is also a `VA416xx` chip target available for persistent flashing. -Runner configuration avilable in the `.cargo/def-config.toml` file to use `probe-rs` for -convenience. +Runner configuration is available in the `.cargo/def-config.toml` file to use `probe-rs` for +convenience. `probe-rs` is also able to process and display `defmt` strings directly. ### Pre-Requisites @@ -123,16 +123,25 @@ You can build the blinky example application with the following command cargo build --example blinky ``` -Start the GDB server first. The server needs to be started with a certain configuration and with -a JLink script to disable ROM protection. +Start the GDB server first. Depending on whether the application is flashed to RAM or the NVM +flash memory, the server needs to be started with a different configuration For example, on Debian based system the following command can be used to do this (this command is also run when running the `jlink-gdb.sh` script) +**RAM Flash** + ```sh JLinkGDBServer -select USB -device Cortex-M4 -endian little -if SWD -speed 2000 \ -LocalhostOnly -vd -jlinkscriptfile ./jlink/JLinkSettings.JLinkScript ``` +**NVM Flash** + +```sh +JLinkGDBServer -select USB -device VA416xx -endian little -if SWD -speed 2000 \ + -LocalhostOnly -vd +``` + After this, you can flash and debug the application with the following command ```sh @@ -144,7 +153,7 @@ runner configuration, for example with the following lines in your `.cargo/confi ```toml [target.'cfg(all(target_arch = "arm", target_os = "none"))'] -runner = "gdb-multiarch -q -x jlink/jlink.gdb" +runner = "gdb-multiarch -q -x jlink/jlink.gdb -tui" ``` After that, you can simply use `cargo run --example blinky` to flash the blinky @@ -156,6 +165,15 @@ The Segger RTT viewer can be used to display log messages received from the targ address for the RTT block placement is 0x1fff8000. It is recommended to use a search range of 0x1000 around that base address when using the RTT viewer. +The RTT viewer will not be able to process `defmt` printouts. However, you can view the defmt +logs by [installing defmt-print](https://crates.io/crates/defmt-print) first and then running + +```sh +defmt-print -e tcp +``` + +The path of the ELF file which is being debugged needs to be specified for this to work. + ## Learning (Embedded) Rust If you are unfamiliar with Rust on Embedded Systems or Rust in general, the following resources diff --git a/bootloader/Cargo.toml b/bootloader/Cargo.toml index 51cb0a3..3e984af 100644 --- a/bootloader/Cargo.toml +++ b/bootloader/Cargo.toml @@ -7,16 +7,12 @@ edition = "2021" cortex-m = "0.7" cortex-m-rt = "0.7" embedded-hal = "1" -panic-rtt-target = { version = "0.2" } -panic-halt = { version = "1" } -rtt-target = { version = "0.6" } +defmt-rtt = "0.4" +defmt = "1" +panic-probe = { version = "1", features = ["defmt"] } crc = "3" static_assertions = "1" [dependencies.va416xx-hal] version = "0.5" -features = ["va41630"] - -[features] -default = [] -rtt-panic = [] +features = ["va41630", "defmt"] diff --git a/bootloader/src/main.rs b/bootloader/src/main.rs index ec67a41..1551e05 100644 --- a/bootloader/src/main.rs +++ b/bootloader/src/main.rs @@ -7,11 +7,8 @@ use cortex_m_rt::entry; use crc::{Crc, CRC_32_ISO_HDLC}; -#[cfg(not(feature = "rtt-panic"))] -use panic_halt as _; -#[cfg(feature = "rtt-panic")] -use panic_rtt_target as _; -use rtt_target::{rprintln, rtt_init_print}; +use defmt_rtt as _; +use panic_probe as _; use va416xx_hal::{ clock::{pll_setup_delay, ClkDivSel, ClkselSys}, edac, @@ -35,7 +32,7 @@ const DEBUG_PRINTOUTS: bool = true; const FLASH_SELF: bool = false; // Useful for debugging and see what the bootloader is doing. Enabled currently, because // the binary stays small enough. -const RTT_PRINTOUT: bool = true; +const DEFMT_PRINTOUTS: bool = true; // Important bootloader addresses and offsets, vector table information. @@ -76,7 +73,7 @@ pub const RESET_VECTOR_OFFSET: u32 = 0x4; const CRC_ALGO: Crc = Crc::::new(&CRC_32_ISO_HDLC); -#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, defmt::Format)] enum AppSel { A, B, @@ -98,9 +95,8 @@ impl WdtInterface for OptWdt { #[entry] fn main() -> ! { - if RTT_PRINTOUT { - rtt_init_print!(); - rprintln!("-- VA416xx bootloader --"); + if DEFMT_PRINTOUTS { + defmt::println!("-- VA416xx bootloader --"); } let mut dp = pac::Peripherals::take().unwrap(); let cp = cortex_m::Peripherals::take().unwrap(); @@ -145,20 +141,20 @@ fn main() -> ! { nvm.write_data(0x0, &first_four_bytes); nvm.write_data(0x4, bootloader_data); if let Err(e) = nvm.verify_data(0x0, &first_four_bytes) { - if RTT_PRINTOUT { - rprintln!("verification of self-flash to NVM failed: {:?}", e); + if DEFMT_PRINTOUTS { + defmt::error!("verification of self-flash to NVM failed: {:?}", e); } } if let Err(e) = nvm.verify_data(0x4, bootloader_data) { - if RTT_PRINTOUT { - rprintln!("verification of self-flash to NVM failed: {:?}", e); + if DEFMT_PRINTOUTS { + defmt::error!("verification of self-flash to NVM failed: {:?}", e); } } nvm.write_data(BOOTLOADER_CRC_ADDR, &bootloader_crc.to_be_bytes()); if let Err(e) = nvm.verify_data(BOOTLOADER_CRC_ADDR, &bootloader_crc.to_be_bytes()) { - if RTT_PRINTOUT { - rprintln!( + if DEFMT_PRINTOUTS { + defmt::error!( "error: CRC verification for bootloader self-flash failed: {:?}", e ); @@ -174,8 +170,8 @@ fn main() -> ! { } else if check_app_crc(AppSel::B, &opt_wdt) { boot_app(AppSel::B, &cp) } else { - if DEBUG_PRINTOUTS && RTT_PRINTOUT { - rprintln!("both images corrupt! booting image A"); + if DEBUG_PRINTOUTS && DEFMT_PRINTOUTS { + defmt::println!("both images corrupt! booting image A"); } // TODO: Shift a CCSDS packet out to inform host/OBC about image corruption. // Both images seem to be corrupt. Boot default image A. @@ -202,8 +198,8 @@ fn check_own_crc(wdt: &OptWdt, nvm: &Nvm, cp: &cortex_m::Peripherals) { let crc_calc = digest.finalize(); wdt.feed(); if crc_exp == 0x0000 || crc_exp == 0xffff { - if DEBUG_PRINTOUTS && RTT_PRINTOUT { - rprintln!("BL CRC blank - prog new CRC"); + if DEBUG_PRINTOUTS && DEFMT_PRINTOUTS { + defmt::info!("BL CRC blank - prog new CRC"); } // Blank CRC, write it to NVM. nvm.write_data(BOOTLOADER_CRC_ADDR, &crc_calc.to_be_bytes()); @@ -212,8 +208,8 @@ fn check_own_crc(wdt: &OptWdt, nvm: &Nvm, cp: &cortex_m::Peripherals) { // cortex_m::peripheral::SCB::sys_reset(); } else if crc_exp != crc_calc { // Bootloader is corrupted. Try to run App A. - if DEBUG_PRINTOUTS && RTT_PRINTOUT { - rprintln!( + if DEBUG_PRINTOUTS && DEFMT_PRINTOUTS { + defmt::info!( "bootloader CRC corrupt, read {} and expected {}. booting image A immediately", crc_calc, crc_exp @@ -235,8 +231,8 @@ fn read_four_bytes_at_addr_zero(buf: &mut [u8; 4]) { } } fn check_app_crc(app_sel: AppSel, wdt: &OptWdt) -> bool { - if DEBUG_PRINTOUTS && RTT_PRINTOUT { - rprintln!("Checking image {:?}", app_sel); + if DEBUG_PRINTOUTS && DEFMT_PRINTOUTS { + defmt::info!("Checking image {:?}", app_sel); } if app_sel == AppSel::A { check_app_given_addr(APP_A_CRC_ADDR, APP_A_START_ADDR, APP_A_SIZE_ADDR, wdt) @@ -255,8 +251,8 @@ fn check_app_given_addr( let image_size = unsafe { (image_size_addr as *const u32).read_unaligned().to_be() }; // Sanity check. if image_size > APP_A_END_ADDR - APP_A_START_ADDR - 8 { - if RTT_PRINTOUT { - rprintln!("detected invalid app size {}", image_size); + if DEFMT_PRINTOUTS { + defmt::info!("detected invalid app size {}", image_size); } return false; } @@ -272,8 +268,8 @@ fn check_app_given_addr( } fn boot_app(app_sel: AppSel, cp: &cortex_m::Peripherals) -> ! { - if DEBUG_PRINTOUTS && RTT_PRINTOUT { - rprintln!("booting app {:?}", app_sel); + if DEBUG_PRINTOUTS && DEFMT_PRINTOUTS { + defmt::info!("booting app {:?}", app_sel); } let clkgen = unsafe { pac::Clkgen::steal() }; clkgen diff --git a/examples/embassy/Cargo.toml b/examples/embassy/Cargo.toml index e586a19..4c41c7f 100644 --- a/examples/embassy/Cargo.toml +++ b/examples/embassy/Cargo.toml @@ -12,9 +12,10 @@ embedded-io = "0.6" embedded-hal-async = "1" embedded-io-async = "0.6" -rtt-target = { version = "0.6" } heapless = "0.8" -panic-rtt-target = { version = "0.2" } +defmt-rtt = "0.4" +defmt = "1" +panic-probe = { version = "1", features = ["defmt"] } static_cell = "2" critical-section = "1" once_cell = { version = "1", default-features = false, features = ["critical-section"] } @@ -28,7 +29,7 @@ embassy-executor = { version = "0.7", features = [ "executor-interrupt" ]} -va416xx-hal = { version = "0.5" } +va416xx-hal = { version = "0.5", features = ["defmt"] } va416xx-embassy = { version = "0.1", default-features = false } [features] diff --git a/examples/embassy/src/bin/async-gpio.rs b/examples/embassy/src/bin/async-gpio.rs index a739e36..56b3729 100644 --- a/examples/embassy/src/bin/async-gpio.rs +++ b/examples/embassy/src/bin/async-gpio.rs @@ -5,6 +5,10 @@ //! [CHECK_XXX_TO_XXX] constants to true. #![no_std] #![no_main] +// Import panic provider. +use panic_probe as _; +// Import logger. +use defmt_rtt as _; use embassy_example::EXTCLK_FREQ; use embassy_executor::Spawner; @@ -12,8 +16,6 @@ use embassy_sync::channel::{Receiver, Sender}; use embassy_sync::{blocking_mutex::raw::ThreadModeRawMutex, channel::Channel}; use embassy_time::{Duration, Instant, Timer}; use embedded_hal_async::digital::Wait; -use panic_rtt_target as _; -use rtt_target::{rprintln, rtt_init_print}; use va416xx_hal::clock::ClkgenExt; use va416xx_hal::gpio::{ on_interrupt_for_async_gpio_for_port, InputDynPinAsync, InputPinAsync, PinsB, PinsC, PinsD, @@ -66,8 +68,7 @@ static CHANNEL_PF0_TO_PF1: Channel = Channel::ne #[embassy_executor::main] async fn main(spawner: Spawner) { - rtt_init_print!(); - rprintln!("-- VA416xx Async GPIO Demo --"); + defmt::println!("-- VA416xx Async GPIO Demo --"); let mut dp = pac::Peripherals::take().unwrap(); @@ -114,7 +115,7 @@ async fn main(spawner: Spawner) { )) .unwrap(); check_pin_to_pin_async_ops("PA0 to PA1", CHANNEL_PA0_TO_PA1.sender(), in_pin).await; - rprintln!("Example PA0 to PA1 done"); + defmt::info!("Example PA0 to PA1 done"); } if CHECK_PB0_TO_PB1 { @@ -131,7 +132,7 @@ async fn main(spawner: Spawner) { )) .unwrap(); check_pin_to_pin_async_ops("PB0 to PB1", CHANNEL_PB0_TO_PB1.sender(), in_pin).await; - rprintln!("Example PB0 to PB1 done"); + defmt::info!("Example PB0 to PB1 done"); } if CHECK_PC14_TO_PC15 { @@ -147,7 +148,7 @@ async fn main(spawner: Spawner) { )) .unwrap(); check_pin_to_pin_async_ops("PC14 to PC15", CHANNEL_PC14_TO_PC15.sender(), in_pin).await; - rprintln!("Example PC14 to PC15 done"); + defmt::info!("Example PC14 to PC15 done"); } if CHECK_PD2_TO_PD3 { @@ -163,7 +164,7 @@ async fn main(spawner: Spawner) { )) .unwrap(); check_pin_to_pin_async_ops("PD2 to PD3", CHANNEL_PD2_TO_PD3.sender(), in_pin).await; - rprintln!("Example PD2 to PD3 done"); + defmt::info!("Example PD2 to PD3 done"); } if CHECK_PE0_TO_PE1 { @@ -179,7 +180,7 @@ async fn main(spawner: Spawner) { )) .unwrap(); check_pin_to_pin_async_ops("PE0 to PE1", CHANNEL_PE0_TO_PE1.sender(), in_pin).await; - rprintln!("Example PE0 to PE1 done"); + defmt::info!("Example PE0 to PE1 done"); } if CHECK_PF0_TO_PF1 { @@ -195,10 +196,10 @@ async fn main(spawner: Spawner) { )) .unwrap(); check_pin_to_pin_async_ops("PF0 to PF1", CHANNEL_PF0_TO_PF1.sender(), in_pin).await; - rprintln!("Example PF0 to PF1 done"); + defmt::info!("Example PF0 to PF1 done"); } - rprintln!("Example done, toggling LED0"); + defmt::info!("Example done, toggling LED0"); loop { led.toggle(); Timer::after(Duration::from_millis(500)).await; @@ -210,46 +211,46 @@ async fn check_pin_to_pin_async_ops( sender: Sender<'static, ThreadModeRawMutex, GpioCmd, 3>, mut async_input: impl Wait, ) { - rprintln!( + defmt::info!( "{}: sending SetHigh command ({} ms)", ctx, Instant::now().as_millis() ); sender.send(GpioCmd::new(GpioCmdType::SetHigh, 20)).await; async_input.wait_for_high().await.unwrap(); - rprintln!( + defmt::info!( "{}: Input pin is high now ({} ms)", ctx, Instant::now().as_millis() ); - rprintln!( + defmt::info!( "{}: sending SetLow command ({} ms)", ctx, Instant::now().as_millis() ); sender.send(GpioCmd::new(GpioCmdType::SetLow, 20)).await; async_input.wait_for_low().await.unwrap(); - rprintln!( + defmt::info!( "{}: Input pin is low now ({} ms)", ctx, Instant::now().as_millis() ); - rprintln!( + defmt::info!( "{}: sending RisingEdge command ({} ms)", ctx, Instant::now().as_millis() ); sender.send(GpioCmd::new(GpioCmdType::RisingEdge, 20)).await; async_input.wait_for_rising_edge().await.unwrap(); - rprintln!( + defmt::info!( "{}: input pin had rising edge ({} ms)", ctx, Instant::now().as_millis() ); - rprintln!( + defmt::info!( "{}: sending Falling command ({} ms)", ctx, Instant::now().as_millis() @@ -258,13 +259,13 @@ async fn check_pin_to_pin_async_ops( .send(GpioCmd::new(GpioCmdType::FallingEdge, 20)) .await; async_input.wait_for_falling_edge().await.unwrap(); - rprintln!( + defmt::info!( "{}: input pin had a falling edge ({} ms)", ctx, Instant::now().as_millis() ); - rprintln!( + defmt::info!( "{}: sending Falling command ({} ms)", ctx, Instant::now().as_millis() @@ -273,20 +274,20 @@ async fn check_pin_to_pin_async_ops( .send(GpioCmd::new(GpioCmdType::FallingEdge, 20)) .await; async_input.wait_for_any_edge().await.unwrap(); - rprintln!( + defmt::info!( "{}: input pin had a falling (any) edge ({} ms)", ctx, Instant::now().as_millis() ); - rprintln!( + defmt::info!( "{}: sending Falling command ({} ms)", ctx, Instant::now().as_millis() ); sender.send(GpioCmd::new(GpioCmdType::RisingEdge, 20)).await; async_input.wait_for_any_edge().await.unwrap(); - rprintln!( + defmt::info!( "{}: input pin had a rising (any) edge ({} ms)", ctx, Instant::now().as_millis() @@ -305,29 +306,29 @@ async fn output_task( Timer::after(Duration::from_millis(next_cmd.after_delay.into())).await; match next_cmd.cmd_type { GpioCmdType::SetHigh => { - rprintln!("{}: Set output high", ctx); + defmt::info!("{}: Set output high", ctx); out.set_high().unwrap(); } GpioCmdType::SetLow => { - rprintln!("{}: Set output low", ctx); + defmt::info!("{}: Set output low", ctx); out.set_low().unwrap(); } GpioCmdType::RisingEdge => { - rprintln!("{}: Rising edge", ctx); + defmt::info!("{}: Rising edge", ctx); if !out.is_low().unwrap() { out.set_low().unwrap(); } out.set_high().unwrap(); } GpioCmdType::FallingEdge => { - rprintln!("{}: Falling edge", ctx); + defmt::info!("{}: Falling edge", ctx); if !out.is_high().unwrap() { out.set_high().unwrap(); } out.set_low().unwrap(); } GpioCmdType::CloseTask => { - rprintln!("{}: Closing task", ctx); + defmt::info!("{}: Closing task", ctx); break; } } diff --git a/examples/embassy/src/bin/async-uart-rx.rs b/examples/embassy/src/bin/async-uart-rx.rs index 49df09a..4f3447d 100644 --- a/examples/embassy/src/bin/async-uart-rx.rs +++ b/examples/embassy/src/bin/async-uart-rx.rs @@ -12,7 +12,12 @@ //! RTT logs to see received data. #![no_std] #![no_main] +// Import panic provider. +use panic_probe as _; +// Import logger. use core::cell::RefCell; +use defmt_rtt as _; +use defmt_rtt as _; use critical_section::Mutex; use embassy_example::EXTCLK_FREQ; @@ -21,8 +26,6 @@ use embassy_time::Instant; use embedded_io::Write; use embedded_io_async::Read; use heapless::spsc::{Producer, Queue}; -use panic_rtt_target as _; -use rtt_target::{rprintln, rtt_init_print}; use va416xx_hal::{ gpio::PinsG, pac::{self, interrupt}, @@ -41,8 +44,7 @@ static PRODUCER_UART_A: Mutex>>> = Mutex::new(R #[embassy_executor::main] async fn main(_spawner: Spawner) { - rtt_init_print!(); - rprintln!("-- VA108xx Async UART RX Demo --"); + defmt::println!("-- VA108xx Async UART RX Demo --"); let mut dp = pac::Peripherals::take().unwrap(); @@ -84,11 +86,11 @@ async fn main(_spawner: Spawner) { let mut async_uart_rx = RxAsync::new(rx_uart_a, cons_uart_a); let mut buf = [0u8; 256]; loop { - rprintln!("Current time UART A: {}", Instant::now().as_secs()); + defmt::info!("Current time UART A: {}", Instant::now().as_secs()); led.toggle(); let read_bytes = async_uart_rx.read(&mut buf).await.unwrap(); let read_str = core::str::from_utf8(&buf[..read_bytes]).unwrap(); - rprintln!( + defmt::info!( "Read {} bytes asynchronously on UART A: {:?}", read_bytes, read_str @@ -106,6 +108,6 @@ fn UART0_RX() { critical_section::with(|cs| *PRODUCER_UART_A.borrow(cs).borrow_mut() = Some(prod)); // In a production app, we could use a channel to send the errors to the main task. if let Err(errors) = errors { - rprintln!("UART A errors: {:?}", errors); + defmt::info!("UART A errors: {:?}", errors); } } diff --git a/examples/embassy/src/bin/async-uart-tx.rs b/examples/embassy/src/bin/async-uart-tx.rs index 2628dda..c110182 100644 --- a/examples/embassy/src/bin/async-uart-tx.rs +++ b/examples/embassy/src/bin/async-uart-tx.rs @@ -11,12 +11,15 @@ //! RTT logs to see received data. #![no_std] #![no_main] +// Import panic provider. +use panic_probe as _; +// Import logger. +use defmt_rtt as _; + use embassy_example::EXTCLK_FREQ; use embassy_executor::Spawner; use embassy_time::{Duration, Instant, Ticker}; use embedded_io_async::Write; -use panic_rtt_target as _; -use rtt_target::{rprintln, rtt_init_print}; use va416xx_hal::{ gpio::PinsG, pac::{self, interrupt}, @@ -39,8 +42,7 @@ const STR_LIST: &[&str] = &[ // main is itself an async function. #[embassy_executor::main] async fn main(_spawner: Spawner) { - rtt_init_print!(); - rprintln!("-- VA108xx Async UART TX Demo --"); + defmt::println!("-- VA108xx Async UART TX Demo --"); let mut dp = pac::Peripherals::take().unwrap(); @@ -75,7 +77,7 @@ async fn main(_spawner: Spawner) { let mut ticker = Ticker::every(Duration::from_secs(1)); let mut idx = 0; loop { - rprintln!("Current time: {}", Instant::now().as_secs()); + defmt::println!("Current time: {}", Instant::now().as_secs()); led.toggle(); let _written = async_tx .write(STR_LIST[idx].as_bytes()) diff --git a/examples/embassy/src/bin/uart-echo-with-irq.rs b/examples/embassy/src/bin/uart-echo-with-irq.rs index a0b0cbf..e8c6f22 100644 --- a/examples/embassy/src/bin/uart-echo-with-irq.rs +++ b/examples/embassy/src/bin/uart-echo-with-irq.rs @@ -9,6 +9,11 @@ //! on the UART without requiring polling. #![no_std] #![no_main] +// Import panic provider. +use panic_probe as _; +// Import logger. +use defmt_rtt as _; + use core::cell::RefCell; use embassy_example::EXTCLK_FREQ; @@ -17,12 +22,10 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::blocking_mutex::Mutex; use embassy_time::{Duration, Ticker}; use embedded_io::Write; -use panic_rtt_target as _; use ringbuf::{ traits::{Consumer, Observer, Producer}, StaticRb, }; -use rtt_target::{rprintln, rtt_init_print}; use va416xx_hal::{ gpio::{OutputReadablePushPull, Pin, PinsG, PG5}, pac::{self, interrupt}, @@ -49,8 +52,7 @@ static RINGBUF: SharedRingBuf = Mutex::new(RefCell::new(None)); // a peripheral with embassy. #[embassy_executor::main] async fn main(spawner: Spawner) { - rtt_init_print!(); - rprintln!("VA416xx UART-Embassy Example"); + defmt::println!("VA416xx UART-Embassy Example"); let mut dp = pac::Peripherals::take().unwrap(); @@ -153,9 +155,9 @@ fn UART0_RX() { } if errors.is_some() { - rprintln!("UART error: {:?}", errors); + defmt::info!("UART error: {:?}", errors); } if ringbuf_full { - rprintln!("ringbuffer is full, deleted oldest data"); + defmt::info!("ringbuffer is full, deleted oldest data"); } } diff --git a/examples/embassy/src/main.rs b/examples/embassy/src/main.rs index c580a68..f89d348 100644 --- a/examples/embassy/src/main.rs +++ b/examples/embassy/src/main.rs @@ -1,10 +1,13 @@ #![no_std] #![no_main] +// Import panic provider. +use panic_probe as _; +// Import logger. +use defmt_rtt as _; + use embassy_example::EXTCLK_FREQ; use embassy_executor::Spawner; use embassy_time::{Duration, Instant, Ticker}; -use panic_rtt_target as _; -use rtt_target::{rprintln, rtt_init_print}; use va416xx_hal::{gpio::PinsG, pac, prelude::*, time::Hertz}; cfg_if::cfg_if! { @@ -17,8 +20,7 @@ cfg_if::cfg_if! { // main is itself an async function. #[embassy_executor::main] async fn main(_spawner: Spawner) { - rtt_init_print!(); - rprintln!("VA416xx Embassy Demo"); + defmt::println!("VA416xx Embassy Demo"); let mut dp = pac::Peripherals::take().unwrap(); @@ -57,7 +59,7 @@ async fn main(_spawner: Spawner) { let mut ticker = Ticker::every(Duration::from_secs(1)); loop { ticker.next().await; - rprintln!("Current time: {}", Instant::now().as_secs()); + defmt::info!("Current time: {}", Instant::now().as_secs()); led.toggle(); } } diff --git a/examples/rtic/Cargo.toml b/examples/rtic/Cargo.toml index 7389da0..f04fd4b 100644 --- a/examples/rtic/Cargo.toml +++ b/examples/rtic/Cargo.toml @@ -7,9 +7,10 @@ edition = "2021" cortex-m = { version = "0.7", features = ["critical-section-single-core"] } cortex-m-rt = "0.7" embedded-hal = "1" -rtt-target = { version = "0.6" } +defmt-rtt = "0.4" +defmt = "1" +panic-probe = { version = "1", features = ["defmt"] } rtic-sync = { version = "1.3", features = ["defmt-03"] } -panic-rtt-target = { version = "0.2" } va416xx-hal = { version = "0.5", features = ["va41630"] } diff --git a/examples/rtic/src/bin/rtic-empty.rs b/examples/rtic/src/bin/rtic-empty.rs index be6c109..d0e7a19 100644 --- a/examples/rtic/src/bin/rtic-empty.rs +++ b/examples/rtic/src/bin/rtic-empty.rs @@ -4,8 +4,10 @@ #[rtic::app(device = pac)] mod app { - use panic_rtt_target as _; - use rtt_target::{rprintln, rtt_init_default}; + // Import panic provider. + use panic_probe as _; + // Import logger. + use defmt_rtt as _; use va416xx_hal::pac; #[local] @@ -16,8 +18,7 @@ mod app { #[init] fn init(_ctx: init::Context) -> (Shared, Local) { - rtt_init_default!(); - rprintln!("-- Vorago RTIC template --"); + defmt::println!("-- Vorago RTIC template --"); (Shared {}, Local {}) } diff --git a/examples/rtic/src/main.rs b/examples/rtic/src/main.rs index 3cb713f..d2bbc6c 100644 --- a/examples/rtic/src/main.rs +++ b/examples/rtic/src/main.rs @@ -9,11 +9,13 @@ const EXTCLK_FREQ: Hertz = Hertz::from_raw(40_000_000); #[rtic::app(device = pac, dispatchers = [U1, U2, U3])] mod app { use super::*; + // Import panic provider. + use panic_probe as _; + // Import logger. use cortex_m::asm; - use panic_rtt_target as _; + use defmt_rtt as _; use rtic_monotonics::systick::prelude::*; use rtic_monotonics::Monotonic; - use rtt_target::{rprintln, rtt_init_default}; use va416xx_hal::{ gpio::{OutputReadablePushPull, Pin, PinsG, PG5}, pac, @@ -32,8 +34,7 @@ mod app { #[init] fn init(mut cx: init::Context) -> (Shared, Local) { - rtt_init_default!(); - rprintln!("-- Vorago RTIC example application --"); + defmt::println!("-- Vorago RTIC example application --"); // Use the external clock connected to XTAL_N. let clocks = cx .device diff --git a/examples/simple/Cargo.toml b/examples/simple/Cargo.toml index 24f5294..c2dbf7a 100644 --- a/examples/simple/Cargo.toml +++ b/examples/simple/Cargo.toml @@ -7,8 +7,9 @@ edition = "2021" cortex-m = { version = "0.7", features = ["critical-section-single-core"] } cortex-m-rt = "0.7" critical-section = "1" -panic-rtt-target = { version = "0.2" } -rtt-target = { version = "0.6" } +defmt-rtt = "0.4" +defmt = "1" +panic-probe = { version = "1", features = ["defmt"] } embedded-hal = "1" embedded-hal-nb = "1" nb = "1" @@ -16,7 +17,7 @@ embedded-io = "0.6" panic-halt = "1" accelerometer = "0.12" -va416xx-hal = { version = "0.5", features = ["va41630"] } +va416xx-hal = { version = "0.5", features = ["va41630", "defmt"] } [dependencies.vorago-peb1] path = "../../vorago-peb1" diff --git a/examples/simple/examples/adc.rs b/examples/simple/examples/adc.rs index 57fb96b..3321a1f 100644 --- a/examples/simple/examples/adc.rs +++ b/examples/simple/examples/adc.rs @@ -2,10 +2,13 @@ #![no_main] #![no_std] +// Import panic provider. +use panic_probe as _; +// Import logger. +use defmt_rtt as _; + use cortex_m_rt::entry; use embedded_hal::delay::DelayNs; -use panic_rtt_target as _; -use rtt_target::{rprintln, rtt_init_print}; use simple_examples::peb1; use va416xx_hal::{ adc::{Adc, ChannelSelect, ChannelValue, MultiChannelSelect}, @@ -19,8 +22,7 @@ const ENABLE_BUF_PRINTOUT: bool = false; #[entry] fn main() -> ! { - rtt_init_print!(); - rprintln!("VA416xx ADC example"); + defmt::println!("VA416xx ADC example"); let mut dp = pac::Peripherals::take().unwrap(); // Use the external clock connected to XTAL_N. @@ -38,7 +40,7 @@ fn main() -> ! { let single_value = adc .trigger_and_read_single_channel(va416xx_hal::adc::ChannelSelect::TempSensor) .expect("reading single channel value failed"); - rprintln!( + defmt::info!( "Read single ADC value on temperature sensor channel: {:?}", single_value ); @@ -46,8 +48,8 @@ fn main() -> ! { .sweep_and_read_range(0, 7, &mut read_buf) .expect("ADC range read failed"); if ENABLE_BUF_PRINTOUT { - rprintln!("ADC Range Read (0-8) read {} values", read_num); - rprintln!("ADC Range Read (0-8): {:?}", read_buf); + defmt::info!("ADC Range Read (0-8) read {} values", read_num); + defmt::info!("ADC Range Read (0-8): {:?}", read_buf); } assert_eq!(read_num, 8); for (idx, ch_val) in read_buf.iter().enumerate() { @@ -63,7 +65,7 @@ fn main() -> ! { ) .expect("ADC multiselect read failed"); if ENABLE_BUF_PRINTOUT { - rprintln!("ADC Multiselect Read(0, 2 and 10): {:?}", &read_buf[0..3]); + defmt::info!("ADC Multiselect Read(0, 2 and 10): {:?}", &read_buf[0..3]); } assert_eq!(read_buf[0].channel(), ChannelSelect::AnIn0); assert_eq!(read_buf[1].channel(), ChannelSelect::AnIn2); diff --git a/examples/simple/examples/blinky.rs b/examples/simple/examples/blinky.rs index a890a24..57bb4cc 100644 --- a/examples/simple/examples/blinky.rs +++ b/examples/simple/examples/blinky.rs @@ -2,15 +2,17 @@ #![no_main] #![no_std] +// Import panic provider. +use panic_probe as _; +// Import logger. +use defmt_rtt as _; + use cortex_m_rt::entry; -use panic_rtt_target as _; -use rtt_target::{rprintln, rtt_init_print}; use va416xx_hal::{gpio::PinsG, pac}; #[entry] fn main() -> ! { - rtt_init_print!(); - rprintln!("VA416xx HAL blinky example"); + defmt::println!("VA416xx HAL blinky example"); let mut dp = pac::Peripherals::take().unwrap(); let portg = PinsG::new(&mut dp.sysconfig, dp.portg); diff --git a/examples/simple/examples/dac-adc.rs b/examples/simple/examples/dac-adc.rs index 786bdcd..411fd80 100644 --- a/examples/simple/examples/dac-adc.rs +++ b/examples/simple/examples/dac-adc.rs @@ -2,10 +2,13 @@ #![no_main] #![no_std] +// Import panic provider. +use panic_probe as _; +// Import logger. +use defmt_rtt as _; + use cortex_m_rt::entry; use embedded_hal::delay::DelayNs; -use panic_rtt_target as _; -use rtt_target::{rprintln, rtt_init_print}; use simple_examples::peb1; use va416xx_hal::{adc::Adc, dac::Dac, pac, prelude::*, timer::CountdownTimer}; @@ -25,8 +28,7 @@ const APP_MODE: AppMode = AppMode::DacAndAdc; #[entry] fn main() -> ! { - rtt_init_print!(); - rprintln!("VA416xx DAC/ADC example"); + defmt::println!("VA416xx DAC/ADC example"); let mut dp = pac::Peripherals::take().unwrap(); // Use the external clock connected to XTAL_N. @@ -53,7 +55,7 @@ fn main() -> ! { let mut current_val = 0; loop { if let Some(dac) = &dac { - rprintln!("loading DAC with value {}", current_val); + defmt::info!("loading DAC with value {}", current_val); dac.load_and_trigger_manually(current_val) .expect("loading DAC value failed"); if current_val + DAC_INCREMENT >= 4096 { @@ -70,7 +72,7 @@ fn main() -> ! { let ch_value = adc .trigger_and_read_single_channel(va416xx_hal::adc::ChannelSelect::AnIn0) .expect("reading ADC channel 0 failed"); - rprintln!("Received channel value {:?}", ch_value); + defmt::info!("Received channel value {:?}", ch_value); } delay_provider.delay_ms(500); diff --git a/examples/simple/examples/dma.rs b/examples/simple/examples/dma.rs index affd1b0..e49df7a 100644 --- a/examples/simple/examples/dma.rs +++ b/examples/simple/examples/dma.rs @@ -2,13 +2,16 @@ #![no_main] #![no_std] +// Import panic provider. +use panic_probe as _; +// Import logger. +use defmt_rtt as _; + use core::cell::Cell; use cortex_m_rt::entry; use critical_section::Mutex; use embedded_hal::delay::DelayNs; -use panic_rtt_target as _; -use rtt_target::{rprintln, rtt_init_print}; use simple_examples::peb1; use va416xx_hal::dma::{Dma, DmaCfg, DmaChannel, DmaCtrlBlock}; use va416xx_hal::irq_router::enable_and_init_irq_router; @@ -35,8 +38,7 @@ static mut DMA_DEST_BUF: [u16; 36] = [0; 36]; #[entry] fn main() -> ! { - rtt_init_print!(); - rprintln!("VA416xx DMA example"); + defmt::println!("VA416xx DMA example"); let mut dp = pac::Peripherals::take().unwrap(); // Use the external clock connected to XTAL_N. @@ -119,7 +121,7 @@ fn transfer_example_8_bit( let mut dma_done = false; critical_section::with(|cs| { if DMA_ACTIVE_FLAG.borrow(cs).get() { - rprintln!("DMA0 is active with 8 bit transfer"); + defmt::info!("DMA0 is active with 8 bit transfer"); DMA_ACTIVE_FLAG.borrow(cs).set(false); } if DMA_DONE_FLAG.borrow(cs).get() { @@ -127,7 +129,7 @@ fn transfer_example_8_bit( } }); if dma_done { - rprintln!("8-bit transfer done"); + defmt::info!("8-bit transfer done"); break; } delay_ms.delay_ms(1); @@ -177,7 +179,7 @@ fn transfer_example_16_bit(dma0: &mut DmaChannel, delay_ms: &mut CountdownTimer< let mut dma_done = false; critical_section::with(|cs| { if DMA_ACTIVE_FLAG.borrow(cs).get() { - rprintln!("DMA0 is active with 16-bit transfer"); + defmt::info!("DMA0 is active with 16-bit transfer"); DMA_ACTIVE_FLAG.borrow(cs).set(false); } if DMA_DONE_FLAG.borrow(cs).get() { @@ -185,7 +187,7 @@ fn transfer_example_16_bit(dma0: &mut DmaChannel, delay_ms: &mut CountdownTimer< } }); if dma_done { - rprintln!("16-bit transfer done"); + defmt::info!("16-bit transfer done"); break; } delay_ms.delay_ms(1); @@ -237,7 +239,7 @@ fn transfer_example_32_bit( let mut dma_done = false; critical_section::with(|cs| { if DMA_ACTIVE_FLAG.borrow(cs).get() { - rprintln!("DMA0 is active with 32-bit transfer"); + defmt::info!("DMA0 is active with 32-bit transfer"); DMA_ACTIVE_FLAG.borrow(cs).set(false); } if DMA_DONE_FLAG.borrow(cs).get() { @@ -245,7 +247,7 @@ fn transfer_example_32_bit( } }); if dma_done { - rprintln!("32-bit transfer done"); + defmt::info!("32-bit transfer done"); break; } delay_ms.delay_ms(1); diff --git a/examples/simple/examples/peb1-accelerometer.rs b/examples/simple/examples/peb1-accelerometer.rs index a9ed8bf..533c8de 100644 --- a/examples/simple/examples/peb1-accelerometer.rs +++ b/examples/simple/examples/peb1-accelerometer.rs @@ -2,11 +2,14 @@ #![no_main] #![no_std] +// Import panic provider. +use panic_probe as _; +// Import logger. +use defmt_rtt as _; + use accelerometer::{Accelerometer, RawAccelerometer}; use cortex_m_rt::entry; use embedded_hal::delay::DelayNs; -use panic_rtt_target as _; -use rtt_target::{rprintln, rtt_init_print}; use simple_examples::peb1; use va416xx_hal::{ i2c, @@ -25,9 +28,8 @@ const DISPLAY_MODE: DisplayMode = DisplayMode::Normalized; #[entry] fn main() -> ! { - rtt_init_print!(); let mut dp = pac::Peripherals::take().unwrap(); - rprintln!("-- Vorago PEB1 accelerometer example --"); + defmt::println!("-- Vorago PEB1 accelerometer example --"); // Use the external clock connected to XTAL_N. let clocks = dp .clkgen diff --git a/examples/simple/examples/pwm.rs b/examples/simple/examples/pwm.rs index 2d94ec3..e439735 100644 --- a/examples/simple/examples/pwm.rs +++ b/examples/simple/examples/pwm.rs @@ -4,8 +4,10 @@ use cortex_m_rt::entry; use embedded_hal::{delay::DelayNs, pwm::SetDutyCycle}; -use panic_rtt_target as _; -use rtt_target::{rprintln, rtt_init_print}; +// Import panic provider. +use panic_probe as _; +// Import logger. +use defmt_rtt as _; use simple_examples::peb1; use va416xx_hal::{ gpio::PinsA, @@ -17,8 +19,7 @@ use va416xx_hal::{ #[entry] fn main() -> ! { - rtt_init_print!(); - rprintln!("-- VA108xx PWM example application--"); + defmt::println!("-- VA108xx PWM example application--"); let mut dp = pac::Peripherals::take().unwrap(); // Use the external clock connected to XTAL_N. @@ -52,7 +53,7 @@ fn main() -> ! { current_duty_cycle += 0.02; counter += 1; if counter % 10 == 0 { - rprintln!("current duty cycle: {}", current_duty_cycle); + defmt::info!("current duty cycle: {}", current_duty_cycle); } reduced_pin @@ -74,8 +75,8 @@ fn main() -> ! { upper_limit -= 0.01; pwmb.set_pwmb_lower_limit(get_duty_from_percent(lower_limit)); pwmb.set_pwmb_upper_limit(get_duty_from_percent(upper_limit)); - rprintln!("Lower limit: {}", pwmb.pwmb_lower_limit()); - rprintln!("Upper limit: {}", pwmb.pwmb_upper_limit()); + defmt::info!("Lower limit: {}", pwmb.pwmb_lower_limit()); + defmt::info!("Upper limit: {}", pwmb.pwmb_upper_limit()); } reduced_pin = ReducedPwmPin::::from(pwmb); } diff --git a/examples/simple/examples/rtt-log.rs b/examples/simple/examples/rtt-log.rs index 8eb2475..bbf8ac7 100644 --- a/examples/simple/examples/rtt-log.rs +++ b/examples/simple/examples/rtt-log.rs @@ -2,9 +2,12 @@ #![no_main] #![no_std] +// Import panic provider. +use panic_probe as _; +// Import logger. +use defmt_rtt as _; + use cortex_m_rt::entry; -use panic_rtt_target as _; -use rtt_target::{rprintln, rtt_init_print}; use va416xx_hal::pac; // Mask for the LED @@ -12,6 +15,7 @@ const LED_PG5: u32 = 1 << 5; #[entry] fn main() -> ! { + defmt::println!("VA416xx RTT Demo"); let dp = pac::Peripherals::take().unwrap(); // Enable all peripheral clocks dp.sysconfig @@ -22,11 +26,9 @@ fn main() -> ! { .datamask() .modify(|_, w| unsafe { w.bits(LED_PG5) }); - rtt_init_print!(); - rprintln!("VA416xx RTT Demo"); let mut counter = 0; loop { - rprintln!("{}: Hello, world!", counter); + defmt::info!("{}: Hello, world!", counter); // Still toggle LED. If there are issues with the RTT log, the LED // blinking ensures that the application is actually running. dp.portg.togout().write(|w| unsafe { w.bits(LED_PG5) }); diff --git a/examples/simple/examples/spi.rs b/examples/simple/examples/spi.rs index cb8e181..26038d0 100644 --- a/examples/simple/examples/spi.rs +++ b/examples/simple/examples/spi.rs @@ -3,10 +3,13 @@ //! If you do not use the loopback mode, MOSI and MISO need to be tied together on the board. #![no_main] #![no_std] +// Import panic provider. +use panic_probe as _; +// Import logger. +use defmt_rtt as _; + use cortex_m_rt::entry; use embedded_hal::spi::{Mode, SpiBus, MODE_0}; -use panic_rtt_target as _; -use rtt_target::{rprintln, rtt_init_print}; use simple_examples::peb1; use va416xx_hal::spi::{Spi, SpiClkConfig}; use va416xx_hal::{ @@ -33,8 +36,7 @@ const FILL_WORD: u8 = 0x0f; #[entry] fn main() -> ! { - rtt_init_print!(); - rprintln!("-- VA108xx SPI example application--"); + defmt::println!("-- VA108xx SPI example application--"); let cp = cortex_m::Peripherals::take().unwrap(); let mut dp = pac::Peripherals::take().unwrap(); // Use the external clock connected to XTAL_N. diff --git a/examples/simple/examples/timer-ticks.rs b/examples/simple/examples/timer-ticks.rs index b603a46..353bf34 100644 --- a/examples/simple/examples/timer-ticks.rs +++ b/examples/simple/examples/timer-ticks.rs @@ -1,13 +1,15 @@ //! MS and Second counter implemented using the TIM0 and TIM1 peripheral #![no_main] #![no_std] +// Import panic provider. +use panic_probe as _; +// Import logger. +use defmt_rtt as _; use core::cell::Cell; use cortex_m::asm; use cortex_m_rt::entry; use critical_section::Mutex; -use panic_rtt_target as _; -use rtt_target::{rprintln, rtt_init_print}; use simple_examples::peb1; use va416xx_hal::{ irq_router::enable_and_init_irq_router, @@ -26,10 +28,9 @@ static SEC_COUNTER: Mutex> = Mutex::new(Cell::new(0)); #[entry] fn main() -> ! { - rtt_init_print!(); let mut dp = pac::Peripherals::take().unwrap(); let mut last_ms = 0; - rprintln!("-- Vorago system ticks using timers --"); + defmt::println!("-- Vorago system ticks using timers --"); // Use the external clock connected to XTAL_N. let clocks = dp .clkgen @@ -47,9 +48,9 @@ fn main() -> ! { if current_ms >= last_ms + 1000 { // To prevent drift. last_ms += 1000; - rprintln!("MS counter: {}", current_ms); + defmt::info!("MS counter: {}", current_ms); let second = critical_section::with(|cs| SEC_COUNTER.borrow(cs).get()); - rprintln!("Second counter: {}", second); + defmt::info!("Second counter: {}", second); } asm::delay(1000); } diff --git a/examples/simple/examples/uart.rs b/examples/simple/examples/uart.rs index e319aba..f7c722f 100644 --- a/examples/simple/examples/uart.rs +++ b/examples/simple/examples/uart.rs @@ -2,12 +2,14 @@ // echo mode #![no_main] #![no_std] +// Import panic provider. +use panic_probe as _; +// Import logger. +use defmt_rtt as _; use cortex_m_rt::entry; use embedded_hal_nb::serial::Read; use embedded_io::Write; -use panic_rtt_target as _; -use rtt_target::{rprintln, rtt_init_print}; use simple_examples::peb1; use va416xx_hal::clock::ClkgenExt; use va416xx_hal::time::Hertz; @@ -15,8 +17,7 @@ use va416xx_hal::{gpio::PinsG, pac, uart}; #[entry] fn main() -> ! { - rtt_init_print!(); - rprintln!("-- VA416xx UART example application--"); + defmt::println!("-- VA416xx UART example application--"); let mut dp = pac::Peripherals::take().unwrap(); @@ -45,12 +46,11 @@ fn main() -> ! { // Echo what is received on the serial link. match nb::block!(rx.read()) { Ok(recvd) => { - if let Err(e) = embedded_hal_nb::serial::Write::write(&mut tx, recvd) { - rprintln!("UART TX error: {:?}", e); - } + // Infallible operation. + embedded_hal_nb::serial::Write::write(&mut tx, recvd).unwrap(); } Err(e) => { - rprintln!("UART RX error {:?}", e); + defmt::info!("UART RX error {:?}", e); } } } diff --git a/examples/simple/examples/wdt.rs b/examples/simple/examples/wdt.rs index cf7b0c7..f9d749a 100644 --- a/examples/simple/examples/wdt.rs +++ b/examples/simple/examples/wdt.rs @@ -1,12 +1,14 @@ // Code to test the watchdog timer. #![no_main] #![no_std] +// Import panic provider. +use panic_probe as _; +// Import logger. +use defmt_rtt as _; use core::cell::Cell; use cortex_m_rt::entry; use critical_section::Mutex; -use panic_rtt_target as _; -use rtt_target::{rprintln, rtt_init_print}; use simple_examples::peb1; use va416xx_hal::irq_router::enable_and_init_irq_router; use va416xx_hal::pac::{self, interrupt}; @@ -29,8 +31,7 @@ const WDT_ROLLOVER_MS: u32 = 100; #[entry] fn main() -> ! { - rtt_init_print!(); - rprintln!("-- VA416xx WDT example application--"); + defmt::println!("-- VA416xx WDT example application--"); let cp = cortex_m::Peripherals::take().unwrap(); let mut dp = pac::Peripherals::take().unwrap(); @@ -53,7 +54,7 @@ fn main() -> ! { } let interrupt_counter = critical_section::with(|cs| WDT_INTRPT_COUNT.borrow(cs).get()); if interrupt_counter > last_interrupt_counter { - rprintln!("interrupt counter has increased to {}", interrupt_counter); + defmt::info!("interrupt counter has increased to {}", interrupt_counter); last_interrupt_counter = interrupt_counter; } match TEST_MODE { diff --git a/examples/simple/src/main.rs b/examples/simple/src/main.rs index ddb240e..70a3422 100644 --- a/examples/simple/src/main.rs +++ b/examples/simple/src/main.rs @@ -3,7 +3,7 @@ #![no_std] use cortex_m_rt::entry; -use panic_rtt_target as _; +use panic_halt as _; #[entry] fn main() -> ! { diff --git a/flashloader/Cargo.toml b/flashloader/Cargo.toml index db21a8d..b497c68 100644 --- a/flashloader/Cargo.toml +++ b/flashloader/Cargo.toml @@ -9,9 +9,9 @@ cortex-m-rt = "0.7" embedded-hal = "1" embedded-hal-nb = "1" embedded-io = "0.6" -panic-rtt-target = { version = "0.2" } -rtt-target = { version = "0.6" } -rtt-log = "0.5" +defmt-rtt = "0.4" +defmt = "1" +panic-probe = { version = "1", features = ["defmt"] } log = "0.4" crc = "3" rtic-sync = "1" @@ -19,10 +19,10 @@ static_cell = "2" satrs = { version = "0.3.0-alpha.0", default-features = false } ringbuf = { version = "0.4", default-features = false } once_cell = { version = "1", default-features = false, features = ["critical-section"] } -spacepackets = { version = "0.13", default-features = false } +spacepackets = { version = "0.13", default-features = false, features = ["defmt"] } cobs = { version = "0.3", default-features = false } -va416xx-hal = { version = "0.5", features = ["va41630"] } +va416xx-hal = { version = "0.5", features = ["va41630", "defmt"] } rtic = { version = "2", features = ["thumbv7-backend"] } rtic-monotonics = { version = "2", features = ["cortex-m-systick"] } diff --git a/flashloader/image-loader.py b/flashloader/image-loader.py index 802cdec..2310042 100755 --- a/flashloader/image-loader.py +++ b/flashloader/image-loader.py @@ -2,16 +2,15 @@ from typing import List, Tuple from spacepackets.ecss.defs import PusService from spacepackets.ecss.tm import PusTm -from tmtccmd.com import ComInterface +from com_interface import ComInterface import toml import struct import logging import argparse import time import enum -from tmtccmd.com.serial_base import SerialCfg -from tmtccmd.com.serial_cobs import SerialCobsComIF -from tmtccmd.com.ser_utils import prompt_com_port +from com_interface.serial_base import SerialCfg +from com_interface.serial_cobs import SerialCobsComIF from crcmod.predefined import PredefinedCrc from spacepackets.ecss.tc import PusTc from spacepackets.ecss.pus_verificator import PusVerificator, StatusField @@ -58,6 +57,7 @@ PING_PAYLOAD_SIZE = 0 class ActionId(enum.IntEnum): CORRUPT_APP_A = 128 CORRUPT_APP_B = 129 + SET_BOOT_SLOT = 130 _LOGGER = logging.getLogger(__name__) @@ -78,11 +78,29 @@ class Target(enum.Enum): APP_B = 2 +class AppSel(enum.IntEnum): + APP_A = 0 + APP_B = 1 + + class ImageLoader: def __init__(self, com_if: ComInterface, verificator: PusVerificator) -> None: self.com_if = com_if self.verificator = verificator + def handle_boot_sel_cmd(self, target: AppSel): + _LOGGER.info("Sending ping command") + action_tc = PusTc( + apid=0x00, + service=PusService.S8_FUNC_CMD, + subservice=ActionId.SET_BOOT_SLOT, + seq_count=SEQ_PROVIDER.get_and_increment(), + app_data=bytes([target]), + ) + self.verificator.add_tc(action_tc) + self.com_if.send(bytes(action_tc.pack())) + self.await_for_command_copletion("boot image selection command") + def handle_ping_cmd(self): _LOGGER.info("Sending ping command") ping_tc = PusTc( @@ -94,19 +112,9 @@ class ImageLoader: ) self.verificator.add_tc(ping_tc) self.com_if.send(bytes(ping_tc.pack())) - - data_available = self.com_if.data_available(0.4) - if not data_available: - _LOGGER.warning("no ping reply received") - for reply in self.com_if.receive(): - result = self.verificator.add_tm( - Service1Tm.from_tm(PusTm.unpack(reply, 0), UnpackParams(0)) - ) - if result is not None and result.completed: - _LOGGER.info("received ping completion reply") + self.await_for_command_copletion("ping command") def handle_corruption_cmd(self, target: Target): - if target == Target.BOOTLOADER: _LOGGER.error("can not corrupt bootloader") if target == Target.APP_A: @@ -126,6 +134,25 @@ class ImageLoader: ), ) + def await_for_command_copletion(self, context: str): + done = False + now = time.time() + while time.time() - now < 2.0: + if not self.com_if.data_available(): + time.sleep(0.2) + continue + for reply in self.com_if.receive(): + result = self.verificator.add_tm( + Service1Tm.from_tm(PusTm.unpack(reply, 0), UnpackParams(0)) + ) + if result is not None and result.completed: + _LOGGER.info(f"received {context} reply") + done = True + if done: + break + if not done: + _LOGGER.warning(f"no {context} reply received") + def handle_flash_cmd(self, target: Target, file_path: Path) -> int: loadable_segments = [] _LOGGER.info("Parsing ELF file for loadable sections") @@ -269,12 +296,12 @@ def main() -> int: if "serial_port" in parsed_toml: serial_port = parsed_toml["serial_port"] if serial_port is None: - serial_port = prompt_com_port() + serial_port = input("Please specify the serial port manually: ") serial_cfg = SerialCfg( com_if_id="ser_cobs", serial_port=serial_port, baud_rate=BAUD_RATE, - serial_timeout=0.1, + polling_frequency=0.1, ) verificator = PusVerificator() com_if = SerialCobsComIF(serial_cfg) diff --git a/flashloader/requirements.txt b/flashloader/requirements.txt index 5a2f67b..723ead9 100644 --- a/flashloader/requirements.txt +++ b/flashloader/requirements.txt @@ -1,5 +1,5 @@ -spacepackets == 0.24 -tmtccmd == 8.0.2 +spacepackets == 0.28 +com-interface == 0.1.0 toml == 0.10 pyelftools == 0.31 crcmod == 1.7 diff --git a/flashloader/src/lib.rs b/flashloader/src/lib.rs deleted file mode 100644 index 5c9605a..0000000 --- a/flashloader/src/lib.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![no_std] - -#[cfg(test)] -mod tests { - #[test] - fn simple() { - assert_eq!(1 + 1, 2); - } -} diff --git a/flashloader/src/main.rs b/flashloader/src/main.rs index 3825ae2..f3dbf5c 100644 --- a/flashloader/src/main.rs +++ b/flashloader/src/main.rs @@ -19,7 +19,6 @@ #![no_std] use once_cell::sync::OnceCell; -use panic_rtt_target as _; use va416xx_hal::{clock::Clocks, edac, pac, time::Hertz, wdt::Wdt}; const EXTCLK_FREQ: u32 = 40_000_000; @@ -95,10 +94,12 @@ mod app { use super::*; use cortex_m::asm; use embedded_io::Write; - use panic_rtt_target as _; + // Import panic provider. + use panic_probe as _; + // Import logger. + use defmt_rtt as _; use rtic::Mutex; use rtic_monotonics::systick::prelude::*; - use rtt_target::rprintln; use satrs::pus::verification::VerificationReportCreator; use spacepackets::ecss::PusServiceId; use spacepackets::ecss::{ @@ -150,9 +151,7 @@ mod app { #[init] fn init(mut cx: init::Context) -> (Shared, Local) { - //rtt_init_default!(); - rtt_log::init(); - rprintln!("-- Vorago flashloader --"); + defmt::println!("-- Vorago flashloader --"); // Initialize the systick interrupt & obtain the token to prove that we did // Use the external clock connected to XTAL_N. let clocks = cx @@ -272,7 +271,7 @@ mod app { let decoded_size = cobs::decode_in_place(&mut cx.local.rx_buf[1..result.bytes_read]); if decoded_size.is_err() { - log::warn!("COBS decoding failed"); + defmt::warn!("COBS decoding failed"); } else { let decoded_size = decoded_size.unwrap(); if cx.local.tc_prod.sizes_prod.vacant_len() >= 1 @@ -285,11 +284,13 @@ mod app { .buf_prod .push_slice(&cx.local.rx_buf[1..1 + decoded_size]); } else { - log::warn!("COBS TC queue full"); + defmt::warn!("COBS TC queue full"); } } } else { - log::warn!("COBS frame with invalid format, start and end bytes are not 0"); + defmt::warn!( + "COBS frame with invalid format, start and end bytes are not 0" + ); } // Initiate next transfer. @@ -299,11 +300,11 @@ mod app { .expect("read operation failed"); } if result.has_errors() { - log::warn!("UART error: {:?}", result.errors.unwrap()); + defmt::warn!("UART error: {:?}", result.errors.unwrap()); } } Err(e) => { - log::warn!("UART error: {:?}", e); + defmt::warn!("UART error: {:?}", e); } } } @@ -346,7 +347,7 @@ mod app { fn handle_valid_pus_tc(cx: &mut pus_tc_handler::Context) { let pus_tc = PusTcReader::new(cx.local.tc_buf); if pus_tc.is_err() { - log::warn!("PUS TC error: {}", pus_tc.unwrap_err()); + defmt::warn!("PUS TC error: {}", pus_tc.unwrap_err()); return; } let (pus_tc, _) = pus_tc.unwrap(); @@ -396,11 +397,11 @@ mod app { write_and_send(&tm); }; if pus_tc.subservice() == ActionId::CorruptImageA as u8 { - rprintln!("corrupting App Image A"); + defmt::info!("corrupting App Image A"); corrupt_image(APP_A_START_ADDR); } if pus_tc.subservice() == ActionId::CorruptImageB as u8 { - rprintln!("corrupting App Image B"); + defmt::info!("corrupting App Image B"); corrupt_image(APP_B_START_ADDR); } } @@ -430,23 +431,21 @@ mod app { if pus_tc.subservice() == 2 { let app_data = pus_tc.app_data(); if app_data.len() < 10 { - log::warn!( - target: "TC Handler", + defmt::warn!( "app data for raw memory write is too short: {}", app_data.len() ); } let memory_id = app_data[0]; if memory_id != BOOT_NVM_MEMORY_ID { - log::warn!(target: "TC Handler", "memory ID {} not supported", memory_id); + defmt::warn!("memory ID {} not supported", memory_id); // TODO: Error reporting return; } let offset = u32::from_be_bytes(app_data[2..6].try_into().unwrap()); let data_len = u32::from_be_bytes(app_data[6..10].try_into().unwrap()); if 10 + data_len as usize > app_data.len() { - log::warn!( - target: "TC Handler", + defmt::warn!( "invalid data length {} for raw mem write detected", data_len ); diff --git a/jlink-gdb-ram.sh b/jlink-gdb-ram.sh new file mode 100755 index 0000000..f0ac97f --- /dev/null +++ b/jlink-gdb-ram.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# Start the JLinkGDBServer while also specifying the JLinkScript file. The JLinkScript is necessary +# to disable ROM protection to allow flashing +JLinkGDBServer -select USB -device Cortex-M4 -endian little -if SWD -speed 2000 \ + -LocalhostOnly -vd -jlinkscriptfile ./jlink/JLinkSettings.JLinkScript diff --git a/jlink-gdb.sh b/jlink-gdb.sh index 65e187f..c5385d1 100755 --- a/jlink-gdb.sh +++ b/jlink-gdb.sh @@ -1,5 +1,5 @@ #!/bin/bash # Start the JLinkGDBServer while also specifying the JLinkScript file. The JLinkScript is necessary # to disable ROM protection to allow flashing -JLinkGDBServer -select USB -device Cortex-M4 -endian little -if SWD -speed 2000 \ - -LocalhostOnly -vd -jlinkscriptfile ./jlink/JLinkSettings.JLinkScript +JLinkGDBServer -select USB -device VA416xx -endian little -if SWD -speed 2000 \ + -LocalhostOnly -vd diff --git a/memory.x b/memory.x index 811b87a..a00615d 100644 --- a/memory.x +++ b/memory.x @@ -18,6 +18,5 @@ _stack_start = ORIGIN(RAM) + LENGTH(RAM); SECTIONS { .sram1 (NOLOAD) : ALIGN(8) { *(.sram1 .sram1.*); - . = ALIGN(4); - } > SRAM_1 + } > SRAM_1 }; diff --git a/scripts/defmt-telnet.sh b/scripts/defmt-telnet.sh new file mode 100755 index 0000000..0339483 --- /dev/null +++ b/scripts/defmt-telnet.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# Check if binary path was provided +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " + exit 1 +fi + +BINARY="$1" + +# Check if file exists +if [ ! -f "$BINARY" ]; then + echo "Error: File '$BINARY' not found." + exit 1 +fi + +# Run the command +defmt-print -e "$BINARY" tcp