diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 822777f..ad95726 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -16,4 +16,4 @@ jobs: steps: - uses: actions/checkout@v2 - name: Build - run: ./ci.sh \ No newline at end of file + run: ./ci.sh diff --git a/avr-specs/avr-atmega328p.json b/avr-specs/avr-atmega328p.json new file mode 100644 index 0000000..e236b08 --- /dev/null +++ b/avr-specs/avr-atmega328p.json @@ -0,0 +1,27 @@ +{ + "arch": "avr", + "atomic-cas": false, + "cpu": "atmega328p", + "data-layout": "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8", + "eh-frame-header": false, + "exe-suffix": ".elf", + "executables": true, + "late-link-args": { + "gcc": [ + "-lgcc" + ] + }, + "linker": "avr-gcc", + "linker-is-gnu": true, + "llvm-target": "avr-unknown-unknown", + "max-atomic-width": 8, + "no-default-libraries": false, + "pre-link-args": { + "gcc": [ + "-mmcu=atmega328p", + "-Wl,--as-needed" + ] + }, + "target-c-int-width": "16", + "target-pointer-width": "16" +} diff --git a/ci.sh b/ci.sh index e9ba8b4..b020404 100755 --- a/ci.sh +++ b/ci.sh @@ -2,6 +2,9 @@ set -euxo pipefail +rustup toolchain install nightly-2021-01-07 --component rust-src +cargo +nightly-2021-01-07 build -Zbuild-std=core --target avr-specs/avr-atmega328p.json + cargo build cargo build --target thumbv6m-none-eabi cargo build --target thumbv7em-none-eabi diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 89f0d2e..a407ee4 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -8,4 +8,5 @@ targets = [ "thumbv7em-none-eabi", "riscv32imc-unknown-none-elf", "riscv32imac-unknown-none-elf", + "avr-specs/avr-atmpeg328p.json", ] diff --git a/src/lib.rs b/src/lib.rs index c8f28b4..747fb92 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,7 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![no_std] +#![cfg_attr(target_arch = "avr", feature(llvm_asm))] +#![cfg_attr(target_arch = "avr", feature(extended_key_value_attributes))] #![doc = include_str!("../README.md")] pub use bare_metal::CriticalSection; @@ -118,6 +120,25 @@ cfg_if::cfg_if! { cortex_m::interrupt::enable() } } + } else if #[cfg(target_arch = "avr")] { + #[no_mangle] + unsafe fn _critical_section_acquire() -> u8 { + let mut sreg: u8; + llvm_asm!( + "in $0, 0x3F + cli" + : "=r"(sreg) + ::: "volatile" + ); + sreg + } + + #[no_mangle] + unsafe fn _critical_section_release(token: u8) { + if token & 0x80 == 0x80 { + llvm_asm!("sei" :::: "volatile"); + } + } } else if #[cfg(target_arch = "riscv32")] { #[no_mangle] unsafe fn _critical_section_acquire() -> u8 {