From 16897bb68db9cc556f35d4639edbbb691a9bce51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 5 May 2025 13:33:55 +0200 Subject: [PATCH] Tweak features and dependencies (#3425) * Group optional dependencies * Separate version from crate name * Restore defmt-log mutual exclusivity * Gate ufmt * Remove usb-device * Feature-gate unsable dependencies behind unstable * S2: assume single core for portable-atomic * Clean up feature flag docs * Sack debug * Fix clippy * Update examples * Fix usb-otg feature * Fix fmt * Add version to log dep * Also mark bluetooth private * Correct changelog/MG * Clean up esp-hal-embassy * Clean up ieee802154 * Clean up esp-println * Move the timestamp function up * Move info from readme to feature docs * Clean up esp-storage * Clean up esp-wifi * Fix examples * Add a note for the private features --- esp-hal-embassy/CHANGELOG.md | 1 + esp-hal-embassy/Cargo.toml | 31 ++-- esp-hal-embassy/src/fmt.rs | 174 +++++++++++++-------- esp-hal/CHANGELOG.md | 5 + esp-hal/Cargo.toml | 150 +++++++++++------- esp-hal/MIGRATING-1.0.0-beta.0.md | 12 ++ esp-hal/build.rs | 9 +- esp-hal/src/fmt.rs | 174 +++++++++++++-------- esp-hal/src/rng.rs | 16 +- esp-hal/src/sha.rs | 10 +- esp-ieee802154/CHANGELOG.md | 1 + esp-ieee802154/Cargo.toml | 32 ++-- esp-ieee802154/src/fmt.rs | 174 +++++++++++++-------- esp-println/CHANGELOG.md | 1 + esp-println/Cargo.toml | 52 ++++-- esp-println/README.md | 29 +--- esp-println/build.rs | 52 +++--- esp-println/src/lib.rs | 32 +++- esp-println/src/logger.rs | 31 +--- esp-storage/CHANGELOG.md | 1 + esp-storage/Cargo.toml | 43 +++-- esp-storage/src/lib.rs | 24 +-- esp-storage/src/ll.rs | 13 +- esp-wifi/CHANGELOG.md | 6 +- esp-wifi/Cargo.toml | 88 ++++++----- esp-wifi/build.rs | 13 -- esp-wifi/src/fmt.rs | 174 +++++++++++++-------- examples/Cargo.toml | 12 +- examples/src/bin/dma_extmem2mem.rs | 2 +- examples/src/bin/dma_mem2mem.rs | 2 +- examples/src/bin/embassy_multiprio.rs | 2 +- examples/src/bin/spi_loopback_dma_psram.rs | 2 +- examples/src/bin/wifi_csi.rs | 2 +- hil-test/Cargo.toml | 2 +- qa-test/Cargo.toml | 4 +- qa-test/src/bin/psram.rs | 2 +- xtask/src/lib.rs | 8 +- 37 files changed, 816 insertions(+), 570 deletions(-) diff --git a/esp-hal-embassy/CHANGELOG.md b/esp-hal-embassy/CHANGELOG.md index 1b9349b2f..55a295158 100644 --- a/esp-hal-embassy/CHANGELOG.md +++ b/esp-hal-embassy/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The `IntoAnyTimer` trait has been removed (#3444) - The `TimerCollection` trait has been sealed and renamed to `TimeBase`. Former `IntoAnyTimer` functionality has been merged into `TimeBase`. (#3444) - `esp_hal_embassy::init` will panic if called multiple times (#3444) +- The `log` feature has been replaced by `log-04`. (#3425) ### Fixed diff --git a/esp-hal-embassy/Cargo.toml b/esp-hal-embassy/Cargo.toml index 119c76a02..7faf71a2b 100644 --- a/esp-hal-embassy/Cargo.toml +++ b/esp-hal-embassy/Cargo.toml @@ -19,20 +19,27 @@ bench = false test = false [dependencies] +cfg-if = "1.0.0" critical-section = "1.2.0" -defmt = { version = "1.0.1", optional = true } +esp-hal = { version = "1.0.0-beta.0", path = "../esp-hal" } +portable-atomic = "1.11.0" +static_cell = "2.1.0" + +# Unstable dependencies that are not (strictly) part of the public API document-features = "0.2.11" -embassy-executor = { version = "0.7.0", features = ["timer-item-payload-size-4"], optional = true } embassy-sync = { version = "0.6.2" } embassy-time = { version = "0.4.0" } embassy-time-driver = { version = "0.2.0", features = [ "tick-hz-1_000_000" ] } embassy-time-queue-utils = { version = "0.1.0", features = ["_generic-queue"] } esp-config = { version = "0.3.0", path = "../esp-config" } -esp-hal = { version = "1.0.0-beta.0", path = "../esp-hal" } -log = { version = "0.4.27", optional = true } macros = { version = "0.17.0", features = ["embassy"], package = "esp-hal-procmacros", path = "../esp-hal-procmacros" } -portable-atomic = "1.11.0" -static_cell = "2.1.0" + +# Optional dependencies that enable ecosystem support. +embassy-executor = { version = "0.7.0", features = ["timer-item-payload-size-4"], optional = true } + +# Logging interfaces, they are mutually exclusive so they need to be behind separate features. +defmt = { version = "1.0.1", optional = true } +log-04 = { package = "log", version = "0.4.27", optional = true } [build-dependencies] esp-build = { version = "0.2.0", path = "../esp-build" } @@ -50,12 +57,14 @@ esp32h2 = ["esp-hal/esp32h2"] esp32s2 = ["esp-hal/esp32s2"] esp32s3 = ["esp-hal/esp32s3"] -## Implement `defmt::Format` on certain types. -defmt = ["dep:defmt", "embassy-executor?/defmt", "esp-hal/defmt"] -## Enable logging via the log crate -log = ["dep:log"] -## Provide `Executor` and `InterruptExecutor` +## Enable the `Executor` and `InterruptExecutor` embassy executor implementations. executors = ["dep:embassy-executor", "esp-hal/__esp_hal_embassy"] +#! ### Logging Feature Flags +## Enable logging output using version 0.4 of the `log` crate. +log-04 = ["dep:log-04"] +## Enable logging output using `defmt` and implement `defmt::Format` on certain types. +defmt = ["dep:defmt", "embassy-executor?/defmt", "esp-hal/defmt"] + [lints.rust] unexpected_cfgs = "allow" diff --git a/esp-hal-embassy/src/fmt.rs b/esp-hal-embassy/src/fmt.rs index 2cb1a596c..675e20ea4 100644 --- a/esp-hal-embassy/src/fmt.rs +++ b/esp-hal-embassy/src/fmt.rs @@ -5,10 +5,13 @@ macro_rules! assert { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::assert!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::assert!($($x)*); + } else { + ::core::assert!($($x)*); + } + } } }; } @@ -17,10 +20,13 @@ macro_rules! assert { macro_rules! assert_eq { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::assert_eq!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert_eq!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::assert_eq!($($x)*); + } else { + ::core::assert_eq!($($x)*); + } + } } }; } @@ -29,10 +35,13 @@ macro_rules! assert_eq { macro_rules! assert_ne { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::assert_ne!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert_ne!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::assert_ne!($($x)*); + } else { + ::core::assert_ne!($($x)*); + } + } } }; } @@ -41,10 +50,13 @@ macro_rules! assert_ne { macro_rules! debug_assert { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::debug_assert!($($x)*); + } else { + ::core::debug_assert!($($x)*); + } + } } }; } @@ -53,10 +65,13 @@ macro_rules! debug_assert { macro_rules! debug_assert_eq { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert_eq!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert_eq!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::debug_assert_eq!($($x)*); + } else { + ::core::debug_assert_eq!($($x)*); + } + } } }; } @@ -65,10 +80,13 @@ macro_rules! debug_assert_eq { macro_rules! debug_assert_ne { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert_ne!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert_ne!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::debug_assert_ne!($($x)*); + } else { + ::core::debug_assert_ne!($($x)*); + } + } } }; } @@ -77,10 +95,13 @@ macro_rules! debug_assert_ne { macro_rules! todo { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::todo!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::todo!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::todo!($($x)*); + } else { + ::core::todo!($($x)*); + } + } } }; } @@ -89,10 +110,13 @@ macro_rules! todo { macro_rules! unreachable { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::unreachable!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::unreachable!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::unreachable!($($x)*); + } else { + ::core::unreachable!($($x)*); + } + } } }; } @@ -101,10 +125,13 @@ macro_rules! unreachable { macro_rules! panic { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::panic!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::panic!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::panic!($($x)*); + } else { + ::core::panic!($($x)*); + } + } } }; } @@ -113,12 +140,15 @@ macro_rules! panic { macro_rules! trace { ($s:literal $(, $x:expr)* $(,)?) => { { - #[cfg(feature = "log")] - ::log::trace!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::trace!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::trace!($s $(, $x)*); + } else if #[cfg(feature = "log-04")] { + ::log_04::trace!($s $(, $x)*); + } else { + let _ = ($( & $x ),*); + } + } } }; } @@ -127,12 +157,15 @@ macro_rules! trace { macro_rules! debug { ($s:literal $(, $x:expr)* $(,)?) => { { - #[cfg(feature = "log")] - ::log::debug!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::debug!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::debug!($s $(, $x)*); + } else if #[cfg(feature = "log-04")] { + ::log_04::debug!($s $(, $x)*); + } else { + let _ = ($( & $x ),*); + } + } } }; } @@ -141,12 +174,15 @@ macro_rules! debug { macro_rules! info { ($s:literal $(, $x:expr)* $(,)?) => { { - #[cfg(feature = "log")] - ::log::info!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::info!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::info!($s $(, $x)*); + } else if #[cfg(feature = "log-04")] { + ::log_04::info!($s $(, $x)*); + } else { + let _ = ($( & $x ),*); + } + } } }; } @@ -155,12 +191,15 @@ macro_rules! info { macro_rules! warn { ($s:literal $(, $x:expr)* $(,)?) => { { - #[cfg(feature = "log")] - ::log::warn!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::warn!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::warn!($s $(, $x)*); + } else if #[cfg(feature = "log-04")] { + ::log_04::warn!($s $(, $x)*); + } else { + let _ = ($( & $x ),*); + } + } } }; } @@ -169,12 +208,15 @@ macro_rules! warn { macro_rules! error { ($s:literal $(, $x:expr)* $(,)?) => { { - #[cfg(feature = "log")] - ::log::error!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::error!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::error!($s $(, $x)*); + } else if #[cfg(feature = "log-04")] { + ::log_04::error!($s $(, $x)*); + } else { + let _ = ($( & $x ),*); + } + } } }; } diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index bd3805cf6..a0be12a55 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -56,6 +56,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Update `defmt` to 1.0 (#3416) - `spi::master::Spi::transfer` no longer returns the received data as a slice (#?) - esp-hal no longer clears the GPIO interrupt status bits by default. (#3408) +- `spi::master::Spi::transfer` no longer returns the received data as a slice (#3417) +- The `log` feature has been replaced by `log-04`. (#3425) +- Multiple feature flags have been replaced by `unstable`. (#3425) +- The `debug` feature has been removed. (#3425) +- The `usb_otg` and `bluetooth` features are now considered private and have been renamed accordingly. (#3425) ### Fixed diff --git a/esp-hal/Cargo.toml b/esp-hal/Cargo.toml index 504c99993..c1f52e57f 100644 --- a/esp-hal/Cargo.toml +++ b/esp-hal/Cargo.toml @@ -23,40 +23,51 @@ test = false [dependencies] bitflags = "2.9.0" bytemuck = "1.22.0" -bitfield = "0.19.0" cfg-if = "1.0.0" critical-section = { version = "1.2.0", features = ["restore-state-u32"] } -defmt = { version = "1.0.1", optional = true } -delegate = "0.13.3" -digest = { version = "0.10.7", default-features = false, optional = true } -document-features = "0.2.11" -embassy-embedded-hal = { version = "0.3.0", optional = true } -embassy-futures = "0.1.1" -embassy-sync = "0.6.2" -embassy-usb-driver = { version = "0.1.0", optional = true } -embassy-usb-synopsys-otg = { version = "0.2.0", optional = true } -embedded-can = { version = "0.4.1", optional = true } embedded-hal = "1.0.0" embedded-hal-async = "1.0.0" -embedded-io = { version = "0.6.1", optional = true } -embedded-io-async = { version = "0.6.1", optional = true } enumset = "1.1.5" +paste = "1.0.15" +portable-atomic = { version = "1.11.0", default-features = false } + +# Unstable dependencies that are not (strictly) part of the public API +bitfield = "0.19.0" +delegate = "0.13.3" +document-features = "0.2.11" +embassy-futures = "0.1.1" +embassy-sync = "0.6.2" +fugit = "0.3.7" +instability = "0.3.7" +strum = { version = "0.27.1", default-features = false, features = ["derive"] } + esp-build = { version = "0.2.0", path = "../esp-build" } esp-config = { version = "0.3.0", path = "../esp-config" } esp-metadata = { version = "0.6.0", path = "../esp-metadata", default-features = false } -esp-synopsys-usb-otg = { version = "0.4.2", optional = true, features = ["fs", "esp32sx"] } -fugit = "0.3.7" -instability = "0.3.7" -log = { version = "0.4.27", optional = true } -nb = { version = "1.1.0", optional = true } -paste = "1.0.15" -portable-atomic = { version = "1.11.0", default-features = false } procmacros = { version = "0.17.0", package = "esp-hal-procmacros", path = "../esp-hal-procmacros" } -strum = { version = "0.27.1", default-features = false, features = ["derive"] } -usb-device = { version = "0.3.2", optional = true } -rand_core06 = { package = "rand_core", version = "0.6.4", optional = true } -rand_core09 = { package = "rand_core", version = "0.9.0", optional = true } -ufmt-write = "0.1.0" + +# Dependencies that are optional because they are used by unstable drivers. +# They are needed when using the `unstable` feature. +digest = { version = "0.10.7", default-features = false, optional = true } +embassy-usb-driver = { version = "0.1.0", optional = true } +embassy-usb-synopsys-otg = { version = "0.2.0", optional = true } +embedded-can = { version = "0.4.1", optional = true } +esp-synopsys-usb-otg = { version = "0.4.2", optional = true } +nb = { version = "1.1.0", optional = true } + +# Logging interfaces, they are mutually exclusive so they need to be behind separate features. +defmt = { version = "1.0.1", optional = true } +log-04 = { package = "log", version = "0.4.27", optional = true } + +# Optional dependencies that enable ecosystem support. +# We could support individually enabling them, but there is no big downside to just +# enabling them all via the `unstable` feature. +embassy-embedded-hal = { version = "0.3.0", optional = true } +embedded-io = { version = "0.6.1", optional = true } +embedded-io-async = { version = "0.6.1", optional = true } +rand_core-06 = { package = "rand_core", version = "0.6.4", optional = true } +rand_core-09 = { package = "rand_core", version = "0.9.0", optional = true } +ufmt-write = { version = "0.1.0", optional = true } # IMPORTANT: # Each supported device MUST have its PAC included below along with a @@ -91,50 +102,78 @@ jiff = { version = "0.2.10", default-features = false, features = ["static"] } [features] default = [] -bluetooth = [] - -usb-otg = ["dep:embassy-usb-driver", "dep:embassy-usb-synopsys-otg", "dep:esp-synopsys-usb-otg", "dep:usb-device"] - +# These features are considered private and unstable. They are not covered by +# semver guarantees and may change or be removed without notice. +__bluetooth = [] __esp_hal_embassy = [] - -## Enable debug features in the HAL (used for development). -debug = [ - "esp32?/impl-register-debug", - "esp32c2?/impl-register-debug", - "esp32c3?/impl-register-debug", - "esp32c6?/impl-register-debug", - "esp32h2?/impl-register-debug", - "esp32s2?/impl-register-debug", - "esp32s3?/impl-register-debug", +__usb_otg = [ + "dep:embassy-usb-driver", + "dep:embassy-usb-synopsys-otg", + "dep:esp-synopsys-usb-otg", + "esp-synopsys-usb-otg/esp32sx", + "esp-synopsys-usb-otg/fs", ] -## Enable logging output using the `log` crate. -log = ["dep:log"] # Chip Support Feature Flags # Target the ESP32. -esp32 = ["dep:esp32", "procmacros/rtc-slow", "xtensa-lx-rt/esp32"] +esp32 = [ + "dep:esp32", + "procmacros/rtc-slow", + "xtensa-lx-rt/esp32", +] # Target the ESP32-C2. -esp32c2 = ["dep:esp32c2", "portable-atomic/unsafe-assume-single-core"] +esp32c2 = [ + "dep:esp32c2", + "portable-atomic/unsafe-assume-single-core", +] # Target the ESP32-C3. -esp32c3 = ["dep:esp32c3", "esp-riscv-rt/rtc-ram", "portable-atomic/unsafe-assume-single-core"] +esp32c3 = [ + "dep:esp32c3", + "esp-riscv-rt/rtc-ram", + "portable-atomic/unsafe-assume-single-core", +] # Target the ESP32-C6. -esp32c6 = ["dep:esp32c6", "esp-riscv-rt/rtc-ram", "procmacros/has-lp-core"] +esp32c6 = [ + "dep:esp32c6", + "esp-riscv-rt/rtc-ram", + "procmacros/has-lp-core", +] # Target the ESP32-H2. -esp32h2 = ["dep:esp32h2", "esp-riscv-rt/rtc-ram"] +esp32h2 = [ + "dep:esp32h2", + "esp-riscv-rt/rtc-ram", +] # Target the ESP32-S2. -esp32s2 = ["dep:esp32s2", "portable-atomic/critical-section", "procmacros/has-ulp-core", "procmacros/rtc-slow", "usb-otg", "xtensa-lx-rt/esp32s2"] +esp32s2 = [ + "dep:esp32s2", + "portable-atomic/unsafe-assume-single-core", + "procmacros/has-ulp-core", + "procmacros/rtc-slow", + "xtensa-lx-rt/esp32s2", + "__usb_otg", +] # Target the ESP32-S3. -esp32s3 = ["dep:esp32s3", "procmacros/has-ulp-core", "procmacros/rtc-slow", "usb-otg", "xtensa-lx-rt/esp32s3"] +esp32s3 = [ + "dep:esp32s3", + "procmacros/has-ulp-core", + "procmacros/rtc-slow", + "xtensa-lx-rt/esp32s3", + "__usb_otg", +] -#! ### Trait Implementation Feature Flags -## Implement `defmt::Format` on certain types. + +#! ### Logging Feature Flags +## Enable logging output using version 0.4 of the `log` crate. +log-04 = ["dep:log-04"] + +## Enable logging output using `defmt` and implement `defmt::Format` on certain types. defmt = [ "dep:defmt", "embassy-futures/defmt", "embassy-sync/defmt", "embedded-hal/defmt-03", - "embedded-io/defmt-03", - "embedded-io-async/defmt-03", + "embedded-io?/defmt-03", + "embedded-io-async?/defmt-03", "esp32?/defmt", "esp32c2?/defmt", "esp32c3?/defmt", @@ -146,6 +185,7 @@ defmt = [ ] #! ### PSRAM Feature Flags + ## Use externally connected PSRAM (`quad` by default, can be configured to `octal` via ESP_HAL_CONFIG_PSRAM_MODE) psram = [] @@ -156,13 +196,15 @@ psram = [] ## Enables APIs that are not stable and thus come with no stability guarantees. unstable = [ + "dep:digest", "dep:embassy-embedded-hal", "dep:embedded-can", "dep:embedded-io", "dep:embedded-io-async", - "dep:rand_core06", - "dep:rand_core09", + "dep:rand_core-06", + "dep:rand_core-09", "dep:nb", + "dep:ufmt-write", ] [lints.clippy] diff --git a/esp-hal/MIGRATING-1.0.0-beta.0.md b/esp-hal/MIGRATING-1.0.0-beta.0.md index ff4461538..666aa0399 100644 --- a/esp-hal/MIGRATING-1.0.0-beta.0.md +++ b/esp-hal/MIGRATING-1.0.0-beta.0.md @@ -352,3 +352,15 @@ Some configuration options are now unstable and they require the `unstable` feat enabled. You can learn about a particular option in the [esp-hal documentation](https://docs.espressif.com/projects/rust/esp-hal/latest/). The `ESP_HAL_CONFIG_PLACE_SPI_DRIVER_IN_RAM` configuration option has been renamed to `ESP_HAL_CONFIG_PLACE_SPI_MASTER_DRIVER_IN_RAM`. + +## Changes related to cargo features + +The `log` feature has been replaced by `log-04`. +The following dependencies are now gated behind the `unstable` feature and their +invididual features are no longer available: +- `digest` +- `ufmt-write` + +The `usb_otg` and `bluetooth` features are now considered private and have been renamed accordingly. + +The `debug` feature has been removed. If you used it, enable `impl-register-debug` on the PAC of your device. diff --git a/esp-hal/build.rs b/esp-hal/build.rs index 73cefd491..2b1384e40 100644 --- a/esp-hal/build.rs +++ b/esp-hal/build.rs @@ -8,7 +8,7 @@ use std::{ str::FromStr, }; -use esp_build::assert_unique_used_features; +use esp_build::{assert_unique_features, assert_unique_used_features}; use esp_config::{ConfigOption, Stability, Validator, Value, generate_config}; use esp_metadata::{Chip, Config}; @@ -26,6 +26,11 @@ fn main() -> Result<(), Box> { "esp32", "esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32s2", "esp32s3" ); + // Log and defmt are mutually exclusive features. The main technical reason is + // that allowing both would make the exact panicking behaviour a fragile + // implementation detail. + assert_unique_features!("log-04", "defmt"); + // NOTE: update when adding new device support! // Determine the name of the configured device: let device_name = if cfg!(feature = "esp32") { @@ -383,7 +388,7 @@ fn substitute_config(cfg: &HashMap, line: &str) -> String { #[cfg(feature = "esp32")] fn generate_memory_extras() -> Vec { - let reserve_dram = if cfg!(feature = "bluetooth") { + let reserve_dram = if cfg!(feature = "__bluetooth") { "0x10000" } else { "0x0" diff --git a/esp-hal/src/fmt.rs b/esp-hal/src/fmt.rs index 2cb1a596c..675e20ea4 100644 --- a/esp-hal/src/fmt.rs +++ b/esp-hal/src/fmt.rs @@ -5,10 +5,13 @@ macro_rules! assert { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::assert!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::assert!($($x)*); + } else { + ::core::assert!($($x)*); + } + } } }; } @@ -17,10 +20,13 @@ macro_rules! assert { macro_rules! assert_eq { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::assert_eq!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert_eq!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::assert_eq!($($x)*); + } else { + ::core::assert_eq!($($x)*); + } + } } }; } @@ -29,10 +35,13 @@ macro_rules! assert_eq { macro_rules! assert_ne { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::assert_ne!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert_ne!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::assert_ne!($($x)*); + } else { + ::core::assert_ne!($($x)*); + } + } } }; } @@ -41,10 +50,13 @@ macro_rules! assert_ne { macro_rules! debug_assert { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::debug_assert!($($x)*); + } else { + ::core::debug_assert!($($x)*); + } + } } }; } @@ -53,10 +65,13 @@ macro_rules! debug_assert { macro_rules! debug_assert_eq { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert_eq!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert_eq!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::debug_assert_eq!($($x)*); + } else { + ::core::debug_assert_eq!($($x)*); + } + } } }; } @@ -65,10 +80,13 @@ macro_rules! debug_assert_eq { macro_rules! debug_assert_ne { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert_ne!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert_ne!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::debug_assert_ne!($($x)*); + } else { + ::core::debug_assert_ne!($($x)*); + } + } } }; } @@ -77,10 +95,13 @@ macro_rules! debug_assert_ne { macro_rules! todo { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::todo!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::todo!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::todo!($($x)*); + } else { + ::core::todo!($($x)*); + } + } } }; } @@ -89,10 +110,13 @@ macro_rules! todo { macro_rules! unreachable { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::unreachable!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::unreachable!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::unreachable!($($x)*); + } else { + ::core::unreachable!($($x)*); + } + } } }; } @@ -101,10 +125,13 @@ macro_rules! unreachable { macro_rules! panic { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::panic!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::panic!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::panic!($($x)*); + } else { + ::core::panic!($($x)*); + } + } } }; } @@ -113,12 +140,15 @@ macro_rules! panic { macro_rules! trace { ($s:literal $(, $x:expr)* $(,)?) => { { - #[cfg(feature = "log")] - ::log::trace!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::trace!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::trace!($s $(, $x)*); + } else if #[cfg(feature = "log-04")] { + ::log_04::trace!($s $(, $x)*); + } else { + let _ = ($( & $x ),*); + } + } } }; } @@ -127,12 +157,15 @@ macro_rules! trace { macro_rules! debug { ($s:literal $(, $x:expr)* $(,)?) => { { - #[cfg(feature = "log")] - ::log::debug!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::debug!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::debug!($s $(, $x)*); + } else if #[cfg(feature = "log-04")] { + ::log_04::debug!($s $(, $x)*); + } else { + let _ = ($( & $x ),*); + } + } } }; } @@ -141,12 +174,15 @@ macro_rules! debug { macro_rules! info { ($s:literal $(, $x:expr)* $(,)?) => { { - #[cfg(feature = "log")] - ::log::info!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::info!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::info!($s $(, $x)*); + } else if #[cfg(feature = "log-04")] { + ::log_04::info!($s $(, $x)*); + } else { + let _ = ($( & $x ),*); + } + } } }; } @@ -155,12 +191,15 @@ macro_rules! info { macro_rules! warn { ($s:literal $(, $x:expr)* $(,)?) => { { - #[cfg(feature = "log")] - ::log::warn!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::warn!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::warn!($s $(, $x)*); + } else if #[cfg(feature = "log-04")] { + ::log_04::warn!($s $(, $x)*); + } else { + let _ = ($( & $x ),*); + } + } } }; } @@ -169,12 +208,15 @@ macro_rules! warn { macro_rules! error { ($s:literal $(, $x:expr)* $(,)?) => { { - #[cfg(feature = "log")] - ::log::error!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::error!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::error!($s $(, $x)*); + } else if #[cfg(feature = "log-04")] { + ::log_04::error!($s $(, $x)*); + } else { + let _ = ($( & $x ),*); + } + } } }; } diff --git a/esp-hal/src/rng.rs b/esp-hal/src/rng.rs index bb655ccee..f999a7ab7 100644 --- a/esp-hal/src/rng.rs +++ b/esp-hal/src/rng.rs @@ -134,7 +134,7 @@ impl Rng { impl Sealed for Rng {} #[instability::unstable] -impl rand_core06::RngCore for Rng { +impl rand_core_06::RngCore for Rng { fn next_u32(&mut self) -> u32 { self.random() } @@ -150,14 +150,14 @@ impl rand_core06::RngCore for Rng { self.read(dest); } - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core06::Error> { + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core_06::Error> { self.read(dest); Ok(()) } } #[instability::unstable] -impl rand_core09::RngCore for Rng { +impl rand_core_09::RngCore for Rng { fn next_u32(&mut self) -> u32 { self.random() } @@ -231,7 +231,7 @@ impl Drop for Trng<'_> { /// Implementing RngCore trait from rand_core for `Trng` structure #[instability::unstable] -impl rand_core06::RngCore for Trng<'_> { +impl rand_core_06::RngCore for Trng<'_> { fn next_u32(&mut self) -> u32 { self.rng.next_u32() } @@ -244,13 +244,13 @@ impl rand_core06::RngCore for Trng<'_> { self.rng.fill_bytes(dest) } - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core06::Error> { + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core_06::Error> { self.rng.try_fill_bytes(dest) } } #[instability::unstable] -impl rand_core09::RngCore for Trng<'_> { +impl rand_core_09::RngCore for Trng<'_> { fn next_u32(&mut self) -> u32 { self.rng.next_u32() } @@ -265,8 +265,8 @@ impl rand_core09::RngCore for Trng<'_> { /// Implementing a CryptoRng marker trait that indicates that the generator is /// cryptographically secure. #[instability::unstable] -impl rand_core06::CryptoRng for Trng<'_> {} +impl rand_core_06::CryptoRng for Trng<'_> {} #[instability::unstable] -impl rand_core09::CryptoRng for Trng<'_> {} +impl rand_core_09::CryptoRng for Trng<'_> {} impl Sealed for Trng<'_> {} diff --git a/esp-hal/src/sha.rs b/esp-hal/src/sha.rs index 519df5f8a..8dd273b7a 100644 --- a/esp-hal/src/sha.rs +++ b/esp-hal/src/sha.rs @@ -60,7 +60,6 @@ use core::{borrow::Borrow, convert::Infallible, marker::PhantomData, mem::size_of}; /// Re-export digest for convenience -#[cfg(feature = "digest")] pub use digest::Digest; #[cfg(not(esp32))] @@ -490,7 +489,6 @@ pub trait ShaAlgorithm: crate::private::Sealed { /// For example, in SHA-256, this would be 32 bytes. const DIGEST_LENGTH: usize; - #[cfg(feature = "digest")] #[doc(hidden)] type DigestOutputSize: digest::generic_array::ArrayLength + 'static; @@ -522,25 +520,20 @@ pub trait ShaAlgorithm: crate::private::Sealed { /// implement digest traits if digest feature is present. /// Note: digest has a blanket trait implementation for [digest::Digest] for any /// element that implements FixedOutput + Default + Update + HashMarker -#[cfg(feature = "digest")] impl<'d, A: ShaAlgorithm, S: Borrow>> digest::HashMarker for ShaDigest<'d, A, S> {} -#[cfg(feature = "digest")] impl<'d, A: ShaAlgorithm, S: Borrow>> digest::OutputSizeUser for ShaDigest<'d, A, S> { type OutputSize = A::DigestOutputSize; } -#[cfg(feature = "digest")] impl<'d, A: ShaAlgorithm, S: Borrow>> digest::Update for ShaDigest<'d, A, S> { - fn update(&mut self, data: &[u8]) { - let mut remaining = data.as_ref(); + fn update(&mut self, mut remaining: &[u8]) { while !remaining.is_empty() { remaining = nb::block!(Self::update(self, remaining)).unwrap(); } } } -#[cfg(feature = "digest")] impl<'d, A: ShaAlgorithm, S: Borrow>> digest::FixedOutput for ShaDigest<'d, A, S> { fn finalize_into(mut self, out: &mut digest::Output) { nb::block!(self.finish(out)).unwrap(); @@ -575,7 +568,6 @@ macro_rules! impl_sha { #[cfg(not(esp32))] const MODE_AS_BITS: u8 = $mode_bits; - #[cfg(feature = "digest")] // We use paste to append `U` to the digest size to match a const defined in // digest type DigestOutputSize = paste::paste!(digest::consts::[< U $digest_length >]); diff --git a/esp-ieee802154/CHANGELOG.md b/esp-ieee802154/CHANGELOG.md index d00219b6d..cce8ff97f 100644 --- a/esp-ieee802154/CHANGELOG.md +++ b/esp-ieee802154/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump Rust edition to 2024, bump MSRV to 1.85. (#3391) - Update `defmt` to 1.0 (#3416) +- The `log` feature has been replaced by `log-04`. (#3425) ### Fixed diff --git a/esp-ieee802154/Cargo.toml b/esp-ieee802154/Cargo.toml index 42b4b1679..cbef288b8 100644 --- a/esp-ieee802154/Cargo.toml +++ b/esp-ieee802154/Cargo.toml @@ -19,17 +19,23 @@ bench = false test = false [dependencies] -byte = "0.2.7" -critical-section = "1.2.0" -document-features = "0.2.11" -esp-hal = { version = "1.0.0-beta.0", path = "../esp-hal" } -esp-wifi-sys = "0.7.1" -heapless = "0.8.0" -ieee802154 = "0.6.1" cfg-if = "1.0.0" +critical-section = "1.2.0" +esp-hal = { version = "1.0.0-beta.0", path = "../esp-hal" } + +# ⚠️ Unstable dependencies that are part of the public API +heapless = "0.8.0" + +# Unstable dependencies that are not (strictly) part of the public API +byte = "0.2.7" +document-features = "0.2.11" esp-config = { version = "0.3.0", path = "../esp-config" } -defmt = { version = "1.0.1", optional = true } -log = { version = "0.4.27", optional = true } +esp-wifi-sys = "0.7.1" +ieee802154 = "0.6.1" + +# Logging interfaces, they are mutually exclusive so they need to be behind separate features. +defmt = { version = "1.0.1", optional = true } +log-04 = { package = "log", version = "0.4.27", optional = true } [build-dependencies] esp-config = { version = "0.3.0", path = "../esp-config" } @@ -38,6 +44,12 @@ esp-config = { version = "0.3.0", path = "../esp-config" } [features] esp32c6 = ["esp-hal/esp32c6", "esp-wifi-sys/esp32c6"] esp32h2 = ["esp-hal/esp32h2", "esp-wifi-sys/esp32h2"] + +## Enables log messages from the esp-wifi blobs. sys-logs = ["esp-wifi-sys/sys-logs"] -log = ["dep:log", "esp-wifi-sys/log"] + +#! ### Logging Feature Flags +## Enable logging output using version 0.4 of the `log` crate. +log-04 = ["dep:log-04", "esp-wifi-sys/log"] +## Enable logging output using `defmt` and implement `defmt::Format` on certain types. defmt = ["dep:defmt", "esp-wifi-sys/defmt"] diff --git a/esp-ieee802154/src/fmt.rs b/esp-ieee802154/src/fmt.rs index 2d572b6fa..d2b5bb590 100644 --- a/esp-ieee802154/src/fmt.rs +++ b/esp-ieee802154/src/fmt.rs @@ -7,10 +7,13 @@ use core::fmt::{Debug, Display, LowerHex}; macro_rules! assert { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::assert!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::assert!($($x)*); + } else { + ::core::assert!($($x)*); + } + } } }; } @@ -19,10 +22,13 @@ macro_rules! assert { macro_rules! assert_eq { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::assert_eq!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert_eq!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::assert_eq!($($x)*); + } else { + ::core::assert_eq!($($x)*); + } + } } }; } @@ -31,10 +37,13 @@ macro_rules! assert_eq { macro_rules! assert_ne { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::assert_ne!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert_ne!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::assert_ne!($($x)*); + } else { + ::core::assert_ne!($($x)*); + } + } } }; } @@ -43,10 +52,13 @@ macro_rules! assert_ne { macro_rules! debug_assert { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::debug_assert!($($x)*); + } else { + ::core::debug_assert!($($x)*); + } + } } }; } @@ -55,10 +67,13 @@ macro_rules! debug_assert { macro_rules! debug_assert_eq { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert_eq!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert_eq!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::debug_assert_eq!($($x)*); + } else { + ::core::debug_assert_eq!($($x)*); + } + } } }; } @@ -67,10 +82,13 @@ macro_rules! debug_assert_eq { macro_rules! debug_assert_ne { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert_ne!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert_ne!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::debug_assert_ne!($($x)*); + } else { + ::core::debug_assert_ne!($($x)*); + } + } } }; } @@ -79,10 +97,13 @@ macro_rules! debug_assert_ne { macro_rules! todo { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::todo!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::todo!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::todo!($($x)*); + } else { + ::core::todo!($($x)*); + } + } } }; } @@ -91,10 +112,13 @@ macro_rules! todo { macro_rules! unreachable { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::unreachable!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::unreachable!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::unreachable!($($x)*); + } else { + ::core::unreachable!($($x)*); + } + } } }; } @@ -103,10 +127,13 @@ macro_rules! unreachable { macro_rules! panic { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::panic!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::panic!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::panic!($($x)*); + } else { + ::core::panic!($($x)*); + } + } } }; } @@ -115,12 +142,15 @@ macro_rules! panic { macro_rules! trace { ($s:literal $(, $x:expr)* $(,)?) => { { - #[cfg(feature = "log")] - ::log::trace!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::trace!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::trace!($s $(, $x)*); + } else if #[cfg(feature = "log-04")] { + ::log_04::trace!($s $(, $x)*); + } else { + let _ = ($( & $x ),*); + } + } } }; } @@ -129,12 +159,15 @@ macro_rules! trace { macro_rules! debug { ($s:literal $(, $x:expr)* $(,)?) => { { - #[cfg(feature = "log")] - ::log::debug!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::debug!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::debug!($s $(, $x)*); + } else if #[cfg(feature = "log-04")] { + ::log_04::debug!($s $(, $x)*); + } else { + let _ = ($( & $x ),*); + } + } } }; } @@ -143,12 +176,15 @@ macro_rules! debug { macro_rules! info { ($s:literal $(, $x:expr)* $(,)?) => { { - #[cfg(feature = "log")] - ::log::info!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::info!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::info!($s $(, $x)*); + } else if #[cfg(feature = "log-04")] { + ::log_04::info!($s $(, $x)*); + } else { + let _ = ($( & $x ),*); + } + } } }; } @@ -157,12 +193,15 @@ macro_rules! info { macro_rules! warn { ($s:literal $(, $x:expr)* $(,)?) => { { - #[cfg(feature = "log")] - ::log::warn!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::warn!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::warn!($s $(, $x)*); + } else if #[cfg(feature = "log-04")] { + ::log_04::warn!($s $(, $x)*); + } else { + let _ = ($( & $x ),*); + } + } } }; } @@ -171,12 +210,15 @@ macro_rules! warn { macro_rules! error { ($s:literal $(, $x:expr)* $(,)?) => { { - #[cfg(feature = "log")] - ::log::error!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::error!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::error!($s $(, $x)*); + } else if #[cfg(feature = "log-04")] { + ::log_04::error!($s $(, $x)*); + } else { + let _ = ($( & $x ),*); + } + } } }; } diff --git a/esp-println/CHANGELOG.md b/esp-println/CHANGELOG.md index 8074db419..7572ca362 100644 --- a/esp-println/CHANGELOG.md +++ b/esp-println/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump Rust edition to 2024, bump MSRV to 1.85. (#3391) - Update `defmt` to 1.0 (#3416) +- The `log` feature has been replaced by `log-04`. (#3425) ### Fixed diff --git a/esp-println/Cargo.toml b/esp-println/Cargo.toml index 79842b182..5ea37c72c 100644 --- a/esp-println/Cargo.toml +++ b/esp-println/Cargo.toml @@ -21,21 +21,23 @@ bench = false test = false [dependencies] +document-features = "0.2.11" + +# Optional dependencies critical-section = { version = "1.2.0", optional = true } -defmt = { version = "1.0.1", optional = true } -log = { version = "0.4.27", optional = true } portable-atomic = { version = "1.11.0", optional = true, default-features = false } +# Logging interfaces, they are mutually exclusive so they need to be behind separate features. +defmt = { version = "1.0.1", optional = true } +log-04 = { package = "log", version = "0.4.27", optional = true } + [build-dependencies] esp-build = { version = "0.2.0", path = "../esp-build" } -log = "0.4.27" +log-04 = { package = "log", version = "0.4.27" } [features] default = ["auto", "colors", "critical-section"] -critical-section = ["dep:critical-section"] -log = ["dep:log"] -# You must enable exactly 1 of the below features to support the correct chip: esp32 = [] esp32c2 = [] esp32c3 = [] @@ -45,20 +47,42 @@ esp32p4 = [] esp32s2 = [] esp32s3 = [] -# You must enable exactly 1 of the below features to enable to intended -# communication method (note that "auto" is enabled by default): -jtag-serial = ["dep:portable-atomic"] # C3, C6, H2, P4, and S3 only! -uart = [] -auto = ["dep:portable-atomic"] +## Use a critical section around print calls. This ensures that the output is consistent. +critical-section = ["dep:critical-section"] -# Don't print anything +#! ### Output interfaces +#! You must enable exactly 1 of the below features to enable to intended +#! communication method. + +## Automatically select the best output interface for the target. +auto = ["dep:portable-atomic"] +## Use the `USB_SERIAL_JTAG` interface for printing. Available on ESP32-C3, ESP32-C6, ESP32-H2, ESP32-P4, and ESP32-S3. +jtag-serial = ["dep:portable-atomic"] +## Use the `UART0` peripehral for printing. Available on all devices. +uart = [] +## Don't print anything no-op = [] -# Enables a `defmt` backend usable with espflash. We force rzcobs encoding to simplify implementation +#! ### Logging framework features +## Enables using the `log` crate for logging. +log-04 = ["dep:log-04"] +## Enables printing using `defmt`. +## +## defmt-encoded output can only be read using espflash. With esp_hal, this works out of the box. +## Without esp_hal, you need to set the `--log-format defmt` argument for espflash. defmt-espflash = ["dep:defmt", "defmt?/encoding-rzcobs"] -# logging sub-features +#! ### `log`-specific features +## Colors the message severity in the terminal. colors = [] +## Prints the timestamp in the log message. +## +## This option requires the following function to be implemented: +## ```rust +## extern "Rust" { +## fn _esp_println_timestamp() -> u64; +## } +## ``` timestamp = [] [lints.rust] diff --git a/esp-println/README.md b/esp-println/README.md index 53a9bbcba..2b87167db 100644 --- a/esp-println/README.md +++ b/esp-println/README.md @@ -33,34 +33,10 @@ use esp_println::println; You can now `println!("Hello world")` as usual. -# Features - -- There is one feature for each supported target: `esp32`, `esp32c2`, - `esp32c3`, `esp32c6`, `esp32h2`, `esp32s2`, and `esp32s3`. - - One of these features must be enabled. - - Only one of these features can be enabled at a time. -- There is one feature for each supported communication method: `uart`, `jtag-serial` and `auto`. - - Only one of these features can be enabled at a time. -- `no-op`: Don't print anything. -- `log`: Enables logging using [`log` crate]. -- `colors`: Enable colored logging. - - Only effective when using the `log` feature. -- `critical-section`: Enables critical sections. -- `defmt-espflash`: This is intended to be used with [`espflash`], see `-L/--log-format` argument - of `flash` or `monitor` subcommands of `espflash` and `cargo-espflash`. Uses [rzCOBS] encoding - and adds framing. - -## Default Features - -By default, we use the `auto`, `critial-section` and `colors` features. -Which means that it will auto-detect if it needs to print to the UART or JTAG-Serial, use critical sections and output -messages will be colored. -If we want to use a communication method that is not `auto`, the default -one, we need to [disable the default features]. - ## Logging -With the feature `log` activated you can initialize a simple logger like this +With the feature `log-04` activated, and version 0.4 of the `log` crate added to your dependencies, +you can initialize a simple logger like this: ```rust init_logger(log::LevelFilter::Info); @@ -97,7 +73,6 @@ https://github.com/knurling-rs/defmt?tab=readme-ov-file#msrv [`log` crate]: https://github.com/rust-lang/log [rzCOBS]: https://github.com/Dirbaio/rzcobs [`espflash`]: https://github.com/esp-rs/espflash -[disable the default features]: https://doc.rust-lang.org/cargo/reference/features.html#the-default-feature [Implementing a Logger section log documentaion]: https://docs.rs/log/0.4.17/log/#implementing-a-logger [`defmt` book's setup instructions]: https://defmt.ferrous-systems.com/setup diff --git a/esp-println/build.rs b/esp-println/build.rs index 51159dee1..df3a8f475 100644 --- a/esp-println/build.rs +++ b/esp-println/build.rs @@ -1,6 +1,7 @@ use std::{env, path::Path}; use esp_build::assert_unique_used_features; +use log_04::LevelFilter; fn main() { // Ensure that only a single chip is specified @@ -25,10 +26,10 @@ fn main() { ); } - // Ensure that, if the `colors` is used with `log`.` - if cfg!(feature = "colors") && !cfg!(feature = "log") { + // Ensure that, if the `colors` is used with `log-04`. + if cfg!(feature = "colors") && !cfg!(feature = "log-04") { println!( - "cargo:warning=The `colors` feature is only effective when using the `log` feature" + "cargo:warning=The `colors` feature is only effective when using the `log-04` feature" ); } @@ -63,40 +64,41 @@ fn generate_filter_snippet() { .iter() .map(|v| v.level) .max() - .unwrap_or(log::LevelFilter::Off); + .unwrap_or(LevelFilter::Off); let max = match max { - log::LevelFilter::Off => "Off", - log::LevelFilter::Error => "Error", - log::LevelFilter::Warn => "Warn", - log::LevelFilter::Info => "Info", - log::LevelFilter::Debug => "Debug", - log::LevelFilter::Trace => "Trace", + LevelFilter::Off => "Off", + LevelFilter::Error => "Error", + LevelFilter::Warn => "Warn", + LevelFilter::Info => "Info", + LevelFilter::Debug => "Debug", + LevelFilter::Trace => "Trace", }; let mut snippet = String::new(); snippet.push_str(&format!( - "pub(crate) const FILTER_MAX: log::LevelFilter = log::LevelFilter::{max};" + "pub(crate) const FILTER_MAX: log_04::LevelFilter = log_04::LevelFilter::{max};" )); - snippet - .push_str("pub(crate) fn is_enabled(level: log::Level, _target: &str) -> bool {"); + snippet.push_str( + "pub(crate) fn is_enabled(level: log_04::Level, _target: &str) -> bool {", + ); let mut global_level = None; for directive in res.directives { let level = match directive.level { - log::LevelFilter::Off => "Off", - log::LevelFilter::Error => "Error", - log::LevelFilter::Warn => "Warn", - log::LevelFilter::Info => "Info", - log::LevelFilter::Debug => "Debug", - log::LevelFilter::Trace => "Trace", + LevelFilter::Off => "Off", + LevelFilter::Error => "Error", + LevelFilter::Warn => "Warn", + LevelFilter::Info => "Info", + LevelFilter::Debug => "Debug", + LevelFilter::Trace => "Trace", }; if let Some(name) = directive.name { // If a prefix matches, don't continue to the next directive snippet.push_str(&format!( - "if _target.starts_with(\"{}\") {{ return level <= log::LevelFilter::{}; }}", + "if _target.starts_with(\"{}\") {{ return level <= log_04::LevelFilter::{}; }}", &name, level )); } else { @@ -109,7 +111,7 @@ fn generate_filter_snippet() { // Place the fallback rule at the end if let Some(level) = global_level { - snippet.push_str(&format!("level <= log::LevelFilter::{level}")); + snippet.push_str(&format!("level <= log_04::LevelFilter::{level}")); } else { snippet.push_str(" false"); } @@ -117,7 +119,7 @@ fn generate_filter_snippet() { snippet } } else { - "pub(crate) const FILTER_MAX: log::LevelFilter = log::LevelFilter::Off; pub(crate) fn is_enabled(_level: log::Level, _target: &str) -> bool { true }".to_string() + "pub(crate) const FILTER_MAX: log_04::LevelFilter = log_04::LevelFilter::Off; pub(crate) fn is_enabled(_level: log_04::Level, _target: &str) -> bool { true }".to_string() }; std::fs::write(&dest_path, &snippet).unwrap(); @@ -142,7 +144,7 @@ impl ParseResult { #[derive(Debug)] struct Directive { pub(crate) name: Option, - pub(crate) level: log::LevelFilter, + pub(crate) level: LevelFilter, } /// Parse a logging specification string (e.g: @@ -167,10 +169,10 @@ fn parse_spec(spec: &str) -> ParseResult { // treat that as a global fallback match part0.parse() { Ok(num) => (num, None), - Err(_) => (log::LevelFilter::max(), Some(part0)), + Err(_) => (LevelFilter::max(), Some(part0)), } } - (Some(part0), Some(""), None) => (log::LevelFilter::max(), Some(part0)), + (Some(part0), Some(""), None) => (LevelFilter::max(), Some(part0)), (Some(part0), Some(part1), None) => { if let Ok(num) = part1.parse() { (num, Some(part0)) diff --git a/esp-println/src/lib.rs b/esp-println/src/lib.rs index 32586522f..4a098ff09 100644 --- a/esp-println/src/lib.rs +++ b/esp-println/src/lib.rs @@ -1,11 +1,13 @@ #![doc = include_str!("../README.md")] +//! ## Feature Flags +#![doc = document_features::document_features!()] #![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")] #![allow(rustdoc::bare_urls)] #![no_std] #[cfg(feature = "defmt-espflash")] pub mod defmt; -#[cfg(feature = "log")] +#[cfg(feature = "log-04")] pub mod logger; macro_rules! log_format { @@ -528,3 +530,31 @@ fn with(f: impl FnOnce(LockToken) -> R) -> R { #[cfg(not(feature = "critical-section"))] f(unsafe { LockToken::conjure() }) } + +/// A user-provided hook to supply a timestamp in milliseconds for logging. +/// +/// When enabled via the `"timestamp"` feature, this function should be +/// implemented to return a timestamp in milliseconds since a reference point +/// (e.g., system boot or Unix epoch). +/// +/// # Example +/// +/// When using [`esp-hal`], you can define this function as follows: +/// +/// ```rust +/// #[no_mangle] +/// pub extern "Rust" fn _esp_println_timestamp() -> u64 { +/// esp_hal::time::Instant::now() +/// .duration_since_epoch() +/// .as_millis() +/// } +/// ``` +/// +/// # Notes +/// +/// - If no implementations is provided, attempting to use this function will +/// result in a linker error. +#[cfg(feature = "timestamp")] +extern "Rust" { + fn _esp_println_timestamp() -> u64; +} diff --git a/esp-println/src/logger.rs b/esp-println/src/logger.rs index d4b3bb4c5..f5d01363d 100644 --- a/esp-println/src/logger.rs +++ b/esp-println/src/logger.rs @@ -1,3 +1,5 @@ +use log_04 as log; + use super::println; #[cfg(not(host_is_windows))] @@ -94,32 +96,3 @@ fn print_log_record(record: &log::Record) { #[cfg(not(feature = "timestamp"))] println!("{}{} - {}{}", color, record.level(), record.args(), reset); } - -/// A user-provided hook to supply a timestamp in milliseconds for logging. -/// -/// When enabled via the `"timestamp"` feature, this function should be -/// implemented to return a timestamp in milliseconds since a reference point -/// (e.g., system boot or Unix epoch). -/// -/// # Example -/// -/// When using [`esp-hal`], you can define this function as follows: -/// -/// ```rust -/// #[no_mangle] -/// pub extern "Rust" fn _esp_println_timestamp() -> u64 { -/// esp_hal::time::Instant::now() -/// .duration_since_epoch() -/// .as_millis() -/// } -/// ``` -/// -/// # Notes -/// -/// - If no implementations is provided, attempting to use this function will -/// result in a linker -/// error. -#[cfg(feature = "timestamp")] -extern "Rust" { - fn _esp_println_timestamp() -> u64; -} diff --git a/esp-storage/CHANGELOG.md b/esp-storage/CHANGELOG.md index ffba2cd40..1f7503c4e 100644 --- a/esp-storage/CHANGELOG.md +++ b/esp-storage/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Bump Rust edition to 2024, bump MSRV to 1.85. (#3391) +- The `low-level` feature has been removed, the gated API is always available (#3425) ### Fixed diff --git a/esp-storage/Cargo.toml b/esp-storage/Cargo.toml index a7033cc0f..6dc2191fc 100644 --- a/esp-storage/Cargo.toml +++ b/esp-storage/Cargo.toml @@ -20,28 +20,43 @@ test = false [dependencies] embedded-storage = "0.3.1" + +# Optional dependencies critical-section = { version = "1.2.0", optional = true } +# Unstable dependencies that are not (strictly) part of the public API +document-features = "0.2.11" + [build-dependencies] esp-build = { version = "0.2.0", path = "../esp-build" } [features] -default = ["critical-section"] +default = ["critical-section"] + +## Place the flash operations in a critical section critical-section = ["dep:critical-section"] -esp32c2 = [] -esp32c3 = [] -esp32c6 = [] -esp32h2 = [] -esp32 = [] -esp32s2 = [] -esp32s3 = [] - -# Bytewise read emulation +## Bytewise read emulation bytewise-read = [] -# Enable flash emulation to run tests -emulation = [] +#! ### Chip selection +#! One of the following features must be enabled to select the target chip: -# this feature is reserved for very specific use-cases - usually you don't want to use this! -low-level = [] +# The following trailing spaces ("## ") are important to display the feature names. + +## +esp32c2 = [] +## +esp32c3 = [] +## +esp32c6 = [] +## +esp32h2 = [] +## +esp32 = [] +## +esp32s2 = [] +## +esp32s3 = [] +## Used for testing on a host. +emulation = [] diff --git a/esp-storage/src/lib.rs b/esp-storage/src/lib.rs index 0be0d4d68..3bd870bf9 100644 --- a/esp-storage/src/lib.rs +++ b/esp-storage/src/lib.rs @@ -1,6 +1,7 @@ +//! ## Feature Flags +#![doc = document_features::document_features!()] #![cfg_attr(not(all(test, feature = "emulation")), no_std)] -#[cfg(not(feature = "emulation"))] #[cfg_attr(feature = "esp32c2", path = "esp32c2.rs")] #[cfg_attr(feature = "esp32c3", path = "esp32c3.rs")] #[cfg_attr(feature = "esp32c6", path = "esp32c6.rs")] @@ -8,22 +9,7 @@ #[cfg_attr(feature = "esp32", path = "esp32.rs")] #[cfg_attr(feature = "esp32s2", path = "esp32s2.rs")] #[cfg_attr(feature = "esp32s3", path = "esp32s3.rs")] -#[cfg_attr( - not(any( - feature = "esp32c2", - feature = "esp32c3", - feature = "esp32c6", - feature = "esp32", - feature = "esp32s2", - feature = "esp32s3", - feature = "esp32h2" - )), - path = "stub.rs" -)] -mod chip_specific; - -#[cfg(feature = "emulation")] -#[path = "stub.rs"] +#[cfg_attr(feature = "emulation", path = "stub.rs")] mod chip_specific; mod common; @@ -31,12 +17,10 @@ mod common; use common::FlashSectorBuffer; pub use common::{FlashStorage, FlashStorageError}; +pub mod ll; mod nor_flash; mod storage; -#[cfg(feature = "low-level")] -pub mod ll; - #[cfg(not(feature = "emulation"))] #[inline(always)] #[unsafe(link_section = ".rwtext")] diff --git a/esp-storage/src/ll.rs b/esp-storage/src/ll.rs index 0823ae7e6..7cc4ddfc4 100644 --- a/esp-storage/src/ll.rs +++ b/esp-storage/src/ll.rs @@ -1,8 +1,11 @@ -/// Low-level API -/// -/// This gives you access to the underlying low level functionality. -/// These operate on raw pointers and all functions here are unsafe. -/// No pre-conditions are checked by any of these functions. +//! # Low-level API +//! +//! ⚠️ This is a low-level API and should be used with caution. ⚠️ +//! +//! This gives you access to the underlying low level functionality. +//! These operate on raw pointers and all functions here are unsafe. +//! No pre-conditions are checked by any of these functions. + use crate::chip_specific; /// Low-level SPI NOR Flash read diff --git a/esp-wifi/CHANGELOG.md b/esp-wifi/CHANGELOG.md index 3cf9bc996..fd2079f77 100644 --- a/esp-wifi/CHANGELOG.md +++ b/esp-wifi/CHANGELOG.md @@ -14,20 +14,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - The scheduler now runs at interrupt priority 1 on Xtensa chips, too. (#3164) - - `esp-now` and `sniffer` are available via `Interfaces` (#3283) - - Remove the `heapless` dependency (including from the public API) (#3317) - - Bump Rust edition to 2024, bump MSRV to 1.85. (#3391) - Update `defmt` to 1.0 (#3416) +- The `log` feature has been replaced by `log-04`. (#3425) ### Fixed - Update bt-hci version to fix serialization/deserialization of byte slices (#3340) - - Allow `Configuration::None`, set country early, changed default power-save-mode to None (#3364) - - Enterprise WPA fixed for ESP32-S2 (#3406) - COEX on ESP32 is now working (#3403) diff --git a/esp-wifi/Cargo.toml b/esp-wifi/Cargo.toml index 7d5288203..972e41e2b 100644 --- a/esp-wifi/Cargo.toml +++ b/esp-wifi/Cargo.toml @@ -15,35 +15,40 @@ bench = false test = false [dependencies] +esp-hal = { version = "1.0.0-beta.0", path = "../esp-hal", default-features = false } +critical-section = "1.2.0" +cfg-if = "1.0.0" +portable-atomic = { version = "1.11.0", default-features = false } +enumset = { version = "1.1.5", default-features = false, optional = true } + +# ⚠️ Unstable dependencies +embedded-io = { version = "0.6.1", default-features = false } +embedded-io-async = { version = "0.6.1" } +rand_core = "0.9.3" + +# Unstable dependencies that are not (strictly) part of the public API allocator-api2 = { version = "0.2.0", default-features = false, features = ["alloc"] } -defmt = { version = "1.0.1", optional = true } -log = { version = "0.4.27", optional = true } document-features = "0.2.11" esp-alloc = { version = "0.7.0", path = "../esp-alloc", optional = true } -esp-hal = { version = "1.0.0-beta.0", path = "../esp-hal", default-features = false } +esp-config = { version = "0.3.0", path = "../esp-config" } +esp-wifi-sys = "0.7.1" +num-derive = { version = "0.4.2" } +num-traits = { version = "0.2.19", default-features = false } +portable_atomic_enum = { version = "0.3.1", features = ["portable-atomic"] } +xtensa-lx-rt = { version = "0.18.0", path = "../xtensa-lx-rt", optional = true } + +# Optional dependencies enabling ecosystem features +serde = { version = "1.0.218", default-features = false, features = ["derive"], optional = true } smoltcp = { version = "0.12.0", default-features = false, features = [ "medium-ethernet", "socket-raw", ], optional = true } -critical-section = "1.2.0" -enumset = { version = "1.1.5", default-features = false, optional = true } -embedded-io = { version = "0.6.1", default-features = false } -embedded-io-async = { version = "0.6.1" } -num-derive = { version = "0.4.2" } -num-traits = { version = "0.2.19", default-features = false } -esp-wifi-sys = "0.7.1" -embassy-sync = { version = "0.6.2", optional = true } embassy-net-driver = { version = "0.2.0", optional = true } -cfg-if = "1.0.0" -portable-atomic = { version = "1.11.0", default-features = false } -portable_atomic_enum = { version = "0.3.1", features = ["portable-atomic"] } -rand_core = "0.9.3" - bt-hci = { version = "0.3.0", optional = true } -esp-config = { version = "0.3.0", path = "../esp-config" } -xtensa-lx-rt = { version = "0.18.0", path = "../xtensa-lx-rt", optional = true } -serde = { version = "1.0.218", default-features = false, features = ["derive"], optional = true } +# Logging interfaces, they are mutually exclusive so they need to be behind separate features. +defmt = { version = "1.0.1", optional = true } +log-04 = { package = "log", version = "0.4.27", optional = true } [build-dependencies] esp-build = { version = "0.2.0", path = "../esp-build" } @@ -53,14 +58,6 @@ esp-metadata = { version = "0.6.0", path = "../esp-metadata" } [features] default = ["builtin-scheduler", "esp-alloc"] -## Use `esp-alloc` for dynamic allocations. -## -## If you opt-out you need to provide implementations for the following functions: -## - `pub extern "C" fn esp_wifi_free_internal_heap() -> usize` -## - `pub extern "C" fn esp_wifi_allocate_from_internal_ram(size: usize) -> *mut u8` -## - `pub extern "C" fn esp_wifi_deallocate_internal_ram(ptr: *mut u8)` -esp-alloc = ["dep:esp-alloc"] - # Chip Support Feature Flags # Target the ESP32-C2. esp32c2 = [ @@ -101,20 +98,24 @@ esp32s3 = [ "xtensa-lx-rt/float-save-restore", ] -## Enable WiFi-BLE coexistence support -coex = [] +## Use `esp-alloc` for dynamic allocations. +## +## If you opt-out you need to provide implementations for the following functions: +## - `pub extern "C" fn esp_wifi_free_internal_heap() -> usize` +## - `pub extern "C" fn esp_wifi_allocate_from_internal_ram(size: usize) -> *mut u8` +## - `pub extern "C" fn esp_wifi_deallocate_internal_ram(ptr: *mut u8)` +esp-alloc = ["dep:esp-alloc"] ## Logs the WiFi logs from the driver at log level info (needs a nightly-compiler) sys-logs = ["esp-wifi-sys/sys-logs"] -## Enable support for `defmt` -defmt = ["dep:defmt", "smoltcp?/defmt", "esp-hal/defmt", "bt-hci?/defmt", "esp-wifi-sys/defmt"] +## Use builtin scheduler +builtin-scheduler = [] -## Enable support for the `log` crate -log = ["dep:log", "esp-hal/log", "esp-wifi-sys/log"] +#! ### Wireless Feature Flags ## Enable WiFi support -wifi = ["dep:enumset", "dep:embassy-net-driver", "dep:embassy-sync"] +wifi = ["dep:enumset", "dep:embassy-net-driver"] ## Enable esp-now support esp-now = ["wifi"] @@ -123,20 +124,29 @@ esp-now = ["wifi"] sniffer = ["wifi"] ## Enable BLE support -ble = ["esp-hal/bluetooth", "dep:bt-hci", "dep:embassy-sync"] +ble = ["esp-hal/__bluetooth", "dep:bt-hci"] + +## Enable WiFi-BLE coexistence support +coex = [] ## Enable WiFi channel state information. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv4N18wifi_init_config_t10csi_enableE)", csi = [] +#! ### Ecosystem Feature Flags + ## Provide implementations of smoltcp traits smoltcp = ["dep:smoltcp"] -## Use builtin scheduler -builtin-scheduler = [] - -# Implement serde Serialize / Deserialize +## Implement serde Serialize / Deserialize serde = ["dep:serde", "enumset?/serde"] +#! ### Logging Feature Flags +## Enable logging output using version 0.4 of the `log` crate. +log-04 = ["dep:log-04", "esp-hal/log-04", "esp-wifi-sys/log"] + +## Enable logging output using `defmt` and implement `defmt::Format` on certain types. +defmt = ["dep:defmt", "smoltcp?/defmt", "esp-hal/defmt", "bt-hci?/defmt", "esp-wifi-sys/defmt"] + [package.metadata.docs.rs] features = [ "esp32c3", diff --git a/esp-wifi/build.rs b/esp-wifi/build.rs index dec615f5c..4692a7c80 100644 --- a/esp-wifi/build.rs +++ b/esp-wifi/build.rs @@ -299,19 +299,6 @@ fn main() -> Result<(), Box> { Ok(()) } -#[cfg(not(any( - feature = "esp32", - feature = "esp32c2", - feature = "esp32c3", - feature = "esp32c6", - feature = "esp32h2", - feature = "esp32s2", - feature = "esp32s3", -)))] -fn main() { - panic!("Select a chip via it's cargo feature"); -} - fn print_warning(message: impl core::fmt::Display) { println!("cargo:warning={message}"); } diff --git a/esp-wifi/src/fmt.rs b/esp-wifi/src/fmt.rs index 2cb1a596c..675e20ea4 100644 --- a/esp-wifi/src/fmt.rs +++ b/esp-wifi/src/fmt.rs @@ -5,10 +5,13 @@ macro_rules! assert { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::assert!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::assert!($($x)*); + } else { + ::core::assert!($($x)*); + } + } } }; } @@ -17,10 +20,13 @@ macro_rules! assert { macro_rules! assert_eq { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::assert_eq!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert_eq!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::assert_eq!($($x)*); + } else { + ::core::assert_eq!($($x)*); + } + } } }; } @@ -29,10 +35,13 @@ macro_rules! assert_eq { macro_rules! assert_ne { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::assert_ne!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert_ne!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::assert_ne!($($x)*); + } else { + ::core::assert_ne!($($x)*); + } + } } }; } @@ -41,10 +50,13 @@ macro_rules! assert_ne { macro_rules! debug_assert { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::debug_assert!($($x)*); + } else { + ::core::debug_assert!($($x)*); + } + } } }; } @@ -53,10 +65,13 @@ macro_rules! debug_assert { macro_rules! debug_assert_eq { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert_eq!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert_eq!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::debug_assert_eq!($($x)*); + } else { + ::core::debug_assert_eq!($($x)*); + } + } } }; } @@ -65,10 +80,13 @@ macro_rules! debug_assert_eq { macro_rules! debug_assert_ne { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert_ne!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert_ne!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::debug_assert_ne!($($x)*); + } else { + ::core::debug_assert_ne!($($x)*); + } + } } }; } @@ -77,10 +95,13 @@ macro_rules! debug_assert_ne { macro_rules! todo { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::todo!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::todo!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::todo!($($x)*); + } else { + ::core::todo!($($x)*); + } + } } }; } @@ -89,10 +110,13 @@ macro_rules! todo { macro_rules! unreachable { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::unreachable!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::unreachable!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::unreachable!($($x)*); + } else { + ::core::unreachable!($($x)*); + } + } } }; } @@ -101,10 +125,13 @@ macro_rules! unreachable { macro_rules! panic { ($($x:tt)*) => { { - #[cfg(not(feature = "defmt"))] - ::core::panic!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::panic!($($x)*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::panic!($($x)*); + } else { + ::core::panic!($($x)*); + } + } } }; } @@ -113,12 +140,15 @@ macro_rules! panic { macro_rules! trace { ($s:literal $(, $x:expr)* $(,)?) => { { - #[cfg(feature = "log")] - ::log::trace!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::trace!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::trace!($s $(, $x)*); + } else if #[cfg(feature = "log-04")] { + ::log_04::trace!($s $(, $x)*); + } else { + let _ = ($( & $x ),*); + } + } } }; } @@ -127,12 +157,15 @@ macro_rules! trace { macro_rules! debug { ($s:literal $(, $x:expr)* $(,)?) => { { - #[cfg(feature = "log")] - ::log::debug!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::debug!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::debug!($s $(, $x)*); + } else if #[cfg(feature = "log-04")] { + ::log_04::debug!($s $(, $x)*); + } else { + let _ = ($( & $x ),*); + } + } } }; } @@ -141,12 +174,15 @@ macro_rules! debug { macro_rules! info { ($s:literal $(, $x:expr)* $(,)?) => { { - #[cfg(feature = "log")] - ::log::info!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::info!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::info!($s $(, $x)*); + } else if #[cfg(feature = "log-04")] { + ::log_04::info!($s $(, $x)*); + } else { + let _ = ($( & $x ),*); + } + } } }; } @@ -155,12 +191,15 @@ macro_rules! info { macro_rules! warn { ($s:literal $(, $x:expr)* $(,)?) => { { - #[cfg(feature = "log")] - ::log::warn!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::warn!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::warn!($s $(, $x)*); + } else if #[cfg(feature = "log-04")] { + ::log_04::warn!($s $(, $x)*); + } else { + let _ = ($( & $x ),*); + } + } } }; } @@ -169,12 +208,15 @@ macro_rules! warn { macro_rules! error { ($s:literal $(, $x:expr)* $(,)?) => { { - #[cfg(feature = "log")] - ::log::error!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::error!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); + cfg_if::cfg_if! { + if #[cfg(feature = "defmt")] { + ::defmt::error!($s $(, $x)*); + } else if #[cfg(feature = "log-04")] { + ::log_04::error!($s $(, $x)*); + } else { + let _ = ($( & $x ),*); + } + } } }; } diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 619346675..f22b10727 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -14,9 +14,9 @@ critical-section = "1.1.3" embassy-executor = { version = "0.7.0", features = ["task-arena-size-20480"] } embassy-futures = "0.1.1" embassy-net = { version = "0.6.0", features = [ "tcp", "udp", "dhcpv4", "medium-ethernet"] } -embassy-sync = "0.6.0" +embassy-sync = "0.6.2" embassy-time = "0.4.0" -embassy-usb = { version = "0.2.0", default-features = false } +embassy-usb = { version = "0.4.0", default-features = false } embedded-hal-async = "1.0.0" embedded-io = { version = "0.6.1", default-features = false } embedded-io-async = "0.6.1" @@ -24,17 +24,17 @@ embedded-storage = "0.3.1" esp-alloc = { path = "../esp-alloc" } esp-backtrace = { path = "../esp-backtrace", features = ["exception-handler", "panic-handler", "println"] } esp-bootloader-esp-idf = { path = "../esp-bootloader-esp-idf" } -esp-hal = { path = "../esp-hal", features = ["log"] } +esp-hal = { path = "../esp-hal", features = ["log-04"] } esp-hal-embassy = { path = "../esp-hal-embassy", optional = true } esp-ieee802154 = { path = "../esp-ieee802154", optional = true } -esp-println = { path = "../esp-println", features = ["log"] } +esp-println = { path = "../esp-println", features = ["log-04"] } esp-storage = { path = "../esp-storage", optional = true } -esp-wifi = { path = "../esp-wifi", features = ["log"], optional = true } +esp-wifi = { path = "../esp-wifi", features = ["log-04"], optional = true } heapless = "0.8.0" hmac = { version = "0.12.1", default-features = false } ieee80211 = { version = "0.4.0", default-features = false } ieee802154 = "0.6.1" -log = "0.4.22" +log = "0.4.27" nb = "1.1.0" sha2 = { version = "0.10.8", default-features = false } smoltcp = { version = "0.12.0", default-features = false, features = [ "medium-ethernet", "socket-raw"] } diff --git a/examples/src/bin/dma_extmem2mem.rs b/examples/src/bin/dma_extmem2mem.rs index ceab43e30..096348aef 100644 --- a/examples/src/bin/dma_extmem2mem.rs +++ b/examples/src/bin/dma_extmem2mem.rs @@ -2,7 +2,7 @@ //! //! If your module is octal PSRAM then you need to set `ESP_HAL_CONFIG_PSRAM_MODE` to `octal`. -//% FEATURES: esp-hal/log esp-hal/psram aligned esp-hal/unstable +//% FEATURES: esp-hal/psram aligned esp-hal/unstable //% CHIPS: esp32s3 #![no_std] diff --git a/examples/src/bin/dma_mem2mem.rs b/examples/src/bin/dma_mem2mem.rs index a6a9d7643..fca3a292c 100644 --- a/examples/src/bin/dma_mem2mem.rs +++ b/examples/src/bin/dma_mem2mem.rs @@ -1,6 +1,6 @@ //! Uses DMA to copy memory to memory. -//% FEATURES: esp-hal/log esp-hal/unstable +//% FEATURES: esp-hal/unstable //% CHIPS: esp32s2 esp32s3 esp32c2 esp32c3 esp32c6 esp32h2 #![no_std] diff --git a/examples/src/bin/embassy_multiprio.rs b/examples/src/bin/embassy_multiprio.rs index e3693b34e..a1249b822 100644 --- a/examples/src/bin/embassy_multiprio.rs +++ b/examples/src/bin/embassy_multiprio.rs @@ -15,7 +15,7 @@ // The interrupt-executor is created in `main` and is used to spawn `high_prio`. //% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3 -//% FEATURES: embassy esp-hal-embassy/log esp-hal/unstable +//% FEATURES: embassy esp-hal-embassy/log-04 esp-hal/unstable #![no_std] #![no_main] diff --git a/examples/src/bin/spi_loopback_dma_psram.rs b/examples/src/bin/spi_loopback_dma_psram.rs index 5167f6684..bb37f1f77 100644 --- a/examples/src/bin/spi_loopback_dma_psram.rs +++ b/examples/src/bin/spi_loopback_dma_psram.rs @@ -15,7 +15,7 @@ //! //! If your module is octal PSRAM then you need to set `ESP_HAL_CONFIG_PSRAM_MODE` to `octal`. -//% FEATURES: esp-hal/log esp-hal/psram esp-hal/unstable +//% FEATURES: esp-hal/psram esp-hal/unstable //% CHIPS: esp32s3 #![no_std] diff --git a/examples/src/bin/wifi_csi.rs b/examples/src/bin/wifi_csi.rs index dd7ae2f4f..17d4a8954 100644 --- a/examples/src/bin/wifi_csi.rs +++ b/examples/src/bin/wifi_csi.rs @@ -4,7 +4,7 @@ //! Set SSID and PASSWORD env variable before running this example. //! -//% FEATURES: esp-wifi esp-wifi/wifi esp-wifi/smoltcp esp-wifi/log esp-wifi/csi esp-hal/unstable +//% FEATURES: esp-wifi esp-wifi/wifi esp-wifi/smoltcp esp-wifi/log-04 esp-wifi/csi esp-hal/unstable //% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6 #![no_std] diff --git a/hil-test/Cargo.toml b/hil-test/Cargo.toml index 331315b71..184fddcc7 100644 --- a/hil-test/Cargo.toml +++ b/hil-test/Cargo.toml @@ -238,7 +238,7 @@ embedded-hal-async = "1.0.0" embedded-hal-nb = "1.0.0" esp-alloc = { path = "../esp-alloc", optional = true } esp-backtrace = { path = "../esp-backtrace", default-features = false, features = ["exception-handler", "defmt", "semihosting"] } -esp-hal = { path = "../esp-hal", features = ["digest"], optional = true } +esp-hal = { path = "../esp-hal", optional = true } esp-hal-embassy = { path = "../esp-hal-embassy", optional = true } esp-storage = { path = "../esp-storage", optional = true } esp-wifi = { path = "../esp-wifi", optional = true } diff --git a/qa-test/Cargo.toml b/qa-test/Cargo.toml index 65bb92319..db51f0586 100644 --- a/qa-test/Cargo.toml +++ b/qa-test/Cargo.toml @@ -15,9 +15,9 @@ embedded-graphics = "0.8.1" embedded-hal-async = "1.0.0" esp-alloc = { path = "../esp-alloc" } esp-backtrace = { path = "../esp-backtrace", features = ["exception-handler", "panic-handler", "println"] } -esp-hal = { path = "../esp-hal", features = ["unstable", "log"] } +esp-hal = { path = "../esp-hal", features = ["unstable", "log-04"] } esp-hal-embassy = { path = "../esp-hal-embassy" } -esp-println = { path = "../esp-println", features = ["log"] } +esp-println = { path = "../esp-println", features = ["log-04"] } lis3dh-async = "0.9.3" ssd1306 = "0.10.0" diff --git a/qa-test/src/bin/psram.rs b/qa-test/src/bin/psram.rs index 0c2926f66..43315dcbe 100644 --- a/qa-test/src/bin/psram.rs +++ b/qa-test/src/bin/psram.rs @@ -6,7 +6,7 @@ //! the device comes with octal-SPIRAM //% CHIPS: esp32 esp32s2 esp32s3 -//% FEATURES: esp-hal/psram esp-alloc/internal-heap-stats esp-hal/log +//% FEATURES: esp-hal/psram esp-alloc/internal-heap-stats #![no_std] #![no_main] diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs index 7f60a3510..484e68c0f 100644 --- a/xtask/src/lib.rs +++ b/xtask/src/lib.rs @@ -112,10 +112,10 @@ impl Package { features.push("psram".to_owned()) } if config.contains("usb0") { - features.push("usb-otg".to_owned()); + features.push("__usb_otg".to_owned()); } if config.contains("bt") { - features.push("bluetooth".to_owned()); + features.push("__bluetooth".to_owned()); } } Package::EspWifi => { @@ -157,9 +157,7 @@ impl Package { features.push("auto".to_owned()); features.push("defmt-espflash".to_owned()); } - Package::EspStorage => { - features.push("low-level".to_owned()); - } + Package::EspStorage => {} Package::EspBootloaderEspIdf => { features.push("defmt".to_owned()); features.push("validation".to_owned());