diff --git a/CHANGELOG.md b/CHANGELOG.md index ddc03a74..95ed2030 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,10 +7,21 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +## [v0.7.5] - 2022-05-15 + ### Deprecated - the `ptr()` function on all peripherals register blocks in favor of the associated constant `PTR` (#386). +### Changed + +- The `inline-asm` feature no longer requires a nightly Rust compiler, but + does require Rust 1.59 or above. + +### Fixed +- Fixed `singleton!()` statics sometimes ending up in `.data` instead of `.bss` (#364, #380). + (Backported from upcoming 0.8 release). + ## [v0.7.4] - 2021-12-31 ### Added @@ -735,7 +746,8 @@ fn main() { - Functions to get the vector table - Wrappers over miscellaneous instructions like `bkpt` -[Unreleased]: https://github.com/rust-embedded/cortex-m/compare/v0.7.4...HEAD +[Unreleased]: https://github.com/rust-embedded/cortex-m/compare/v0.7.5...HEAD +[v0.7.5]: https://github.com/rust-embedded/cortex-m/compare/v0.7.4...v0.7.5 [v0.7.4]: https://github.com/rust-embedded/cortex-m/compare/v0.7.3...v0.7.4 [v0.7.3]: https://github.com/rust-embedded/cortex-m/compare/v0.7.2...v0.7.3 [v0.7.2]: https://github.com/rust-embedded/cortex-m/compare/v0.7.1...v0.7.2 diff --git a/Cargo.toml b/Cargo.toml index dcbd3bdb..dc0678ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ license = "MIT OR Apache-2.0" name = "cortex-m" readme = "README.md" repository = "https://github.com/rust-embedded/cortex-m" -version = "0.7.4" +version = "0.7.5" edition = "2018" links = "cortex-m" # prevent multiple versions of this crate to be linked together diff --git a/cortex-m-semihosting/src/lib.rs b/cortex-m-semihosting/src/lib.rs index a67b84d8..721ac45d 100644 --- a/cortex-m-semihosting/src/lib.rs +++ b/cortex-m-semihosting/src/lib.rs @@ -153,8 +153,7 @@ //! //! ## `inline-asm` //! -//! When this feature is enabled semihosting is implemented using inline assembly (`llvm_asm!`) and -//! compiling this crate requires nightly. +//! When this feature is enabled semihosting is implemented using inline assembly (`asm!`). //! //! When this feature is disabled semihosting is implemented using FFI calls into an external //! assembly file and compiling this crate works on stable and beta. @@ -179,7 +178,6 @@ //! //! [pdf]: http://infocenter.arm.com/help/topic/com.arm.doc.dui0471e/DUI0471E_developing_for_arm_processors.pdf -#![cfg_attr(feature = "inline-asm", feature(llvm_asm))] #![deny(missing_docs)] #![no_std] @@ -213,7 +211,7 @@ pub unsafe fn syscall1(_nr: usize, _arg: usize) -> usize { #[cfg(all(thumb, feature = "inline-asm", not(feature = "no-semihosting")))] () => { let mut nr = _nr; - llvm_asm!("bkpt 0xAB" : "+{r0}"(nr) : "{r1}"(_arg) :: "volatile"); + core::arch::asm!("bkpt #0xab", inout("r0") nr, in("r1") _arg, options(nostack, preserves_flags)); nr } diff --git a/src/lib.rs b/src/lib.rs index beff6e8f..4790f980 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,7 +22,8 @@ //! - Some of the `register` API only becomes available only when `inline-asm` is enabled. Check the //! API docs for details. //! -//! The disadvantage is that `inline-asm` requires a nightly toolchain. +//! The disadvantage is that `inline-asm` requires a Rust version at least 1.59 to use the `asm!()` +//! macro. In the future 0.8 and above versions of `cortex-m`, this feature will always be enabled. //! //! ## `cm7-r0p1` //! @@ -55,7 +56,6 @@ //! This crate is guaranteed to compile on stable Rust 1.38 and up. It *might* //! compile with older versions but that may change in any new patch release. -#![cfg_attr(feature = "inline-asm", feature(asm))] #![deny(missing_docs)] #![no_std] #![allow(clippy::identity_op)] diff --git a/src/macros.rs b/src/macros.rs index 66b75b17..512c9323 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -30,9 +30,12 @@ macro_rules! iprintln { /// `None` variant the caller must ensure that the macro is called from a function that's executed /// at most once in the whole lifetime of the program. /// -/// # Note +/// # Notes /// This macro is unsound on multi core systems. /// +/// For debuggability, you can set an explicit name for a singleton. This name only shows up the +/// the debugger and is not referencable from other code. See example below. +/// /// # Example /// /// ``` no_run @@ -50,15 +53,24 @@ macro_rules! iprintln { /// fn alias() -> &'static mut bool { /// singleton!(: bool = false).unwrap() /// } +/// +/// fn singleton_with_name() { +/// // A name only for debugging purposes +/// singleton!(FOO_BUFFER: [u8; 1024] = [0u8; 1024]); +/// } /// ``` #[macro_export] macro_rules! singleton { - (: $ty:ty = $expr:expr) => { + ($name:ident: $ty:ty = $expr:expr) => { $crate::interrupt::free(|_| { - static mut VAR: Option<$ty> = None; + // this is a tuple of a MaybeUninit and a bool because using an Option here is + // problematic: Due to niche-optimization, an Option could end up producing a non-zero + // initializer value which would move the entire static from `.bss` into `.data`... + static mut $name: (::core::mem::MaybeUninit<$ty>, bool) = + (::core::mem::MaybeUninit::uninit(), false); #[allow(unsafe_code)] - let used = unsafe { VAR.is_some() }; + let used = unsafe { $name.1 }; if used { None } else { @@ -66,16 +78,16 @@ macro_rules! singleton { #[allow(unsafe_code)] unsafe { - VAR = Some(expr) - } - - #[allow(unsafe_code)] - unsafe { - VAR.as_mut() + $name.1 = true; + $name.0 = ::core::mem::MaybeUninit::new(expr); + Some(&mut *$name.0.as_mut_ptr()) } } }) }; + (: $ty:ty = $expr:expr) => { + $crate::singleton!(VAR: $ty = $expr) + }; } /// ``` compile_fail