diff --git a/.cargo/def-config.toml b/.cargo/def-config.toml index 5a92bed..6b78b69 100644 --- a/.cargo/def-config.toml +++ b/.cargo/def-config.toml @@ -18,9 +18,9 @@ rustflags = [ "-C", "link-arg=-Tlink.x", # knurling-rs tooling. If you want to use flip-link, ensure it is installed first. - # "-C", "linker=flip-link", + "-C", "linker=flip-link", # Unfortunately, defmt is clunky to use without probe-rs.. - # "-C", "link-arg=-Tdefmt.x", + "-C", "link-arg=-Tdefmt.x", # Can be useful for debugging. # "-Clink-args=-Map=app.map" diff --git a/Cargo.toml b/Cargo.toml index 618e8a3..966472f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,6 @@ members = [ "flashloader", ] exclude = [ - "defmt-testapp", "flashloader/slot-a-blinky", "flashloader/slot-b-blinky", ] diff --git a/README.md b/README.md index 382bd6f..01f4582 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ to flash and run the blinky program on the RAM. There is also a `VA108xx` chip t available for persistent flashing. Runner configuration avilable in the `.cargo/def-config.toml` file to use `probe-rs` for -convenience. +convenience. `probe-rs` is also able to process and display `defmt` strings directly. ### Using VS Code @@ -123,13 +123,13 @@ is also run when running the `jlink-gdb.sh` script) ```sh JLinkGDBServer -select USB -device Cortex-M0 -endian little -if JTAG-speed auto \ - -LocalhostOnly + -LocalhostOnly -jtagconf -1,-1 ``` After this, you can flash and debug the application with the following command ```sh -gdb-mutliarch -q -x jlink/jlink.gdb target/thumbv6m-none-eabihf/debug/examples/blinky +gdb-mutliarch -q -x jlink/jlink.gdb target/thumbv6m-none-eabihf/debug/examples/blinky -tui ``` Please note that you can automate all steps except starting the GDB server by using a cargo @@ -149,6 +149,16 @@ The Segger RTT viewer can be used to display log messages received from the targ address for the RTT block placement is 0x10000000. 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 piping +the output on telnet port 19021 into `defmt-print`, for example by running + +```sh +telnet localhost 19021 | defmt-print -e +``` + +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/defmt-testapp/.cargo/config.toml b/defmt-testapp/.cargo/config.toml deleted file mode 100644 index 68458a8..0000000 --- a/defmt-testapp/.cargo/config.toml +++ /dev/null @@ -1,48 +0,0 @@ -[target.'cfg(all(target_arch = "arm", target_os = "none"))'] -# uncomment ONE of these three option to make `cargo run` start a GDB session -# which option to pick depends on your system -# runner = "arm-none-eabi-gdb -q -x openocd.gdb" -# runner = "gdb-multiarch -q -x openocd.gdb" -# runner = "gdb -q -x openocd.gdb" -runner = "gdb-multiarch -q -x jlink.gdb" - -# Probe-rs is currently problematic: https://github.com/probe-rs/probe-rs/issues/2567 -# runner = "probe-rs run --chip VA108xx --chip-description-path ./scripts/VA108xx_Series.yaml" -# runner = ["probe-rs", "run", "--chip", "$CHIP", "--log-format", "{L} {s}"] - -rustflags = [ - # 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", "link-arg=--nmagic", - - # LLD (shipped with the Rust toolchain) is used as the default linker - "-C", "link-arg=-Tlink.x", - - # knurling-rs tooling. If you want to use flip-link, ensure it is installed first. - "-C", "linker=flip-link", - # Unfortunately, defmt is clunky to use without probe-rs.. - "-C", "link-arg=-Tdefmt.x", - - # Can be useful for debugging. - "-Clink-args=-Map=app.map" - -] - -[build] -# Pick ONE of these compilation targets -target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+ -# target = "thumbv7m-none-eabi" # Cortex-M3 -# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU) -# target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU) -# target = "thumbv8m.base-none-eabi" # Cortex-M23 -# target = "thumbv8m.main-none-eabi" # Cortex-M33 (no FPU) -# target = "thumbv8m.main-none-eabihf" # Cortex-M33 (with FPU) - -[alias] -re = "run --example" -rb = "run --bin" -rrb = "run --release --bin" -ut = "test --target x86_64-unknown-linux-gnu" - -[env] -DEFMT_LOG = "info" diff --git a/defmt-testapp/.gitignore b/defmt-testapp/.gitignore deleted file mode 100644 index ea8c4bf..0000000 --- a/defmt-testapp/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/defmt-testapp/Cargo.toml b/defmt-testapp/Cargo.toml deleted file mode 100644 index 6b31352..0000000 --- a/defmt-testapp/Cargo.toml +++ /dev/null @@ -1,34 +0,0 @@ -[package] -name = "defmt-testapp" -version = "0.1.0" -edition = "2021" - -[dependencies] -cortex-m = {version = "0.7", features = ["critical-section-single-core"]} -panic-rtt-target = "0.1" -cortex-m-rt = "0.7" -rtt-target = "0.5" -rtic-sync = { version = "1.3", features = ["defmt-03"] } -embedded-hal = "1" -embedded-hal-nb = "1" -embedded-io = "0.6" -cortex-m-semihosting = "0.5.0" -# Tricky without probe-rs. -defmt = "0.3" -defmt-brtt = { version = "0.1", default-features = false, features = ["rtt"] } -panic-probe = { version = "0.3", features = ["print-defmt"] } - -[dependencies.rtic] -version = "2" -features = ["thumbv6-backend"] - -[dependencies.rtic-monotonics] -version = "1" -features = ["cortex-m-systick"] - -[dependencies.va108xx-hal] -version = "0.10" -features = ["rt", "defmt"] - -[dependencies.va108xx] -version = "0.5" diff --git a/defmt-testapp/README.md b/defmt-testapp/README.md deleted file mode 100644 index 7514cbe..0000000 --- a/defmt-testapp/README.md +++ /dev/null @@ -1,9 +0,0 @@ -defmt Testapp -====== - -`defmt` is clunky to use without probe-rs and requires special configuration inside the -`.cargo/config.toml` file. - -`probe-rs` is currently problematic for usage with the VA108xx , so it is not the default tool -recommended and used for the whole workspace. This project contains an isolated, `defmt` compatible -configuration for testing with `defmt` (and `probe-rs`). diff --git a/defmt-testapp/src/lib.rs b/defmt-testapp/src/lib.rs deleted file mode 100644 index 7466d3f..0000000 --- a/defmt-testapp/src/lib.rs +++ /dev/null @@ -1,53 +0,0 @@ -#![no_main] -#![no_std] - -use cortex_m_semihosting::debug; - -use defmt_brtt as _; // global logger - -use va108xx_hal as _; // memory layout - -use panic_probe as _; - -// same panicking *behavior* as `panic-probe` but doesn't print a panic message -// this prevents the panic message being printed *twice* when `defmt::panic` is invoked -// #[defmt::panic_handler] -/* -fn panic() -> ! { - cortex_m::asm::udf() -} -*/ - -/// Terminates the application and makes a semihosting-capable debug tool exit -/// with status code 0. -pub fn exit() -> ! { - loop { - debug::exit(debug::EXIT_SUCCESS); - } -} - -/// Hardfault handler. -/// -/// Terminates the application and makes a semihosting-capable debug tool exit -/// with an error. This seems better than the default, which is to spin in a -/// loop. -#[cortex_m_rt::exception] -unsafe fn HardFault(_frame: &cortex_m_rt::ExceptionFrame) -> ! { - loop { - debug::exit(debug::EXIT_FAILURE); - } -} - -// defmt-test 0.3.0 has the limitation that this `#[tests]` attribute can only be used -// once within a crate. the module can be in any file but there can only be at most -// one `#[tests]` module in this library crate -#[cfg(test)] -#[defmt_test::tests] -mod unit_tests { - use defmt::assert; - - #[test] - fn it_works() { - assert!(true) - } -} diff --git a/defmt-testapp/src/main.rs b/defmt-testapp/src/main.rs deleted file mode 100644 index c0fa5e5..0000000 --- a/defmt-testapp/src/main.rs +++ /dev/null @@ -1,29 +0,0 @@ -//! Empty RTIC project template -#![no_main] -#![no_std] - -use defmt_testapp as _; - -#[rtic::app(device = pac)] -mod app { - use va108xx_hal::pac; - - #[local] - struct Local {} - - #[shared] - struct Shared {} - - #[init] - fn init(_ctx: init::Context) -> (Shared, Local) { - defmt::println!("-- Vorago RTIC template --"); - (Shared {}, Local {}) - } - - // `shared` cannot be accessed from this context - #[idle] - fn idle(_cx: idle::Context) -> ! { - #[allow(clippy::empty_loop)] - loop {} - } -} diff --git a/examples/embassy/Cargo.toml b/examples/embassy/Cargo.toml index d1854fd..039e18a 100644 --- a/examples/embassy/Cargo.toml +++ b/examples/embassy/Cargo.toml @@ -14,8 +14,10 @@ embedded-io-async = "0.6" heapless = "0.8" static_cell = "2" -rtt-target = "0.6" -panic-rtt-target = "0.2" +defmt = "1" +defmt-rtt = "0.4" +panic-probe = { version = "0.3", features = ["print-defmt"] } + critical-section = "1" portable-atomic = { version = "1", features = ["unsafe-assume-single-core"]} @@ -27,7 +29,7 @@ embassy-executor = { version = "0.7", features = [ "executor-interrupt" ]} -va108xx-hal = { version = "0.11" } +va108xx-hal = { version = "0.11", features = ["defmt"] } va108xx-embassy = { version = "0.2" } [features] diff --git a/examples/embassy/src/bin/async-gpio.rs b/examples/embassy/src/bin/async-gpio.rs index 3237e4c..e06f774 100644 --- a/examples/embassy/src/bin/async-gpio.rs +++ b/examples/embassy/src/bin/async-gpio.rs @@ -4,14 +4,14 @@ //! and then set the `CHECK_PB22_TO_PB23` to true to also test async operations on Port B. #![no_std] #![no_main] +// This imports the logger and the panic handler. +use embassy_example as _; use embassy_executor::Spawner; 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 va108xx_hal::gpio::{ on_interrupt_for_async_gpio_for_port, InputDynPinAsync, InputPinAsync, PinsB, Port, }; @@ -58,8 +58,7 @@ static CHANNEL_PB22_TO_PB23: Channel = Channel:: #[embassy_executor::main] async fn main(spawner: Spawner) { - rtt_init_print!(); - rprintln!("-- VA108xx Async GPIO Demo --"); + defmt::println!("-- VA108xx Async GPIO Demo --"); let mut dp = pac::Peripherals::take().unwrap(); @@ -102,15 +101,15 @@ async fn main(spawner: Spawner) { if CHECK_PA0_TO_PA1 { check_pin_to_pin_async_ops("PA0 to PA1", CHANNEL_PA0_PA1.sender(), in_pa1_async).await; - rprintln!("Example PA0 to PA1 done"); + defmt::info!("Example PA0 to PA1 done"); } if CHECK_PB22_TO_PB23 { check_pin_to_pin_async_ops("PB22 to PB23", CHANNEL_PB22_TO_PB23.sender(), in_pb23_async) .await; - rprintln!("Example PB22 to PB23 done"); + defmt::info!("Example PB22 to PB23 done"); } - rprintln!("Example done, toggling LED0"); + defmt::info!("Example done, toggling LED0"); loop { led0.toggle(); Timer::after(Duration::from_millis(500)).await; @@ -122,46 +121,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() @@ -170,13 +169,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() @@ -185,20 +184,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() @@ -216,22 +215,22 @@ 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(); } diff --git a/examples/embassy/src/bin/async-uart-rx.rs b/examples/embassy/src/bin/async-uart-rx.rs index ccd163e..33a974d 100644 --- a/examples/embassy/src/bin/async-uart-rx.rs +++ b/examples/embassy/src/bin/async-uart-rx.rs @@ -13,16 +13,16 @@ //! RTT logs to see received data. #![no_std] #![no_main] -use core::cell::RefCell; +// This imports the logger and the panic handler. +use embassy_example as _; +use core::cell::RefCell; use critical_section::Mutex; use embassy_executor::Spawner; use embassy_time::Instant; use embedded_io::Write; use embedded_io_async::Read; use heapless::spsc::{Consumer, Producer, Queue}; -use panic_rtt_target as _; -use rtt_target::{rprintln, rtt_init_print}; use va108xx_hal::{ gpio::PinsA, pac::{self, interrupt}, @@ -49,8 +49,7 @@ static CONSUMER_UART_B: Mutex>>> = Mutex::new(R // main is itself an async function. #[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(); @@ -108,13 +107,13 @@ async fn main(spawner: Spawner) { .unwrap(); 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()); led0.toggle(); led1.toggle(); led2.toggle(); let read_bytes = async_rx_uart_a.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 @@ -127,11 +126,11 @@ async fn main(spawner: Spawner) { async fn uart_b_task(mut async_rx: RxAsyncOverwriting, mut tx: Tx) { let mut buf = [0u8; 256]; loop { - rprintln!("Current time UART B: {}", Instant::now().as_secs()); + defmt::info!("Current time UART B: {}", Instant::now().as_secs()); // Infallible asynchronous operation. let read_bytes = async_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 B: {:?}", read_bytes, read_str @@ -149,7 +148,7 @@ fn OC2() { 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); } } @@ -162,6 +161,6 @@ fn OC3() { critical_section::with(|cs| *PRODUCER_UART_B.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 B errors: {:?}", errors); + defmt::info!("UART B errors: {:?}", errors); } } diff --git a/examples/embassy/src/bin/async-uart-tx.rs b/examples/embassy/src/bin/async-uart-tx.rs index fdf97aa..29ee434 100644 --- a/examples/embassy/src/bin/async-uart-tx.rs +++ b/examples/embassy/src/bin/async-uart-tx.rs @@ -10,11 +10,12 @@ //! can verify the correctness of the sent strings. #![no_std] #![no_main] +// This imports the logger and the panic handler. +use embassy_example as _; + 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 va108xx_hal::{ gpio::PinsA, pac::{self, interrupt}, @@ -35,8 +36,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(); @@ -70,7 +70,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::info!("Current time: {}", Instant::now().as_secs()); led0.toggle(); led1.toggle(); led2.toggle(); diff --git a/examples/embassy/src/lib.rs b/examples/embassy/src/lib.rs new file mode 100644 index 0000000..cd7af3f --- /dev/null +++ b/examples/embassy/src/lib.rs @@ -0,0 +1,3 @@ +#![no_std] +use panic_probe as _; +use defmt_rtt as _; diff --git a/examples/embassy/src/main.rs b/examples/embassy/src/main.rs index d1ecad8..9b532a1 100644 --- a/examples/embassy/src/main.rs +++ b/examples/embassy/src/main.rs @@ -2,8 +2,7 @@ #![no_main] use embassy_executor::Spawner; use embassy_time::{Duration, Instant, Ticker}; -use panic_rtt_target as _; -use rtt_target::{rprintln, rtt_init_print}; +use embassy_example as _; cfg_if::cfg_if! { if #[cfg(feature = "custom-irqs")] { @@ -20,8 +19,7 @@ const SYSCLK_FREQ: Hertz = Hertz::from_raw(50_000_000); // main is itself an async function. #[embassy_executor::main] async fn main(_spawner: Spawner) { - rtt_init_print!(); - rprintln!("-- VA108xx Embassy Demo --"); + defmt::println!("-- VA108xx Embassy Demo --"); let mut dp = pac::Peripherals::take().unwrap(); @@ -55,7 +53,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()); led0.toggle(); led1.toggle(); led2.toggle(); diff --git a/examples/simple/Cargo.toml b/examples/simple/Cargo.toml index 1222d39..158cbff 100644 --- a/examples/simple/Cargo.toml +++ b/examples/simple/Cargo.toml @@ -17,7 +17,7 @@ cortex-m-semihosting = "0.5.0" [dependencies.va108xx-hal] version = "0.11" -features = ["rt", "defmt"] +features = ["defmt"] [dependencies.vorago-reb1] version = "0.8" diff --git a/examples/simple/src/main.rs b/examples/simple/src/main.rs index ddb240e..154f422 100644 --- a/examples/simple/src/main.rs +++ b/examples/simple/src/main.rs @@ -3,6 +3,7 @@ #![no_std] use cortex_m_rt::entry; +use va108xx_hal as _; use panic_rtt_target as _; #[entry] diff --git a/flashloader/Cargo.toml b/flashloader/Cargo.toml index 0f29ec8..a979b11 100644 --- a/flashloader/Cargo.toml +++ b/flashloader/Cargo.toml @@ -9,17 +9,16 @@ cortex-m-rt = "0.7" embedded-hal = "1" embedded-hal-nb = "1" embedded-io = "0.6" -panic-rtt-target = "0.2" -rtt-target = "0.6" +defmt = "1" +defmt-rtt = { version = "0.4" } +panic-probe = { version = "0.3", features = ["print-defmt"] } num_enum = { version = "0.7", default-features = false } -log = "0.4" crc = "3" cobs = { version = "0.3", default-features = false } satrs = { version = "0.2", default-features = false } -rtt-log = "0.5" ringbuf = { version = "0.4.7", default-features = false, features = ["portable-atomic"] } once_cell = { version = "1", default-features = false, features = ["critical-section"] } -spacepackets = { version = "0.11", default-features = false } +spacepackets = { version = "0.11", default-features = false, features = ["defmt"] } # Even though we do not use this directly, we need to activate this feature explicitely # so that RTIC compiles because thumv6 does not have CAS operations natively. portable-atomic = {version = "1", features = ["unsafe-assume-single-core"]} @@ -30,6 +29,7 @@ rtic-sync = {version = "1", features = ["defmt-03"]} [dependencies.va108xx-hal] version = "0.11" +features = ["defmt"] [dependencies.vorago-reb1] version = "0.8" 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 a87a669..e9ac424 100644 --- a/flashloader/src/main.rs +++ b/flashloader/src/main.rs @@ -4,7 +4,8 @@ #![no_std] use num_enum::TryFromPrimitive; -use panic_rtt_target as _; +use panic_probe as _; +use defmt_rtt as _; // global logger use ringbuf::{ traits::{Consumer, Observer, Producer}, StaticRb, @@ -29,7 +30,7 @@ pub enum ActionId { SetBootSlot = 130, } -#[derive(Debug, Copy, Clone, PartialEq, Eq, TryFromPrimitive)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, TryFromPrimitive, defmt::Format)] #[repr(u8)] enum AppSel { A = 0, @@ -60,10 +61,8 @@ mod app { use super::*; use cortex_m::asm; use embedded_io::Write; - use panic_rtt_target as _; use rtic::Mutex; use rtic_monotonics::systick::prelude::*; - use rtt_target::rprintln; use satrs::pus::verification::{FailParams, VerificationReportCreator}; use spacepackets::ecss::PusServiceId; use spacepackets::ecss::{ @@ -102,8 +101,7 @@ mod app { #[init] fn init(cx: init::Context) -> (Shared, Local) { - rtt_log::init(); - rprintln!("-- Vorago flashloader --"); + defmt::println!("-- Vorago flashloader --"); Mono::start(cx.core.SYST, SYSCLK_FREQ.raw()); @@ -181,8 +179,8 @@ mod app { { Ok(result) => { if RX_DEBUGGING { - log::debug!("RX Info: {:?}", cx.local.rx_context); - log::debug!("RX Result: {:?}", result); + defmt::debug!("RX Info: {:?}", cx.local.rx_context); + defmt::debug!("RX Result: {:?}", result); } if result.complete() { // Check frame validity (must have COBS format) and decode the frame. @@ -193,7 +191,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(); let mut tc_rb_full = false; @@ -207,11 +205,13 @@ mod app { } }); if tc_rb_full { - 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. @@ -221,11 +221,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); } } } @@ -252,7 +252,7 @@ mod app { continue; } let packet_len = packet_len.unwrap(); - log::info!(target: "TC Handler", "received packet with length {}", packet_len); + defmt::info!("received packet with length {}", packet_len); let popped_packet_len = cx .shared .tc_rb @@ -266,7 +266,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!(target: "TC Handler", "PUS TC error: {}", pus_tc.unwrap_err()); + defmt::warn!("PUS TC error: {}", pus_tc.unwrap_err()); return; } let (pus_tc, _) = pus_tc.unwrap(); @@ -312,22 +312,25 @@ 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); } if pus_tc.subservice() == ActionId::SetBootSlot as u8 { if pus_tc.app_data().is_empty() { - log::warn!(target: "TC Handler", "App data for preferred image command too short"); + defmt::warn!("App data for preferred image command too short"); } let app_sel_result = AppSel::try_from(pus_tc.app_data()[0]); if app_sel_result.is_err() { - log::warn!("Invalid app selection value: {}", pus_tc.app_data()[0]); + defmt::warn!("Invalid app selection value: {}", pus_tc.app_data()[0]); } - log::info!(target: "TC Handler", "received boot selection command with app select: {:?}", app_sel_result.unwrap()); + defmt::info!( + "received boot selection command with app select: {:?}", + app_sel_result.unwrap() + ); cx.local .nvm .write(PREFERRED_SLOT_OFFSET as usize, &[pus_tc.app_data()[0]]) @@ -341,7 +344,7 @@ mod app { } } if pus_tc.service() == PusServiceId::Test as u8 && pus_tc.subservice() == 1 { - log::info!(target: "TC Handler", "received ping TC"); + defmt::info!("received ping TC"); let tm = cx .local .verif_reporter @@ -366,23 +369,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 ); @@ -390,12 +391,7 @@ mod app { return; } let data = &app_data[10..10 + data_len as usize]; - log::info!( - target: "TC Handler", - "writing {} bytes at offset {} to NVM", - data_len, - offset - ); + defmt::info!("writing {} bytes at offset {} to NVM", data_len, offset); cx.local .nvm .write(offset as usize, data) @@ -406,7 +402,7 @@ mod app { .verify(offset as usize, data) .expect("NVM verification failed") { - log::warn!("verification of data written to NVM failed"); + defmt::warn!("verification of data written to NVM failed"); cx.local .verif_reporter .completion_failure( @@ -424,9 +420,7 @@ mod app { .expect("completion success failed") }; write_and_send(&tm); - log::info!( - target: "TC Handler", - "NVM operation done"); + defmt::info!("NVM operation done"); } } } diff --git a/jlink-gdb.sh b/jlink-gdb.sh index 44b38f4..6233f1f 100755 --- a/jlink-gdb.sh +++ b/jlink-gdb.sh @@ -1,3 +1,3 @@ #!/bin/bash -JLinkGDBServer -select USB -device Cortex-M0 -endian little -if JTAG -speed auto \ - -LocalhostOnly +JLinkGDBServer -select USB -device VA10820 -endian little -if JTAG -speed auto \ + -LocalhostOnly -jtagconf -1,-1 diff --git a/scripts/defmt-telnet.sh b/scripts/defmt-telnet.sh new file mode 100755 index 0000000..e86688a --- /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 +telnet localhost 19021 | defmt-print -e "$BINARY" diff --git a/va108xx/Cargo.toml b/va108xx/Cargo.toml index 20573b7..15b6446 100644 --- a/va108xx/Cargo.toml +++ b/va108xx/Cargo.toml @@ -13,7 +13,7 @@ categories = ["embedded", "no-std", "hardware-support"] [dependencies] cortex-m = "0.7" vcell = "0.1.3" -defmt = { version = "0.3", optional = true } +defmt = { version = "1", optional = true } critical-section = { version = "1", optional = true } [dependencies.cortex-m-rt]