From 1fdece43e396be953033fbac74b5946c9ef291a5 Mon Sep 17 00:00:00 2001 From: sli Date: Wed, 26 Jun 2024 19:36:02 -0500 Subject: [PATCH 1/3] generated rp2040 project compiles successfully --- ci.sh | 4 ++ src/chip.rs | 3 ++ src/chip/family.rs | 2 + src/chip/family/mem_region.rs | 7 ++++ src/init.rs | 62 +++++++++++++++++++++++++----- src/templates/build.rs.rp.template | 36 +++++++++++++++++ src/templates/main.rs.rp.template | 30 +++++++++++++++ src/templates/memory.x.rp.template | 15 ++++++++ 8 files changed, 149 insertions(+), 10 deletions(-) create mode 100644 src/templates/build.rs.rp.template create mode 100644 src/templates/main.rs.rp.template create mode 100644 src/templates/memory.x.rp.template diff --git a/ci.sh b/ci.sh index 742c3d1..ed70898 100755 --- a/ci.sh +++ b/ci.sh @@ -27,11 +27,15 @@ $cwd/target/release/cargo-embassy embassy init test-stm32g4 --chip stm32g431rb - $cwd/target/release/cargo-embassy embassy init test-nrf52840 --chip nrf52840 $cwd/target/release/cargo-embassy embassy init test-nrf52832 --chip nrf52832-xxab --softdevice s132 +# rp +$cwd/target/release/cargo-embassy embassy init test-rp2040 --chip rp2040 + # compile cd test-stm32g0; cargo build; cargo build --no-default-features --release cd ../test-stm32g4; cargo build; cargo build --no-default-features --release cd ../test-nrf52840; cargo build; cargo build --no-default-features --release cd ../test-nrf52832; cargo build; cargo build --no-default-features --release +cd ../test-rp2040; cargo build; cargo build --no-default-features --release # clean up cd ../.. diff --git a/src/chip.rs b/src/chip.rs index a2fc418..ff93195 100644 --- a/src/chip.rs +++ b/src/chip.rs @@ -48,6 +48,8 @@ impl FromStr for Chip { ("stm32wb", (STM32, Thumbv7e)), ("stm32wba", (STM32, Thumbv8)), ("stm32wl", (STM32, Thumbv7e)), + // RP2040 + ("rp2040", (RP2040, Thumbv6)), ]; let (family, target) = chips @@ -63,6 +65,7 @@ impl FromStr for Chip { STM32 => chip.to_string(), // FRAGILE: "_" is used to coerce probe-rs chip search NRF(_) => chip.split('_').next().unwrap().to_string(), + RP2040 => chip.to_string(), }, family, target, diff --git a/src/chip/family.rs b/src/chip/family.rs index 5f5d390..344a2a8 100644 --- a/src/chip/family.rs +++ b/src/chip/family.rs @@ -8,6 +8,7 @@ use std::fmt::Display; pub enum Family { STM32, NRF(MemRegion), + RP2040, } impl Display for Family { @@ -15,6 +16,7 @@ impl Display for Family { f.write_str(match self { Self::STM32 => "stm32", Self::NRF(_) => "nrf", + Self::RP2040 => "rp", }) } } diff --git a/src/chip/family/mem_region.rs b/src/chip/family/mem_region.rs index fe61cc9..f91bae9 100644 --- a/src/chip/family/mem_region.rs +++ b/src/chip/family/mem_region.rs @@ -45,4 +45,11 @@ impl MemRegion { ram_origin: 0x2 << 28, ram_length: 256, }; + + pub const RP2040: Self = Self { + flash_origin: 0x10000100, + flash_length: 2048, + ram_origin: 0x2 << 28, + ram_length: 256 + }; } diff --git a/src/init.rs b/src/init.rs index 6567454..3ef8571 100644 --- a/src/init.rs +++ b/src/init.rs @@ -69,6 +69,8 @@ impl Init { if let Family::NRF(mem_reg) = chip.family { self.init_memory_x(mem_reg)?; self.pb.println("[ACTION NEEDED] You must now flash the Softdevice and configure memory.x. Instructions can be found here: https://github.com/embassy-rs/nrf-softdevice#running-examples."); + } else if let Family::RP2040 = chip.family { + self.init_memory_x_rp()?; } Ok(()) @@ -134,6 +136,7 @@ impl Init { let template = match family { Family::STM32 => include_str!("templates/build.rs.stm32.template"), Family::NRF(_) => include_str!("templates/build.rs.nrf.template"), + Family::RP2040 => include_str!("templates/build.rs.rp.template"), }; self.create_file("build.rs", template) @@ -159,7 +162,16 @@ impl Init { )?; self.cargo_add("embassy-sync", None, false)?; self.cargo_add("embassy-futures", None, false)?; - self.cargo_add("embassy-time", Some(&["tick-hz-32_768"]), false)?; + + + + self.cargo_add( + "embassy-time", + match chip.family { + Family::RP2040 => None, + _ => Some(&["tick-hz-32_768"]) + }, + false)?; match chip.family { Family::STM32 => self.cargo_add( @@ -178,6 +190,17 @@ impl Init { Some(&[chip.name.as_str(), "gpiote", "time-driver-rtc1"]), false, ), + Family::RP2040 => { + self.cargo_add( + "embassy-rp", + Some(&["unstable-pac", "time-driver", "critical-section-impl"]), + false, + )?; + + self.cargo_add("embassy-embedded-hal", None, false)?; + + Ok(()) + }, }?; if let Some(softdevice) = softdevice { @@ -195,15 +218,21 @@ impl Init { self.cargo_add(&format!("nrf-softdevice-{}", softdevice.str()), None, false)?; } - self.cargo_add( - "cortex-m", - Some(if softdevice.is_some() { - &["inline-asm"] - } else { - &["inline-asm", "critical-section-single-core"] - }), - false, - )?; + match chip.family { + Family::RP2040 => self.cargo_add("cortex-m", Some(&["inline-asm"]), false)?, + _ => { + self.cargo_add( + "cortex-m", + Some(if softdevice.is_some() { + &["inline-asm"] + } else { + &["inline-asm", "critical-section-single-core"] + }), + false, + )?; + } + } + self.cargo_add("cortex-m-rt", None, false)?; self.cargo_add("defmt", None, true)?; self.cargo_add("defmt-rtt", None, true)?; @@ -272,6 +301,12 @@ impl Init { panic_handler = panic_handler ) } + (Family::RP2040, _) => { + format!( + include_str!("templates/main.rs.rp.template"), + panic_handler = panic_handler + ) + } }, ) } @@ -289,6 +324,13 @@ impl Init { ) } + fn init_memory_x_rp(&self) -> Result<(), Error> { + self.create_file( + "memory.x", + &include_str!("templates/memory.x.rp.template"), + ) + } + fn create_file(&self, name: &str, content: &str) -> Result<(), Error> { self.pb.set_message(format!("Create file: {name}")); diff --git a/src/templates/build.rs.rp.template b/src/templates/build.rs.rp.template new file mode 100644 index 0000000..575de05 --- /dev/null +++ b/src/templates/build.rs.rp.template @@ -0,0 +1,36 @@ +//! This build script copies the `memory.x` file from the crate root into +//! a directory where the linker can always find it at build time. +//! For many projects this is optional, as the linker always searches the +//! project root directory -- wherever `Cargo.toml` is. However, if you +//! are using a workspace or have a more complicated build setup, this +//! build script becomes required. Additionally, by requesting that +//! Cargo re-run the build script whenever `memory.x` is changed, +//! updating `memory.x` ensures a rebuild of the application with the +//! new memory settings. + +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; + +fn main() {{ + // Put `memory.x` in our output directory and ensure it's + // on the linker search path. + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + + // By default, Cargo will re-run a build script whenever + // any file in the project changes. By specifying `memory.x` + // here, we ensure the build script is only re-run when + // `memory.x` is changed. + println!("cargo:rerun-if-changed=memory.x"); + + println!("cargo:rustc-link-arg-bins=--nmagic"); + println!("cargo:rustc-link-arg-bins=-Tlink.x"); + println!("cargo:rustc-link-arg-bins=-Tlink-rp.x"); + println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); +}} \ No newline at end of file diff --git a/src/templates/main.rs.rp.template b/src/templates/main.rs.rp.template new file mode 100644 index 0000000..c654d53 --- /dev/null +++ b/src/templates/main.rs.rp.template @@ -0,0 +1,30 @@ +#![no_std] +#![no_main] + +mod fmt; + +#[cfg(not(feature = "defmt"))] +use {panic_handler} as _; +#[cfg(feature = "defmt")] +use {{defmt_rtt as _, panic_probe as _}}; + +use embassy_executor::Spawner; +use embassy_rp::gpio::{{Level, Output}}; +use embassy_time::Timer; +use fmt::info; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) {{ + let p = embassy_rp::init(Default::default()); + let mut led = Output::new(p.PIN_25, Level::Low); + + loop {{ + info!("led on!"); + led.set_high(); + Timer::after_secs(1).await; + + info!("led off!"); + led.set_low(); + Timer::after_secs(1).await; + }} +}} diff --git a/src/templates/memory.x.rp.template b/src/templates/memory.x.rp.template new file mode 100644 index 0000000..4077aab --- /dev/null +++ b/src/templates/memory.x.rp.template @@ -0,0 +1,15 @@ +MEMORY { + BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100 + FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100 + RAM : ORIGIN = 0x20000000, LENGTH = 256K +} + +EXTERN(BOOT2_FIRMWARE) + +SECTIONS { + /* ### Boot loader */ + .boot2 ORIGIN(BOOT2) : + { + KEEP(*(.boot2)); + } > BOOT2 +} INSERT BEFORE .text; From ee57e552051f0d4989657dfabc560bfae45dc37f Mon Sep 17 00:00:00 2001 From: sli Date: Sat, 6 Jul 2024 17:32:19 -0500 Subject: [PATCH 2/3] updated readme --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4f3db28..70c08b7 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Get up and running with Embassy in seconds. # Features -- Supports STM32* and NRF* +- Supports STM32*, NRF*, and RP* - Generates project structure - Toolchain - Probing @@ -57,3 +57,8 @@ cargo embassy init my_project --chip nrf52840 ```sh cargo embassy init my_project --chip nrf52832_xxAA --softdevice s132 ``` + +**Create a new Embassy project for the RP Pico** +```sh +cargo embassy init my_project --chip rp2040 +``` \ No newline at end of file From edf6c7ef774837c476ddcd9e174577a4a8ffc3c6 Mon Sep 17 00:00:00 2001 From: Adin Ackerman Date: Mon, 8 Jul 2024 08:23:17 -0700 Subject: [PATCH 3/3] fix build errors, fix leaked SD message --- src/init.rs | 54 ++++++++----------- src/templates/build.rs.rp.template | 5 +- ...emory.x.template => memory.x.nrf.template} | 0 3 files changed, 26 insertions(+), 33 deletions(-) rename src/templates/{memory.x.template => memory.x.nrf.template} (100%) diff --git a/src/init.rs b/src/init.rs index 3ef8571..6e18dc7 100644 --- a/src/init.rs +++ b/src/init.rs @@ -1,9 +1,5 @@ use crate::{ - chip::{ - family::{mem_region::MemRegion, Family}, - target::Target, - Chip, - }, + chip::{family::Family, target::Target, Chip}, cli::init_args::{panic_handler::PanicHandler, soft_device::Softdevice, InitArgs}, error::{Error, InvalidChip}, }; @@ -65,12 +61,10 @@ impl Init { )?; self.init_fmt()?; self.init_main(&chip.family, &args.panic_handler, args.softdevice.as_ref())?; + self.init_memory_x(&chip.family)?; - if let Family::NRF(mem_reg) = chip.family { - self.init_memory_x(mem_reg)?; + if args.softdevice.is_some() { self.pb.println("[ACTION NEEDED] You must now flash the Softdevice and configure memory.x. Instructions can be found here: https://github.com/embassy-rs/nrf-softdevice#running-examples."); - } else if let Family::RP2040 = chip.family { - self.init_memory_x_rp()?; } Ok(()) @@ -163,15 +157,14 @@ impl Init { self.cargo_add("embassy-sync", None, false)?; self.cargo_add("embassy-futures", None, false)?; - - self.cargo_add( "embassy-time", match chip.family { Family::RP2040 => None, - _ => Some(&["tick-hz-32_768"]) + _ => Some(&["tick-hz-32_768"]), }, - false)?; + false, + )?; match chip.family { Family::STM32 => self.cargo_add( @@ -200,7 +193,7 @@ impl Init { self.cargo_add("embassy-embedded-hal", None, false)?; Ok(()) - }, + } }?; if let Some(softdevice) = softdevice { @@ -311,24 +304,23 @@ impl Init { ) } - fn init_memory_x(&self, memory: MemRegion) -> Result<(), Error> { - self.create_file( - "memory.x", - &format!( - include_str!("templates/memory.x.template"), - flash_origin = memory.flash_origin, - flash_len = memory.flash_length, - ram_origin = memory.ram_origin, - ram_len = memory.ram_length, + fn init_memory_x(&self, family: &Family) -> Result<(), Error> { + match family { + Family::NRF(mem) => self.create_file( + "memory.x", + &format!( + include_str!("templates/memory.x.nrf.template"), + flash_origin = mem.flash_origin, + flash_len = mem.flash_length, + ram_origin = mem.ram_origin, + ram_len = mem.ram_length, + ), ), - ) - } - - fn init_memory_x_rp(&self) -> Result<(), Error> { - self.create_file( - "memory.x", - &include_str!("templates/memory.x.rp.template"), - ) + Family::RP2040 => { + self.create_file("memory.x", &include_str!("templates/memory.x.rp.template")) + } + _ => Ok(()), + } } fn create_file(&self, name: &str, content: &str) -> Result<(), Error> { diff --git a/src/templates/build.rs.rp.template b/src/templates/build.rs.rp.template index 575de05..a665707 100644 --- a/src/templates/build.rs.rp.template +++ b/src/templates/build.rs.rp.template @@ -13,7 +13,7 @@ use std::fs::File; use std::io::Write; use std::path::PathBuf; -fn main() {{ +fn main() { // Put `memory.x` in our output directory and ensure it's // on the linker search path. let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); @@ -32,5 +32,6 @@ fn main() {{ println!("cargo:rustc-link-arg-bins=--nmagic"); println!("cargo:rustc-link-arg-bins=-Tlink.x"); println!("cargo:rustc-link-arg-bins=-Tlink-rp.x"); + #[cfg(feature = "defmt")] println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); -}} \ No newline at end of file +} diff --git a/src/templates/memory.x.template b/src/templates/memory.x.nrf.template similarity index 100% rename from src/templates/memory.x.template rename to src/templates/memory.x.nrf.template