diff --git a/firmware/.cargo/config.toml b/firmware/.cargo/config.toml index 2ba1943..f632639 100644 --- a/firmware/.cargo/config.toml +++ b/firmware/.cargo/config.toml @@ -4,24 +4,13 @@ target = "xtensa-esp32-espidf" [target.xtensa-esp32-espidf] linker = "ldproxy" runner = "espflash flash --monitor" -# Future - necessary for the experimental "native build" of esp-idf-sys with ESP32C3 -# See also https://github.com/ivmarkov/embuild/issues/16 -rustflags = ["--cfg", "espidf_time64"] +rustflags = [ "--cfg", "espidf_time64"] [unstable] build-std = ["std", "panic_abort"] [env] -# Enables the esp-idf-sys "native" build feature (`cargo build --features native`) to build against ESP-IDF (v5.3.2) -ESP_IDF_VERSION = { value = "tag:v5.3.2" } +MCU="esp32" +# Note: this variable is not used by the pio builder (`cargo build --features pio`) +ESP_IDF_VERSION = "v5.2.3" -# These configurations will pick up your custom "sdkconfig.release", "sdkconfig.debug" or "sdkconfig.defaults[.*]" files -# that you might put in the root of the project -# The easiest way to generate a full "sdkconfig[.release|debug]" configuration (as opposed to manually enabling only the necessary flags via "sdkconfig.defaults[.*]" -# is by running "cargo pio espidf menuconfig" (that is, if using the pio builder) -#ESP_IDF_SDKCONFIG = { value = "./sdkconfig.release", relative = true } -#ESP_IDF_SDKCONFIG = { value = "./sdkconfig.debug", relative = true } -ESP_IDF_SDKCONFIG_DEFAULTS = { value = "./sdkconfig.defaults", relative = true } -# ESP-IDF will be installed in ~/.espressif so it can be reused across the different examples. -# See also https://github.com/esp-rs/esp-idf-sys/blob/master/BUILD-OPTIONS.md#esp_idf_tools_install_dir-esp_idf_tools_install_dir -ESP_IDF_TOOLS_INSTALL_DIR = { value = "fromenv" } diff --git a/firmware/.gitignore b/firmware/.gitignore index 8835ff2..73a638b 100644 --- a/firmware/.gitignore +++ b/firmware/.gitignore @@ -1,21 +1,4 @@ -# Generated by Cargo -# will have compiled files and executables -debug/ -target/ -.vscode/ - -# These are backup files generated by rustfmt -**/*.rs.bk - -# MSVC Windows builds of rustc generate these, which store debugging information -*.pdb - -# RustRover -# JetBrains specific template is maintained in a separate JetBrains.gitignore that can -# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# and can be added to the global gitignore or merged into this file. For a more nuclear -# option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ - -# esp-idf -.embuild/ \ No newline at end of file +/.vscode +/.embuild +/target +/Cargo.lock diff --git a/firmware/Cargo.lock b/firmware/Cargo.lock index ae1a88a..01fdb1f 100644 --- a/firmware/Cargo.lock +++ b/firmware/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 4 +version = 3 [[package]] name = "aho-corasick" @@ -163,9 +163,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.27" +version = "1.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" +checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362" dependencies = [ "shlex", ] @@ -621,11 +621,9 @@ dependencies = [ name = "firmware" version = "0.1.0" dependencies = [ - "anyhow", "embuild", "esp-idf-svc", "log", - "toml-cfg", ] [[package]] @@ -1210,15 +1208,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_spanned" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" -dependencies = [ - "serde", -] - [[package]] name = "shlex" version = "1.3.0" @@ -1350,40 +1339,11 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "toml" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml-cfg" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68c587298ddd135c156e92e8c3eae69614d6eecea8e2d8a09daab011e5e6a21d" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "serde", - "syn 2.0.104", - "toml", -] - [[package]] name = "toml_datetime" version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", -] [[package]] name = "toml_edit" @@ -1392,19 +1352,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap", - "serde", - "serde_spanned", "toml_datetime", - "toml_write", "winnow", ] -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - [[package]] name = "uncased" version = "0.9.10" diff --git a/firmware/Cargo.toml b/firmware/Cargo.toml index 48ade66..9724ed8 100644 --- a/firmware/Cargo.toml +++ b/firmware/Cargo.toml @@ -1,26 +1,47 @@ [package] name = "firmware" version = "0.1.0" -edition = "2024" +authors = ["Clara Dautermann "] +edition = "2021" resolver = "2" +rust-version = "1.77" [[bin]] name = "firmware" -harness = false # We can't use the default rust libtest harness for a crosscompile target +harness = false # do not use the built in cargo test harness -> resolve rust-analyzer errors [profile.release] opt-level = "s" [profile.dev] -debug = true # Symbols are nice and they don't increase the size on Flash +debug = true # Symbols are nice and they don't increase the size on Flash opt-level = "z" +[features] +default = [] + +experimental = ["esp-idf-svc/experimental"] + [dependencies] -anyhow = "1.0.98" -esp-idf-svc = "0.51.0" -log = "=0.4.27" -toml-cfg = "=0.2.0" +log = "0.4" +esp-idf-svc = "0.51" + +# --- Optional Embassy Integration --- +# esp-idf-svc = { version = "0.51", features = ["critical-section", "embassy-time-driver", "embassy-sync"] } + +# If you enable embassy-time-driver, you MUST also add one of: + +# a) Standalone Embassy libs ( embassy-time, embassy-sync etc) with a foreign async runtime: +# embassy-time = { version = "0.4.0", features = ["generic-queue-8"] } # NOTE: any generic-queue variant will work + +# b) With embassy-executor: +# embassy-executor = { version = "0.7", features = ["executor-thread", "arch-std"] } + +# NOTE: if you use embassy-time with embassy-executor you don't need the generic-queue-8 feature + +# --- Temporary workaround for embassy-executor < 0.8 --- +# esp-idf-svc = { version = "0.51", features = ["embassy-time-driver", "embassy-sync"] } +# critical-section = { version = "1.1", features = ["std"], default-features = false } [build-dependencies] -embuild = "=0.33.0" -toml-cfg = "=0.2.0" \ No newline at end of file +embuild = "0.33" diff --git a/firmware/build.rs b/firmware/build.rs index a76b496..112ec3f 100644 --- a/firmware/build.rs +++ b/firmware/build.rs @@ -1,52 +1,3 @@ fn main() { - linker_be_nice(); - // make sure linkall.x is the last linker script (otherwise might cause problems with flip-link) - println!("cargo:rustc-link-arg=-Tlinkall.x"); -} - -fn linker_be_nice() { - let args: Vec = std::env::args().collect(); - if args.len() > 1 { - let kind = &args[1]; - let what = &args[2]; - - match kind.as_str() { - "undefined-symbol" => match what.as_str() { - "_defmt_timestamp" => { - eprintln!(); - eprintln!("💡 `defmt` not found - make sure `defmt.x` is added as a linker script and you have included `use defmt_rtt as _;`"); - eprintln!(); - } - "_stack_start" => { - eprintln!(); - eprintln!("💡 Is the linker script `linkall.x` missing?"); - eprintln!(); - } - "esp_wifi_preempt_enable" - | "esp_wifi_preempt_yield_task" - | "esp_wifi_preempt_task_create" => { - eprintln!(); - eprintln!("💡 `esp-wifi` has no scheduler enabled. Make sure you have the `builtin-scheduler` feature enabled, or that you provide an external scheduler."); - eprintln!(); - } - "embedded_test_linker_file_not_added_to_rustflags" => { - eprintln!(); - eprintln!("💡 `embedded-test` not found - make sure `embedded-test.x` is added as a linker script for tests"); - eprintln!(); - } - _ => (), - }, - // we don't have anything helpful for "missing-lib" yet - _ => { - std::process::exit(1); - } - } - - std::process::exit(0); - } - - println!( - "cargo:rustc-link-arg=-Wl,--error-handling-script={}", - std::env::current_exe().unwrap().display() - ); + embuild::espidf::sysenv::output(); } diff --git a/firmware/rust-toolchain.toml b/firmware/rust-toolchain.toml index 8270120..a2f5ab5 100644 --- a/firmware/rust-toolchain.toml +++ b/firmware/rust-toolchain.toml @@ -1,3 +1,2 @@ [toolchain] -channel = "esp" #nightly-2025-01-01 -components = ["rust-src"] +channel = "esp" diff --git a/firmware/sdkconfig.defaults b/firmware/sdkconfig.defaults new file mode 100644 index 0000000..c25b89d --- /dev/null +++ b/firmware/sdkconfig.defaults @@ -0,0 +1,10 @@ +# Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) +CONFIG_ESP_MAIN_TASK_STACK_SIZE=8000 + +# Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). +# This allows to use 1 ms granularity for thread sleeps (10 ms by default). +#CONFIG_FREERTOS_HZ=1000 + +# Workaround for https://github.com/espressif/esp-idf/issues/7631 +#CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +#CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n diff --git a/firmware/src/main.rs b/firmware/src/main.rs index 5a00db8..9f40bc6 100644 --- a/firmware/src/main.rs +++ b/firmware/src/main.rs @@ -1,14 +1,10 @@ -use anyhow::{bail, Result}; -use esp_idf_svc::eventloop::EspSystemEventLoop; -use esp_idf_svc::hal::prelude::Peripherals; -use log::info; - -fn main() -> Result<()> { +fn main() { + // It is necessary to call this function once. Otherwise some patches to the runtime + // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71 esp_idf_svc::sys::link_patches(); + + // Bind the log crate to the ESP Logging facilities esp_idf_svc::log::EspLogger::initialize_default(); - let peripherals = Peripherals::take().unwrap(); - let sysloop = EspSystemEventLoop::take()?; - - info!("Hello, world!"); + log::info!("Hello, world!"); } diff --git a/flake.nix b/flake.nix index 6e6ac13..47e2647 100644 --- a/flake.nix +++ b/flake.nix @@ -13,13 +13,28 @@ # Optionally pin to a specific commit of `nixpkgs-esp-dev`. rev = "f37890edc9b327fcbc6d48c4cf174e65e4c0d148"; }; - forEachSupportedSystem = f: nixpkgs.lib.genAttrs supportedSystems (system: f { - pkgs = import nixpkgs { inherit system; overlays = [ (import "${nixpkgs-esp-dev}/overlay.nix") ]; }; - }); + + forEachSupportedSystem = f: nixpkgs.lib.genAttrs supportedSystems (system: + let + pkgs = import nixpkgs { inherit system; overlays = [ (import "${nixpkgs-esp-dev}/overlay.nix") ]; }; + + libxml2Shared = pkgs.libxml2.overrideAttrs (old: { + configureFlags = (old.configureFlags or [ ]) ++ [ "--enable-shared" ]; + + # cursed patch necessary to fix linking errors + postInstall = '' + ln -sf libxml2.so $out/lib/libxml2.so.2 + ${old.postInstall or ""} + ''; + }); + in + f { inherit pkgs libxml2Shared; } + ); + in { devShells = forEachSupportedSystem - ({ pkgs }: { + ({ pkgs, libxml2Shared }: { default = pkgs.mkShell { packages = with pkgs; [ @@ -27,7 +42,23 @@ espflash cargo-espflash espup + + llvmPackages_16.libclang # Explicitly add libclang + llvmPackages_16.clang # Include clang/headers + pkg-config # Often needed for bindgen to find clang + glibc.dev # Needed for C headers + libxml2Shared.out + ldproxy ]; + + env = { + # Set LD_LIBRARY_PATH so libstdc++.so.6 zlib and libxml2 can be found + LD_LIBRARY_PATH = with pkgs; pkgs.lib.makeLibraryPath [ + gcc.cc.lib + zlib + libxml2Shared.out + ]; + }; }; }); };