From e8babedd87932f43e3fa9c75c12dd74c4d3a67c6 Mon Sep 17 00:00:00 2001 From: ivmarkov Date: Mon, 12 Jun 2023 11:41:33 +0000 Subject: [PATCH] Support for ESP-IDF build --- Cargo.toml | 2 +- README.md | 24 +++++++++++++++++++++--- examples/onoff_light/src/main.rs | 31 ++++++++++++++++++------------- matter/Cargo.toml | 19 +++++++++++++------ matter/build.rs | 11 +++++++++++ matter/src/transport/udp.rs | 2 ++ 6 files changed, 66 insertions(+), 23 deletions(-) create mode 100644 matter/build.rs diff --git a/Cargo.toml b/Cargo.toml index 7561a52..11f05af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["matter", "matter_macro_derive", "tools/tlv_tool"] +members = ["matter", "matter_macro_derive"] exclude = ["examples/*"] diff --git a/README.md b/README.md index 80cb2b2..86de880 100644 --- a/README.md +++ b/README.md @@ -47,13 +47,31 @@ Building the library: $ cargo build ``` -Building the example: +Building and running the example (Linux, MacOS X): ``` -$ RUST_LOG="matter" cargo run --example onoff_light +$ cargo run --example onoff_light ``` -With the chip-tool (the current tool for testing Matter) use the Ethernet commissioning mechanism: +Building the example (Espressif's ESP-IDF): +* Install all build prerequisites described [here](https://github.com/esp-rs/esp-idf-template#prerequisites) +* Build with the following command line: +``` +export MCU=esp32; export CARGO_TARGET_XTENSA_ESP32_ESPIDF_LINKER=ldproxy; export RUSTFLAGS="-C default-linker-libraries"; export WIFI_SSID=ssid;export WIFI_PASS=pass; cargo build --example onoff_light --no-default-features --features std,crypto_rustcrypto --target xtensa-esp32-espidf -Zbuild-std=std,panic_abort +``` +* If you are building for a different Espressif MCU, change the `MCU` variable, the `xtensa-esp32-espidf` target and the name of the `CARGO_TARGET__LINKER` variable to match your MCU and its Rust target. Available Espressif MCUs and targets are: + * esp32 / xtensa-esp32-espidf + * esp32s2 / xtensa-esp32s2-espidf + * esp32s3 / xtensa-esp32s3-espidf + * esp32c3 / riscv32imc-esp-espidf + * esp32c5 / riscv32imc-esp-espidf + * esp32c6 / risxcv32imac-esp-espidf +* Put in `WIFI_SSID` / `WIFI_PASS` the SSID & password for your wireless router +* Flash using the `espflash` utility described in the build prerequsites' link above + +## Test + +With the `chip-tool` (the current tool for testing Matter) use the Ethernet commissioning mechanism: ``` $ chip-tool pairing code 12344321 diff --git a/examples/onoff_light/src/main.rs b/examples/onoff_light/src/main.rs index e26f20f..069f1dd 100644 --- a/examples/onoff_light/src/main.rs +++ b/examples/onoff_light/src/main.rs @@ -31,7 +31,6 @@ use matter::data_model::system_model::descriptor; use matter::error::Error; use matter::interaction_model::core::InteractionModel; use matter::mdns::{DefaultMdns, DefaultMdnsRunner}; -use matter::persist; use matter::secure_channel::spake2p::VerifierData; use matter::transport::network::{Address, IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; use matter::transport::{ @@ -50,7 +49,6 @@ fn main() -> Result<(), Error> { .unwrap(); thread.join().unwrap() - // run() } #[cfg(not(feature = "std"))] @@ -105,17 +103,21 @@ fn run() -> Result<(), Error> { let psm_path = std::env::temp_dir().join("matter-iot"); info!("Persisting from/to {}", psm_path.display()); - let psm = persist::FilePsm::new(psm_path)?; + #[cfg(all(feature = "std", not(target_os = "espidf")))] + let psm = matter::persist::FilePsm::new(psm_path)?; let mut buf = [0; 4096]; let buf = &mut buf; - if let Some(data) = psm.load("acls", buf)? { - matter.load_acls(data)?; - } + #[cfg(all(feature = "std", not(target_os = "espidf")))] + { + if let Some(data) = psm.load("acls", buf)? { + matter.load_acls(data)?; + } - if let Some(data) = psm.load("fabrics", buf)? { - matter.load_fabrics(data)?; + if let Some(data) = psm.load("fabrics", buf)? { + matter.load_fabrics(data)?; + } } let mut transport = Transport::new(&matter); @@ -180,12 +182,15 @@ fn run() -> Result<(), Error> { } } - if let Some(data) = transport.matter().store_fabrics(buf)? { - psm.store("fabrics", data)?; - } + #[cfg(all(feature = "std", not(target_os = "espidf")))] + { + if let Some(data) = transport.matter().store_fabrics(buf)? { + psm.store("fabrics", data)?; + } - if let Some(data) = transport.matter().store_acls(buf)? { - psm.store("acls", data)?; + if let Some(data) = transport.matter().store_acls(buf)? { + psm.store("acls", data)?; + } } } diff --git a/matter/Cargo.toml b/matter/Cargo.toml index 2f859b7..5b8816d 100644 --- a/matter/Cargo.toml +++ b/matter/Cargo.toml @@ -16,7 +16,6 @@ path = "src/lib.rs" [features] default = ["os", "crypto_rustcrypto"] -#default = ["crypto_rustcrypto"] os = ["std", "backtrace", "env_logger", "nix", "critical-section/std", "embassy-sync/std", "embassy-time/std"] std = ["alloc", "rand", "qrcode", "async-io", "smol", "esp-idf-sys/std"] backtrace = [] @@ -51,7 +50,6 @@ domain = { version = "0.7.2", default_features = false, features = ["heapless"] # STD-only dependencies rand = { version = "0.8.5", optional = true } qrcode = { version = "0.12", default-features = false, optional = true } # Print QR code -astro-dnssd = { version = "0.3", optional = true } # On Linux needs avahi-compat-libdns_sd, i.e. on Ubuntu/Debian do `sudo apt-get install libavahi-compat-libdnssd-dev` smol = { version = "1.2", optional = true } # =1.2 for compatibility with ESP IDF async-io = { version = "=1.12", optional = true } # =1.2 for compatibility with ESP IDF @@ -72,18 +70,27 @@ crypto-bigint = { version = "0.4", default-features = false, optional = true } rand_core = { version = "0.6", default-features = false, optional = true } x509-cert = { version = "0.2.0", default-features = false, features = ["pem"], optional = true } # TODO: requires `alloc` +[target.'cfg(target_os = "macos")'.dependencies] +astro-dnssd = { version = "0.3" } + [target.'cfg(not(target_os = "espidf"))'.dependencies] mbedtls = { git = "https://github.com/fortanix/rust-mbedtls", optional = true } env_logger = { version = "0.10.0", optional = true } nix = { version = "0.26", features = ["net"], optional = true } [target.'cfg(target_os = "espidf")'.dependencies] -esp-idf-sys = { version = "0.33", default-features = false, features = ["native"] } +esp-idf-sys = { version = "0.33", default-features = false, features = ["native", "binstart"] } +esp-idf-hal = { version = "0.41", features = ["embassy-sync", "critical-section"] } +esp-idf-svc = { version = "0.46", features = ["embassy-time-driver"] } +embedded-svc = "0.25" + +[build-dependencies] +embuild = "0.31.2" [[example]] name = "onoff_light" path = "../examples/onoff_light/src/main.rs" -[[example]] -name = "speaker" -path = "../examples/speaker/src/main.rs" +# [[example]] +# name = "speaker" +# path = "../examples/speaker/src/main.rs" diff --git a/matter/build.rs b/matter/build.rs new file mode 100644 index 0000000..9e17e10 --- /dev/null +++ b/matter/build.rs @@ -0,0 +1,11 @@ +use std::env::var; + +// Necessary because of this issue: https://github.com/rust-lang/cargo/issues/9641 +fn main() -> Result<(), Box> { + if var("TARGET").unwrap().ends_with("-espidf") { + embuild::build::CfgArgs::output_propagated("ESP_IDF")?; + embuild::build::LinkArgs::output_propagated("ESP_IDF")?; + } + + Ok(()) +} diff --git a/matter/src/transport/udp.rs b/matter/src/transport/udp.rs index 5308462..0aa6573 100644 --- a/matter/src/transport/udp.rs +++ b/matter/src/transport/udp.rs @@ -52,6 +52,8 @@ mod smol_udp { IpAddr::V6(ip_addr) => self.socket.join_multicast_v6(&ip_addr, 0)?, } + info!("Joining multicast on {:?}", ip_addr); + Ok(()) }