~ruther/avr-device

12879fde354dd3ff7144568d5d79c7a9eba9f2fc — Rahix 4 years ago 91f3ea8
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 <rahix@rahix.de>
3 files changed, 58 insertions(+), 32 deletions(-)

M Cargo.toml
M src/asm.rs
M src/interrupt.rs
M Cargo.toml => Cargo.toml +4 -3
@@ 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

M src/asm.rs => src/asm.rs +21 -3
@@ 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!()
        }
    }
}

M src/interrupt.rs => src/interrupt.rs +33 -26
@@ 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, R>(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!()
        }
    }
}

Do not follow this link