From 6f76c0ebccf1d3d7b8712eaa145f6033b277a6ae Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 1 Dec 2020 17:46:56 +0100 Subject: [PATCH] Add support for log+defmt again, but better. --- embassy-nrf/Cargo.toml | 3 +- embassy-nrf/src/fmt.rs | 110 +++++++++++++++++++++++++++++++ embassy-nrf/src/gpiote.rs | 5 +- embassy-nrf/src/interrupt.rs | 3 +- embassy-nrf/src/lib.rs | 3 + embassy-nrf/src/qspi.rs | 2 +- embassy-nrf/src/uarte.rs | 2 +- embassy/Cargo.toml | 3 +- embassy/src/executor/executor.rs | 3 +- embassy/src/flash.rs | 3 +- embassy/src/fmt.rs | 110 +++++++++++++++++++++++++++++++ embassy/src/io/error.rs | 3 +- embassy/src/lib.rs | 3 + embassy/src/rand.rs | 2 +- embassy/src/time/duration.rs | 3 +- embassy/src/time/instant.rs | 3 +- embassy/src/time/mod.rs | 2 +- embassy/src/util/drop_bomb.rs | 2 +- embassy/src/util/portal.rs | 2 +- embassy/src/util/signal.rs | 2 +- examples/Cargo.toml | 8 +-- test-build.sh | 5 ++ 22 files changed, 261 insertions(+), 21 deletions(-) create mode 100644 embassy-nrf/src/fmt.rs create mode 100644 embassy/src/fmt.rs diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index d1538908..7fe285c6 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml @@ -21,7 +21,8 @@ defmt-error = [ ] [dependencies] embassy = { version = "0.1.0", path = "../embassy" } -defmt = { version = "0.1.2" } +defmt = { version = "0.1.3", optional = true } +log = { version = "0.4.11", optional = true } cortex-m-rt = "0.6.13" cortex-m = { version = "0.6.4" } embedded-hal = { version = "0.2.4" } diff --git a/embassy-nrf/src/fmt.rs b/embassy-nrf/src/fmt.rs new file mode 100644 index 00000000..93dda67d --- /dev/null +++ b/embassy-nrf/src/fmt.rs @@ -0,0 +1,110 @@ +#![macro_use] + +#[cfg(all(feature = "defmt", feature = "log"))] +compile_error!("You may not enable both `defmt` and `log` features."); + +pub use fmt::*; + +#[cfg(feature = "defmt")] +mod fmt { + pub use defmt::{ + assert, assert_eq, assert_ne, debug, debug_assert, debug_assert_eq, debug_assert_ne, error, + info, panic, todo, trace, unreachable, unwrap, warn, + }; +} + +#[cfg(feature = "log")] +mod fmt { + pub use core::{ + assert, assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, panic, todo, + unreachable, + }; + pub use log::{debug, error, info, trace, warn}; +} + +#[cfg(not(any(feature = "defmt", feature = "log")))] +mod fmt { + #![macro_use] + + pub use core::{ + assert, assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, panic, todo, + unreachable, + }; + + #[macro_export] + macro_rules! trace { + ($($msg:expr),*) => { + () + }; + } + + #[macro_export] + macro_rules! debug { + ($($msg:expr),*) => { + () + }; + } + + #[macro_export] + macro_rules! info { + ($($msg:expr),*) => { + () + }; + } + + #[macro_export] + macro_rules! warn { + ($($msg:expr),*) => { + () + }; + } + + #[macro_export] + macro_rules! error { + ($($msg:expr),*) => { + () + }; + } +} + +#[cfg(not(feature = "defmt"))] +#[macro_export] +macro_rules! unwrap { + ($arg:expr$(,$msg:expr)*) => { + match $crate::fmt::Try::into_result($arg) { + ::core::result::Result::Ok(t) => t, + ::core::result::Result::Err(e) => { + panic!($($msg,)*); + } + } + } +} + +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub struct NoneError; + +pub trait Try { + type Ok; + type Error; + fn into_result(self) -> Result; +} + +impl Try for Option { + type Ok = T; + type Error = NoneError; + + #[inline] + fn into_result(self) -> Result { + self.ok_or(NoneError) + } +} + +impl Try for Result { + type Ok = T; + type Error = E; + + #[inline] + fn into_result(self) -> Self { + self + } +} diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index bb15cca6..069e9140 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs @@ -1,8 +1,8 @@ +use crate::fmt::{panic, *}; use core::cell::Cell; use core::future::Future; use core::ptr; use core::task::{Context, Poll}; -use defmt::{panic, *}; use embassy::util::Signal; use crate::hal::gpio::{Input, Level, Output, Pin, Port}; @@ -51,7 +51,8 @@ pub enum OutputChannelPolarity { Toggle, } -#[derive(Debug, Copy, Clone, Eq, PartialEq, defmt::Format)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum NewChannelError { NoFreeChannels, } diff --git a/embassy-nrf/src/interrupt.rs b/embassy-nrf/src/interrupt.rs index 384426ea..17fc9ab3 100644 --- a/embassy-nrf/src/interrupt.rs +++ b/embassy-nrf/src/interrupt.rs @@ -12,7 +12,8 @@ pub use crate::pac::Interrupt; pub use crate::pac::Interrupt::*; // needed for cortex-m-rt #[interrupt] pub use cortex_m::interrupt::{CriticalSection, Mutex}; -#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, defmt::Format)] +#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[repr(u8)] pub enum Priority { Level0 = 0, diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 8efd6c56..7b3368d6 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -48,6 +48,9 @@ pub use nrf52833_hal as hal; #[cfg(feature = "52840")] pub use nrf52840_hal as hal; +// This mod MUST go first, so that the others see its macros. +pub(crate) mod fmt; + pub mod gpiote; pub mod interrupt; #[cfg(feature = "52840")] diff --git a/embassy-nrf/src/qspi.rs b/embassy-nrf/src/qspi.rs index 75cbe7dd..79fc7029 100644 --- a/embassy-nrf/src/qspi.rs +++ b/embassy-nrf/src/qspi.rs @@ -1,5 +1,5 @@ +use crate::fmt::{assert, assert_eq, panic, *}; use core::future::Future; -use defmt::{assert, assert_eq, panic, *}; use crate::hal::gpio::{Output, Pin as GpioPin, Port as GpioPort, PushPull}; use crate::pac::{Interrupt, QSPI}; diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 0f2030c9..3a33e759 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs @@ -28,7 +28,7 @@ pub use uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; use embassy::io::{AsyncBufRead, AsyncWrite, Result}; use embassy::util::WakerStore; -use defmt::{assert, panic, todo, *}; +use crate::fmt::{assert, panic, todo, *}; //use crate::trace; diff --git a/embassy/Cargo.toml b/embassy/Cargo.toml index 832b06fd..0e4c801b 100644 --- a/embassy/Cargo.toml +++ b/embassy/Cargo.toml @@ -13,7 +13,8 @@ defmt-warn = [] defmt-error = [] [dependencies] -defmt = { version = "0.1.0" } +defmt = { version = "0.1.3", optional = true } +log = { version = "0.4.11", optional = true } cortex-m = "0.6.4" futures = { version = "0.3.5", default-features = false } diff --git a/embassy/src/executor/executor.rs b/embassy/src/executor/executor.rs index ff3a8517..4d73cf9f 100644 --- a/embassy/src/executor/executor.rs +++ b/embassy/src/executor/executor.rs @@ -63,7 +63,8 @@ pub struct Task { future: UninitCell, // Valid if STATE_RUNNING } -#[derive(Copy, Clone, Debug, defmt::Format)] +#[derive(Copy, Clone, Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum SpawnError { Busy, } diff --git a/embassy/src/flash.rs b/embassy/src/flash.rs index 5d62e3b6..ca9fb595 100644 --- a/embassy/src/flash.rs +++ b/embassy/src/flash.rs @@ -1,6 +1,7 @@ use core::future::Future; -#[derive(Copy, Clone, Debug, Eq, PartialEq, defmt::Format)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { Failed, AddressMisaligned, diff --git a/embassy/src/fmt.rs b/embassy/src/fmt.rs new file mode 100644 index 00000000..93dda67d --- /dev/null +++ b/embassy/src/fmt.rs @@ -0,0 +1,110 @@ +#![macro_use] + +#[cfg(all(feature = "defmt", feature = "log"))] +compile_error!("You may not enable both `defmt` and `log` features."); + +pub use fmt::*; + +#[cfg(feature = "defmt")] +mod fmt { + pub use defmt::{ + assert, assert_eq, assert_ne, debug, debug_assert, debug_assert_eq, debug_assert_ne, error, + info, panic, todo, trace, unreachable, unwrap, warn, + }; +} + +#[cfg(feature = "log")] +mod fmt { + pub use core::{ + assert, assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, panic, todo, + unreachable, + }; + pub use log::{debug, error, info, trace, warn}; +} + +#[cfg(not(any(feature = "defmt", feature = "log")))] +mod fmt { + #![macro_use] + + pub use core::{ + assert, assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, panic, todo, + unreachable, + }; + + #[macro_export] + macro_rules! trace { + ($($msg:expr),*) => { + () + }; + } + + #[macro_export] + macro_rules! debug { + ($($msg:expr),*) => { + () + }; + } + + #[macro_export] + macro_rules! info { + ($($msg:expr),*) => { + () + }; + } + + #[macro_export] + macro_rules! warn { + ($($msg:expr),*) => { + () + }; + } + + #[macro_export] + macro_rules! error { + ($($msg:expr),*) => { + () + }; + } +} + +#[cfg(not(feature = "defmt"))] +#[macro_export] +macro_rules! unwrap { + ($arg:expr$(,$msg:expr)*) => { + match $crate::fmt::Try::into_result($arg) { + ::core::result::Result::Ok(t) => t, + ::core::result::Result::Err(e) => { + panic!($($msg,)*); + } + } + } +} + +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub struct NoneError; + +pub trait Try { + type Ok; + type Error; + fn into_result(self) -> Result; +} + +impl Try for Option { + type Ok = T; + type Error = NoneError; + + #[inline] + fn into_result(self) -> Result { + self.ok_or(NoneError) + } +} + +impl Try for Result { + type Ok = T; + type Error = E; + + #[inline] + fn into_result(self) -> Self { + self + } +} diff --git a/embassy/src/io/error.rs b/embassy/src/io/error.rs index 8bbdae7f..8bad0cdb 100644 --- a/embassy/src/io/error.rs +++ b/embassy/src/io/error.rs @@ -2,7 +2,8 @@ /// /// This list is intended to grow over time and it is not recommended to /// exhaustively match against it. -#[derive(Debug, Clone, Copy, PartialEq, Eq, defmt::Format)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { /// An entity was not found, often a file. NotFound, diff --git a/embassy/src/lib.rs b/embassy/src/lib.rs index 65aabef0..49ba8eea 100644 --- a/embassy/src/lib.rs +++ b/embassy/src/lib.rs @@ -4,6 +4,9 @@ #![feature(const_fn)] #![feature(const_fn_fn_ptr_basics)] +// This mod MUST go first, so that the others see its macros. +pub(crate) mod fmt; + pub mod executor; pub mod flash; pub mod io; diff --git a/embassy/src/rand.rs b/embassy/src/rand.rs index 3db164cf..7e378838 100644 --- a/embassy/src/rand.rs +++ b/embassy/src/rand.rs @@ -1,4 +1,4 @@ -use defmt::*; +use crate::fmt::*; pub trait Rand { fn rand(&self, buf: &mut [u8]); diff --git a/embassy/src/time/duration.rs b/embassy/src/time/duration.rs index 715d4155..8135961e 100644 --- a/embassy/src/time/duration.rs +++ b/embassy/src/time/duration.rs @@ -3,7 +3,8 @@ use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; use super::TICKS_PER_SECOND; -#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, defmt::Format)] +#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Duration { pub(crate) ticks: u64, } diff --git a/embassy/src/time/instant.rs b/embassy/src/time/instant.rs index a7f268e1..75098081 100644 --- a/embassy/src/time/instant.rs +++ b/embassy/src/time/instant.rs @@ -5,7 +5,8 @@ use core::ops::{Add, AddAssign, Sub, SubAssign}; use super::TICKS_PER_SECOND; use super::{now, Duration}; -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, defmt::Format)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Instant { ticks: u64, } diff --git a/embassy/src/time/mod.rs b/embassy/src/time/mod.rs index 0d97a789..d6a9a301 100644 --- a/embassy/src/time/mod.rs +++ b/embassy/src/time/mod.rs @@ -8,7 +8,7 @@ pub use instant::Instant; pub use timer::Timer; pub use traits::*; -use defmt::*; +use crate::fmt::*; // TODO allow customizing, probably via Cargo features `tick-hz-32768` or something. pub const TICKS_PER_SECOND: u64 = 32768; diff --git a/embassy/src/util/drop_bomb.rs b/embassy/src/util/drop_bomb.rs index d33591fc..b2b0684e 100644 --- a/embassy/src/util/drop_bomb.rs +++ b/embassy/src/util/drop_bomb.rs @@ -1,5 +1,5 @@ +use crate::fmt::panic; use core::mem; -use defmt::panic; pub struct DropBomb { _private: (), diff --git a/embassy/src/util/portal.rs b/embassy/src/util/portal.rs index 6eecf52c..05bdccf5 100644 --- a/embassy/src/util/portal.rs +++ b/embassy/src/util/portal.rs @@ -1,8 +1,8 @@ +use crate::fmt::panic; use core::cell::UnsafeCell; use core::future::Future; use core::mem; use core::mem::MaybeUninit; -use defmt::panic; use crate::util::*; diff --git a/embassy/src/util/signal.rs b/embassy/src/util/signal.rs index 45205368..bde10c56 100644 --- a/embassy/src/util/signal.rs +++ b/embassy/src/util/signal.rs @@ -1,8 +1,8 @@ +use crate::fmt::panic; use core::cell::UnsafeCell; use core::future::Future; use core::mem; use core::task::{Context, Poll, Waker}; -use defmt::panic; pub struct Signal { state: UnsafeCell>, diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 71d0bbd7..c845c1bf 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -17,14 +17,14 @@ defmt-error = [] [dependencies] -embassy = { version = "0.1.0", path = "../embassy", features = ["defmt-trace"] } -embassy-nrf = { version = "0.1.0", path = "../embassy-nrf", features = ["defmt-trace", "52840"] } +embassy = { version = "0.1.0", path = "../embassy", features = ["defmt", "defmt-trace"] } +embassy-nrf = { version = "0.1.0", path = "../embassy-nrf", features = ["defmt", "defmt-trace", "52840"] } -defmt = "0.1.2" +defmt = "0.1.3" defmt-rtt = "0.1.0" cortex-m = { version = "0.6.3" } -cortex-m-rt = "0.6.12" +cortex-m-rt = "0.6.13" embedded-hal = { version = "0.2.4" } panic-probe = "0.1.0" nrf52840-hal = { version = "0.12.0" } diff --git a/test-build.sh b/test-build.sh index 66128ddc..a3b5e8df 100755 --- a/test-build.sh +++ b/test-build.sh @@ -7,6 +7,8 @@ set -euxo pipefail # embassy (cd embassy; cargo build --target thumbv7em-none-eabihf) +(cd embassy; cargo build --target thumbv7em-none-eabihf --features log) +(cd embassy; cargo build --target thumbv7em-none-eabihf --features defmt) # embassy-nrf (cd embassy-nrf; cargo build --target thumbv7em-none-eabi --features 52810) @@ -15,3 +17,6 @@ set -euxo pipefail (cd embassy-nrf; cargo build --target thumbv7em-none-eabihf --features 52833) (cd embassy-nrf; cargo build --target thumbv7em-none-eabihf --features 52840) +(cd embassy-nrf; cargo build --target thumbv7em-none-eabihf --features 52840,log) +(cd embassy-nrf; cargo build --target thumbv7em-none-eabihf --features 52840,defmt) +