From 12879fde354dd3ff7144568d5d79c7a9eba9f2fc Mon Sep 17 00:00:00 2001 From: Rahix Date: Wed, 12 Aug 2020 22:06:50 +0200 Subject: [PATCH] Only emit inline-assembly when building for AVR Make sure that we'll never emit AVR assembly on non-AVR targets. Instead of failing the build, fail at runtime, to allow a potential application testsuite to run even if those functions somehow get linked in. Signed-off-by: Rahix --- Cargo.toml | 7 +++--- src/asm.rs | 24 +++++++++++++++++--- src/interrupt.rs | 59 +++++++++++++++++++++++++++--------------------- 3 files changed, 58 insertions(+), 32 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ddb939e..a73524f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,9 @@ include = [ "/README.md", ] +[package.metadata.docs.rs] +all-features = true + [features] atmega1280 = [] atmega168 = [] @@ -32,11 +35,9 @@ rt = ["avr-device-macros"] [dependencies] bare-metal = "0.2.5" vcell = "0.1.2" +cfg-if = "0.1.10" [dependencies.avr-device-macros] path = "macros/" version = "=0.2.0" optional = true - -[package.metadata.docs.rs] -all-features = true diff --git a/src/asm.rs b/src/asm.rs index 5dbb170..b8f0e37 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -3,17 +3,35 @@ /// No Operation #[inline(always)] pub fn nop() { - unsafe { llvm_asm!("nop") } + cfg_if::cfg_if! { + if #[cfg(target_arch = "avr")] { + unsafe { llvm_asm!("nop") } + } else { + unimplemented!() + } + } } /// Sleep / Wait For Interrupt #[inline(always)] pub fn sleep() { - unsafe { llvm_asm!("sleep") } + cfg_if::cfg_if! { + if #[cfg(target_arch = "avr")] { + unsafe { llvm_asm!("sleep") } + } else { + unimplemented!() + } + } } /// Watchdog Reset #[inline(always)] pub fn wdr() { - unsafe { llvm_asm!("wdr") } + cfg_if::cfg_if! { + if #[cfg(target_arch = "avr")] { + unsafe { llvm_asm!("wdr") } + } else { + unimplemented!() + } + } } diff --git a/src/interrupt.rs b/src/interrupt.rs index 5eeec1a..de8652e 100644 --- a/src/interrupt.rs +++ b/src/interrupt.rs @@ -13,10 +13,12 @@ pub use bare_metal::{CriticalSection, Mutex, Nr}; #[inline] /// Disables all interrupts pub fn disable() { - unsafe { - llvm_asm!( - "cli" :::: "volatile" - ); + cfg_if::cfg_if! { + if #[cfg(target_arch = "avr")] { + unsafe { llvm_asm!("cli" :::: "volatile") }; + } else { + unimplemented!() + } } } @@ -27,9 +29,13 @@ pub fn disable() { /// /// - Do not call this function inside an [crate::interrupt::free] critical section pub unsafe fn enable() { - llvm_asm!( - "sei" :::: "volatile" - ); + cfg_if::cfg_if! { + if #[cfg(target_arch = "avr")] { + llvm_asm!("sei" :::: "volatile"); + } else { + unimplemented!() + } + } } /// Execute closure `f` in an interrupt-free context. @@ -39,28 +45,29 @@ pub fn free(f: F) -> R where F: FnOnce(&CriticalSection) -> R, { - let sreg: u8; + cfg_if::cfg_if! { + if #[cfg(target_arch = "avr")] { + let sreg: u8; - // Store current state - unsafe { - llvm_asm!( - "in $0,0x3F" - : "=r"(sreg) - : - : - : "volatile" - ); - } + // Store current state + unsafe { + llvm_asm!("in $0,0x3F" :"=r"(sreg) ::: "volatile"); + } - // Disable interrupts - disable(); + // Disable interrupts + disable(); - let r = f(unsafe { &CriticalSection::new() }); + let r = f(unsafe { &CriticalSection::new() }); - // Restore interrupt state - if sreg & 0x80 != 0x00 { - unsafe { enable(); } - } + // Restore interrupt state + if sreg & 0x80 != 0x00 { + unsafe { enable(); } + } - r + r + } else { + let _ = f; + unimplemented!() + } + } }