commit c12b7d5b5cc9556cf7090de622ec5f6779373d8b
parent ba46b929e8b44967c818bab49edc3d4a1f5f5b0c
Author: Florian Gebhardt <me@fgardt.dev>
Date: Sat, 5 Jul 2025 21:45:57 +0200
feat: add defmt support
Diffstat:
11 files changed, 181 insertions(+), 43 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -3,6 +3,44 @@
version = 4
[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "defmt"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "548d977b6da32fa1d1fda2876453da1e7df63ad0304c8b3dae4dbe7b96f39b78"
+dependencies = [
+ "bitflags",
+ "defmt-macros",
+]
+
+[[package]]
+name = "defmt-macros"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d4fc12a85bcf441cfe44344c4b72d58493178ce635338a3f3b78943aceb258e"
+dependencies = [
+ "defmt-parser",
+ "proc-macro-error2",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "defmt-parser"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e"
+dependencies = [
+ "thiserror",
+]
+
+[[package]]
name = "embedded-storage"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -12,6 +50,7 @@ checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032"
name = "esp-hal-ota"
version = "0.4.1"
dependencies = [
+ "defmt",
"embedded-storage",
"esp32",
"esp32c2",
@@ -93,6 +132,83 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
+name = "proc-macro-error-attr2"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5"
+dependencies = [
+ "proc-macro2",
+ "quote",
+]
+
+[[package]]
+name = "proc-macro-error2"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802"
+dependencies = [
+ "proc-macro-error-attr2",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.104"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "thiserror"
+version = "2.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "2.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
+
+[[package]]
name = "vcell"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
@@ -11,6 +11,7 @@ repository = "https://github.com/filipton/esp-hal-ota"
[dependencies]
embedded-storage = "0.3.1"
log = { version = "0.4.26", optional = true }
+defmt = { version = "1.0.1", optional = true }
esp32 = { version = "0.37.0", optional = true }
@@ -24,8 +25,9 @@ esp32c6 = { version = "0.20.0", optional = true }
esp32h2 = { version = "0.16.0", optional = true }
[features]
-default = ["log"]
+default = []
log = ["dep:log"]
+defmt = ["dep:defmt"]
esp32 = ["dep:esp32"]
diff --git a/src/lib.rs b/src/lib.rs
@@ -3,6 +3,9 @@
#![cfg_attr(feature = "esp32", feature(asm_experimental_arch))]
#![doc = include_str!("../README.md")]
+#[macro_use]
+mod logging;
+
use embedded_storage::{ReadStorage, Storage};
pub use structs::*;
@@ -34,8 +37,7 @@ where
pub fn new(mut flash: S) -> Result<Self> {
let pinfo = Self::read_partitions(&mut flash)?;
if pinfo.ota_partitions_count < 2 {
- #[cfg(feature = "log")]
- log::error!("Not enough OTA partitions! (>= 2)");
+ error!("Not enough OTA partitions! (>= 2)");
return Err(OtaError::NotEnoughPartitions);
}
@@ -71,8 +73,7 @@ where
/// Returns ota progress in f32 (0..1)
pub fn get_ota_progress(&self) -> f32 {
if self.progress.is_none() {
- #[cfg(feature = "log")]
- log::warn!("[OTA] Cannot get ota progress! Seems like update wasn't started yet.");
+ warn!("[OTA] Cannot get ota progress! Seems like update wasn't started yet.");
return 0.0;
}
@@ -99,11 +100,9 @@ where
.write(progress.flash_offset, &chunk[..write_size])
.map_err(|_| OtaError::FlashRWError)?;
- #[cfg(feature = "log")]
- log::debug!(
+ debug!(
"[OTA] Wrote {} bytes to ota partition at 0x{:x}",
- write_size,
- progress.flash_offset
+ write_size, progress.flash_offset
);
progress.last_crc = crc32::calc_crc32(&chunk[..write_size], progress.last_crc);
@@ -118,8 +117,7 @@ where
pub fn ota_flush(&mut self, verify: bool, rollback: bool) -> Result<()> {
if verify {
if !self.ota_verify()? {
- #[cfg(feature = "log")]
- log::error!("[OTA] Verify failed! Not flushing...");
+ error!("[OTA] Verify failed! Not flushing...");
return Err(OtaError::OtaVerifyError);
}
@@ -131,12 +129,9 @@ where
.ok_or_else(|| OtaError::OtaNotStarted)?;
if progress.target_crc != progress.last_crc {
- #[cfg(feature = "log")]
- {
- log::warn!("[OTA] Calculated crc: {:?}", progress.last_crc);
- log::warn!("[OTA] Target crc: {:?}", progress.target_crc);
- log::error!("[OTA] Crc check failed! Cant finish ota update...");
- }
+ warn!("[OTA] Calculated crc: {}", progress.last_crc);
+ warn!("[OTA] Target crc: {}", progress.target_crc);
+ error!("[OTA] Crc check failed! Cant finish ota update...");
return Err(OtaError::WrongCRC);
}
@@ -217,8 +212,7 @@ where
1 => self.pinfo.otadata_offset,
2 => self.pinfo.otadata_offset + (self.pinfo.otadata_size >> 1),
_ => {
- #[cfg(feature = "log")]
- log::error!("Use slot1 or slot2!");
+ error!("Use slot1 or slot2!");
return Err(OtaError::CannotFindCurrentBootPartition);
}
};
@@ -303,8 +297,7 @@ where
if current_slot.ota_state != OtaImgState::EspOtaImgValid {
self.set_ota_state(current_slot_nmb, OtaImgState::EspOtaImgValid)?;
- #[cfg(feature = "log")]
- log::info!("Marked current slot as valid!");
+ info!("Marked current slot as valid!");
}
Ok(())
@@ -315,8 +308,7 @@ where
if current_slot.ota_state != OtaImgState::EspOtaImgValid {
self.set_ota_state(current_slot_nmb, OtaImgState::EspOtaImgInvalid)?;
- #[cfg(feature = "log")]
- log::info!("Marked current slot as invalid!");
+ info!("Marked current slot as invalid!");
}
Ok(())
diff --git a/src/logging.rs b/src/logging.rs
@@ -0,0 +1,35 @@
+macro_rules! debug {
+ ($($arg:tt)*) => {
+ #[cfg(feature = "defmt")]
+ defmt::debug!($($arg)*);
+ #[cfg(feature = "log")]
+ log::debug!($($arg)*);
+ };
+}
+
+macro_rules! info {
+ ($($arg:tt)*) => {
+ #[cfg(feature = "defmt")]
+ defmt::info!($($arg)*);
+ #[cfg(feature = "log")]
+ log::info!($($arg)*);
+ };
+}
+
+macro_rules! warn {
+ ($($arg:tt)*) => {
+ #[cfg(feature = "defmt")]
+ defmt::warn!($($arg)*);
+ #[cfg(feature = "log")]
+ log::warn!($($arg)*);
+ };
+}
+
+macro_rules! error {
+ ($($arg:tt)*) => {
+ #[cfg(feature = "defmt")]
+ defmt::error!($($arg)*);
+ #[cfg(feature = "log")]
+ log::error!($($arg)*);
+ };
+}
diff --git a/src/mmu_hal.rs b/src/mmu_hal.rs
@@ -27,8 +27,7 @@ pub fn esp_get_current_running_partition(partitions: &[(u32, u32)]) -> Option<us
let entry_id = crate::mmu_ll::mmu_ll_get_entry_id(mmu_id, ptr as u32);
if !crate::mmu_ll::mmu_ll_check_entry_valid(mmu_id, entry_id) {
- #[cfg(feature = "log")]
- log::error!("mmu_ll_check_entry_valid failed!");
+ error!("mmu_ll_check_entry_valid failed!");
return None;
}
diff --git a/src/mmu_ll/esp32.rs b/src/mmu_ll/esp32.rs
@@ -43,8 +43,7 @@ pub fn mmu_ll_get_entry_id(_mmu_id: u32, vaddr: u32) -> u32 {
shift_code = 15;
vaddr_mask = SOC_MMU_VADDR_MASK >> 1;
} else {
- #[cfg(feature = "log")]
- log::error!("mmu_ll_get_entry_id failed!");
+ error!("mmu_ll_get_entry_id failed!");
}
offset + ((vaddr & vaddr_mask) >> shift_code)
diff --git a/src/mmu_ll/esp32c2.rs b/src/mmu_ll/esp32c2.rs
@@ -24,8 +24,7 @@ pub fn mmu_ll_get_entry_id(mmu_id: u32, vaddr: u32) -> u32 {
MMU_PAGE_32KB => 15,
MMU_PAGE_16KB => 14,
_ => {
- #[cfg(feature = "log")]
- log::error!("mmu_ll_get_entry_id failed!");
+ error!("mmu_ll_get_entry_id failed!");
0
}
@@ -40,8 +39,7 @@ pub fn mmu_ll_entry_id_to_paddr_base(mmu_id: u32, entry_id: u32) -> u32 {
MMU_PAGE_32KB => 15,
MMU_PAGE_16KB => 14,
_ => {
- #[cfg(feature = "log")]
- log::error!("mmu_ll_entry_id_to_paddr_base failed!");
+ error!("mmu_ll_entry_id_to_paddr_base failed!");
0
}
diff --git a/src/mmu_ll/esp32c6.rs b/src/mmu_ll/esp32c6.rs
@@ -1,4 +1,4 @@
-use crate::mmu_hal::{MMU_PAGE_16KB, MMU_PAGE_32KB, MMU_PAGE_64KB, MMU_PAGE_8KB};
+use crate::mmu_hal::{MMU_PAGE_8KB, MMU_PAGE_16KB, MMU_PAGE_32KB, MMU_PAGE_64KB};
const SOC_MMU_ENTRY_NUM: u32 = 256;
const SOC_MMU_VALID_VAL_MASK: u32 = 0x1ff;
@@ -27,8 +27,7 @@ pub fn mmu_ll_get_entry_id(mmu_id: u32, vaddr: u32) -> u32 {
MMU_PAGE_16KB => 14,
MMU_PAGE_8KB => 13,
_ => {
- #[cfg(feature = "log")]
- log::error!("mmu_ll_get_entry_id failed!");
+ error!("mmu_ll_get_entry_id failed!");
0
}
@@ -44,8 +43,7 @@ pub fn mmu_ll_entry_id_to_paddr_base(mmu_id: u32, entry_id: u32) -> u32 {
MMU_PAGE_16KB => 14,
MMU_PAGE_8KB => 13,
_ => {
- #[cfg(feature = "log")]
- log::error!("mmu_ll_entry_id_to_paddr_base failed!");
+ error!("mmu_ll_entry_id_to_paddr_base failed!");
0
}
diff --git a/src/mmu_ll/esp32h2.rs b/src/mmu_ll/esp32h2.rs
@@ -1,4 +1,4 @@
-use crate::mmu_hal::{MMU_PAGE_16KB, MMU_PAGE_32KB, MMU_PAGE_64KB, MMU_PAGE_8KB};
+use crate::mmu_hal::{MMU_PAGE_8KB, MMU_PAGE_16KB, MMU_PAGE_32KB, MMU_PAGE_64KB};
const SOC_MMU_ENTRY_NUM: u32 = 256;
const SOC_MMU_VALID_VAL_MASK: u32 = 0x1ff;
@@ -27,8 +27,7 @@ pub fn mmu_ll_get_entry_id(mmu_id: u32, vaddr: u32) -> u32 {
MMU_PAGE_16KB => 14,
MMU_PAGE_8KB => 13,
_ => {
- #[cfg(feature = "log")]
- log::error!("mmu_ll_get_entry_id failed!");
+ error!("mmu_ll_get_entry_id failed!");
0
}
@@ -44,8 +43,7 @@ pub fn mmu_ll_entry_id_to_paddr_base(mmu_id: u32, entry_id: u32) -> u32 {
MMU_PAGE_16KB => 14,
MMU_PAGE_8KB => 13,
_ => {
- #[cfg(feature = "log")]
- log::error!("mmu_ll_entry_id_to_paddr_base failed!");
+ error!("mmu_ll_entry_id_to_paddr_base failed!");
0
}
diff --git a/src/mmu_ll/esp32s2.rs b/src/mmu_ll/esp32s2.rs
@@ -39,8 +39,7 @@ pub fn mmu_ll_get_entry_id(_mmu_id: u32, vaddr: u32) -> u32 {
} else if soc_address_in_bus!(SOC_DRAM0_CACHE, vaddr) {
PRO_CACHE_DBUS0_MMU_START / 4
} else {
- #[cfg(feature = "log")]
- log::error!("mmu_ll_get_entry_id failed!");
+ error!("mmu_ll_get_entry_id failed!");
0
};
diff --git a/src/structs.rs b/src/structs.rs
@@ -1,6 +1,7 @@
pub(crate) type Result<T> = core::result::Result<T, OtaError>;
#[derive(Debug, PartialEq)]
+#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum OtaError {
NotEnoughPartitions,
OtaNotStarted,
@@ -33,6 +34,7 @@ pub struct PartitionInfo {
#[repr(u32)]
#[derive(Debug, PartialEq)]
+#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum OtaImgState {
EspOtaImgNew = 0x0,
EspOtaImgPendingVerify = 0x1,