aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cortex-m-rt/.github/bors.toml16
-rw-r--r--cortex-m-rt/.github/workflows/ci.yml67
-rw-r--r--cortex-m-rt/CHANGELOG.md23
-rw-r--r--cortex-m-rt/examples/divergent-default-handler.rs3
-rw-r--r--cortex-m-rt/examples/override-exception.rs5
-rw-r--r--cortex-m-rt/link.x.in23
-rw-r--r--cortex-m-rt/macros/src/lib.rs42
-rw-r--r--cortex-m-rt/src/lib.rs99
-rw-r--r--cortex-m-rt/tests/compile-fail/default-handler-bad-signature-1.rs4
-rw-r--r--cortex-m-rt/tests/compile-fail/default-handler-bad-signature-2.rs4
-rw-r--r--cortex-m-rt/tests/compile-fail/default-handler-hidden.rs2
-rw-r--r--cortex-m-rt/tests/compile-fail/default-handler-twice.rs4
-rw-r--r--cortex-m-rt/tests/compile-fail/exception-nmi-unsafe.rs24
-rw-r--r--cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-1.rs4
-rw-r--r--cortex-m-rt/tests/compile-fail/hard-fault-twice.rs4
-rw-r--r--cortex-m-rt/tests/compile-fail/unsafe-init-static.rs4
16 files changed, 235 insertions, 93 deletions
diff --git a/cortex-m-rt/.github/bors.toml b/cortex-m-rt/.github/bors.toml
index 1972ab0..9b9d884 100644
--- a/cortex-m-rt/.github/bors.toml
+++ b/cortex-m-rt/.github/bors.toml
@@ -2,17 +2,9 @@ block_labels = ["needs-decision"]
delete_merged_branches = true
required_approvals = 1
status = [
- "ci-linux (stable, x86_64-unknown-linux-gnu)",
- "ci-linux (stable, thumbv6m-none-eabi)",
- "ci-linux (stable, thumbv7m-none-eabi)",
- "ci-linux (stable, thumbv7em-none-eabi)",
- "ci-linux (stable, thumbv7em-none-eabihf)",
- "ci-linux (stable, thumbv8m.main-none-eabi)",
- "ci-linux (1.39.0, x86_64-unknown-linux-gnu)",
- "ci-linux (1.39.0, thumbv6m-none-eabi)",
- "ci-linux (1.39.0, thumbv7m-none-eabi)",
- "ci-linux (1.39.0, thumbv7em-none-eabi)",
- "ci-linux (1.39.0, thumbv7em-none-eabihf)",
- "ci-linux (1.39.0, thumbv8m.main-none-eabi)",
+ "ci-linux (stable)",
+ "ci-linux (1.39.0)",
+ "build-other (macOS-latest)",
+ "build-other (windows-latest)",
"Rustfmt"
]
diff --git a/cortex-m-rt/.github/workflows/ci.yml b/cortex-m-rt/.github/workflows/ci.yml
index 6905827..35abd15 100644
--- a/cortex-m-rt/.github/workflows/ci.yml
+++ b/cortex-m-rt/.github/workflows/ci.yml
@@ -7,33 +7,74 @@ name: Continuous integration
jobs:
ci-linux:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-20.04
strategy:
matrix:
# All generated code should be running on stable now
rust: [nightly, stable, 1.39.0]
- # The default target we're compiling on and for
- TARGET: [x86_64-unknown-linux-gnu, thumbv6m-none-eabi, thumbv7m-none-eabi, thumbv7em-none-eabi, thumbv7em-none-eabihf, thumbv8m.main-none-eabi]
-
include:
# Nightly is only for reference and allowed to fail
- rust: nightly
experimental: true
steps:
- - uses: fiam/arm-none-eabi-gcc@v1
- with:
- release: '7-2018-q2'
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.rust }}
- target: ${{ matrix.TARGET }}
override: true
- components: rustfmt
- - name: Install qemu
- run: sudo apt-get install qemu-system-arm
- - name: Run CI script for ${{ matrix.TARGET }} under ${{ matrix.rust }}
- run: TARGET=${{ matrix.TARGET }} TRAVIS_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
+ - name: Install all Rust targets for ${{ matrix.rust }}
+ run: rustup target install --toolchain=${{ matrix.rust }} thumbv6m-none-eabi thumbv7m-none-eabi thumbv7em-none-eabi thumbv7em-none-eabihf thumbv8m.base-none-eabi thumbv8m.main-none-eabi thumbv8m.main-none-eabihf
+ - name: Install qemu and gcc
+ run: sudo apt-get update && sudo apt-get install qemu-system-arm gcc-arm-none-eabi
+ - name: Run CI script for x86_64-unknown-linux-gnu under ${{ matrix.rust }}
+ run: TARGET=x86_64-unknown-linux-gnu TRAVIS_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
+ - name: Run CI script for thumbv6m-none-eabi under ${{ matrix.rust }}
+ run: TARGET=thumbv6m-none-eabi TRAVIS_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
+ - name: Run CI script for thumbv7m-none-eabi under ${{ matrix.rust }}
+ run: TARGET=thumbv7m-none-eabi TRAVIS_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
+ - name: Run CI script for thumbv7em-none-eabi under ${{ matrix.rust }}
+ run: TARGET=thumbv7em-none-eabi TRAVIS_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
+ - name: Run CI script for thumbv7em-none-eabihf under ${{ matrix.rust }}
+ run: TARGET=thumbv7em-none-eabihf TRAVIS_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
+ - name: Run CI script for thumbv8m.base-none-eabi under ${{ matrix.rust }}
+ run: TARGET=thumbv8m.base-none-eabi TRAVIS_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
+ - name: Run CI script for thumbv8m.main-none-eabi under ${{ matrix.rust }}
+ run: TARGET=thumbv8m.main-none-eabi TRAVIS_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
+ - name: Run CI script for thumbv8m.main-none-eabihf under ${{ matrix.rust }}
+ run: TARGET=thumbv8m.main-none-eabihf TRAVIS_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
+
+ # On macOS and Windows, we at least make sure that all examples build and link.
+ build-other:
+ strategy:
+ matrix:
+ os:
+ - macOS-latest
+ - windows-latest
+ runs-on: ${{ matrix.os }}
+
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions-rs/toolchain@v1
+ with:
+ profile: minimal
+ toolchain: stable
+ override: true
+ - name: Install all Rust targets
+ run: rustup target install thumbv6m-none-eabi thumbv7m-none-eabi thumbv7em-none-eabi thumbv7em-none-eabihf thumbv8m.base-none-eabi thumbv8m.main-none-eabi thumbv8m.main-none-eabihf
+ - name: Build crate for thumbv6m-none-eabi
+ run: cargo build --target=thumbv6m-none-eabi --examples
+ - name: Build crate for thumbv7m-none-eabi
+ run: cargo build --target=thumbv7m-none-eabi --examples
+ - name: Build crate for thumbv7em-none-eabi
+ run: cargo build --target=thumbv7em-none-eabi --examples
+ - name: Build crate for thumbv7em-none-eabihf
+ run: cargo build --target=thumbv7em-none-eabihf --examples
+ - name: Build crate for thumbv8m.base-none-eabi
+ run: cargo build --target=thumbv8m.base-none-eabi --examples
+ - name: Build crate for thumbv8m.main-none-eabi
+ run: cargo build --target=thumbv8m.main-none-eabi --examples
+ - name: Build crate for thumbv8m.main-none-eabihf
+ run: cargo build --target=thumbv8m.main-none-eabihf --examples
diff --git a/cortex-m-rt/CHANGELOG.md b/cortex-m-rt/CHANGELOG.md
index b6ca176..e04c9c9 100644
--- a/cortex-m-rt/CHANGELOG.md
+++ b/cortex-m-rt/CHANGELOG.md
@@ -7,6 +7,29 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
+### Fixes
+
+- Various fixes to the linker script ([#265], [#286]).
+- Use the correct ABI for the `main` symbol ([#278]).
+- Add barriers after FPU enabling ([#279]).
+
+[#265]: https://github.com/rust-embedded/cortex-m-rt/pull/265
+[#278]: https://github.com/rust-embedded/cortex-m-rt/pull/278
+[#279]: https://github.com/rust-embedded/cortex-m-rt/pull/279
+[#286]: https://github.com/rust-embedded/cortex-m-rt/pull/286
+
+### Breaking Changes
+
+- Make `ExceptionFrame`s fields private, adding setters and getters instead
+ ([#239]).
+- Only allow certain attributes on handlers, and apply them to the trampoline
+ too ([#228]).
+- Make it unsafe to define exception handlers for NMIs ([#289]).
+
+[#239]: https://github.com/rust-embedded/cortex-m-rt/pull/239
+[#228]: https://github.com/rust-embedded/cortex-m-rt/pull/228
+[#289]: https://github.com/rust-embedded/cortex-m-rt/pull/289
+
## [v0.6.11] - 2019-12-04
### Changed
diff --git a/cortex-m-rt/examples/divergent-default-handler.rs b/cortex-m-rt/examples/divergent-default-handler.rs
index 22fa437..3290254 100644
--- a/cortex-m-rt/examples/divergent-default-handler.rs
+++ b/cortex-m-rt/examples/divergent-default-handler.rs
@@ -1,4 +1,3 @@
-#![deny(unsafe_code)]
#![deny(warnings)]
#![no_main]
#![no_std]
@@ -14,6 +13,6 @@ fn foo() -> ! {
}
#[exception]
-fn DefaultHandler(_irqn: i16) -> ! {
+unsafe fn DefaultHandler(_irqn: i16) -> ! {
loop {}
}
diff --git a/cortex-m-rt/examples/override-exception.rs b/cortex-m-rt/examples/override-exception.rs
index 6da6c5e..3190b77 100644
--- a/cortex-m-rt/examples/override-exception.rs
+++ b/cortex-m-rt/examples/override-exception.rs
@@ -1,6 +1,5 @@
//! How to override the hard fault exception handler and the default exception handler
-#![deny(unsafe_code)]
#![deny(warnings)]
#![no_main]
#![no_std]
@@ -18,12 +17,12 @@ fn main() -> ! {
}
#[exception]
-fn DefaultHandler(_irqn: i16) {
+unsafe fn DefaultHandler(_irqn: i16) {
asm::bkpt();
}
#[exception]
-fn HardFault(_ef: &ExceptionFrame) -> ! {
+unsafe fn HardFault(_ef: &ExceptionFrame) -> ! {
asm::bkpt();
loop {}
diff --git a/cortex-m-rt/link.x.in b/cortex-m-rt/link.x.in
index a502a03..f5e582e 100644
--- a/cortex-m-rt/link.x.in
+++ b/cortex-m-rt/link.x.in
@@ -88,9 +88,10 @@ SECTIONS
*(.text .text.*);
*(.HardFaultTrampoline);
*(.HardFault.*);
- . = ALIGN(4);
- __etext = .;
+ . = ALIGN(4); /* Pad .text to the alignment to workaround overlapping load section bug in old lld */
} > FLASH
+ . = ALIGN(4); /* Ensure __etext is aligned if something unaligned is inserted after .text */
+ __etext = .; /* Define outside of .text to allow using INSERT AFTER .text */
/* ### .rodata */
.rodata __etext : ALIGN(4)
@@ -101,32 +102,36 @@ SECTIONS
This is required by LLD to ensure the LMA of the following .data
section will have the correct alignment. */
. = ALIGN(4);
- __erodata = .;
} > FLASH
+ . = ALIGN(4); /* Ensure __erodata is aligned if something unaligned is inserted after .rodata */
+ __erodata = .;
/* ## Sections in RAM */
/* ### .data */
- .data : AT(__erodata) ALIGN(4)
+ .data : ALIGN(4)
{
. = ALIGN(4);
__sdata = .;
*(.data .data.*);
. = ALIGN(4); /* 4-byte align the end (VMA) of this section */
- __edata = .;
- } > RAM
+ } > RAM AT>FLASH
+ . = ALIGN(4); /* Ensure __edata is aligned if something unaligned is inserted after .data */
+ __edata = .;
/* LMA of .data */
__sidata = LOADADDR(.data);
/* ### .bss */
+ . = ALIGN(4);
+ __sbss = .; /* Define outside of section to include INSERT BEFORE/AFTER symbols */
.bss (NOLOAD) : ALIGN(4)
{
- . = ALIGN(4);
- __sbss = .;
*(.bss .bss.*);
+ *(COMMON); /* Uninitialized C statics */
. = ALIGN(4); /* 4-byte align the end (VMA) of this section */
- __ebss = .;
} > RAM
+ . = ALIGN(4); /* Ensure __ebss is aligned if something unaligned is inserted after .bss */
+ __ebss = .;
/* ### .uninit */
.uninit (NOLOAD) : ALIGN(4)
diff --git a/cortex-m-rt/macros/src/lib.rs b/cortex-m-rt/macros/src/lib.rs
index 3c532c0..7e54a5c 100644
--- a/cortex-m-rt/macros/src/lib.rs
+++ b/cortex-m-rt/macros/src/lib.rs
@@ -113,6 +113,14 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
.into()
}
+#[derive(Debug, PartialEq)]
+enum Exception {
+ DefaultHandler,
+ HardFault,
+ NonMaskableInt,
+ Other,
+}
+
#[proc_macro_attribute]
pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
let mut f = parse_macro_input!(input as ItemFn);
@@ -130,20 +138,15 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
let fspan = f.span();
let ident = f.sig.ident.clone();
- enum Exception {
- DefaultHandler,
- HardFault,
- Other,
- }
-
let ident_s = ident.to_string();
let exn = match &*ident_s {
"DefaultHandler" => Exception::DefaultHandler,
"HardFault" => Exception::HardFault,
+ "NonMaskableInt" => Exception::NonMaskableInt,
// NOTE that at this point we don't check if the exception is available on the target (e.g.
// MemoryManagement is not available on Cortex-M0)
- "NonMaskableInt" | "MemoryManagement" | "BusFault" | "UsageFault" | "SecureFault"
- | "SVCall" | "DebugMonitor" | "PendSV" | "SysTick" => Exception::Other,
+ "MemoryManagement" | "BusFault" | "UsageFault" | "SecureFault" | "SVCall"
+ | "DebugMonitor" | "PendSV" | "SysTick" => Exception::Other,
_ => {
return parse::Error::new(ident.span(), "This is not a valid exception name")
.to_compile_error()
@@ -151,7 +154,22 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
}
};
- // XXX should we blacklist other attributes?
+ if f.sig.unsafety.is_none() {
+ match exn {
+ Exception::DefaultHandler | Exception::HardFault | Exception::NonMaskableInt => {
+ // These are unsafe to define.
+ let name = if exn == Exception::DefaultHandler {
+ format!("`DefaultHandler`")
+ } else {
+ format!("`{:?}` handler", exn)
+ };
+ return parse::Error::new(ident.span(), format_args!("defining a {} is unsafe and requires an `unsafe fn` (see the cortex-m-rt docs)", name))
+ .to_compile_error()
+ .into();
+ }
+ Exception::Other => {}
+ }
+ }
match exn {
Exception::DefaultHandler => {
@@ -174,7 +192,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
if !valid_signature {
return parse::Error::new(
fspan,
- "`DefaultHandler` must have signature `[unsafe] fn(i16) [-> !]`",
+ "`DefaultHandler` must have signature `unsafe fn(i16) [-> !]`",
)
.to_compile_error()
.into();
@@ -231,7 +249,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
if !valid_signature {
return parse::Error::new(
fspan,
- "`HardFault` handler must have signature `[unsafe] fn(&ExceptionFrame) -> !`",
+ "`HardFault` handler must have signature `unsafe fn(&ExceptionFrame) -> !`",
)
.to_compile_error()
.into();
@@ -257,7 +275,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
)
.into()
}
- Exception::Other => {
+ Exception::NonMaskableInt | Exception::Other => {
let valid_signature = f.sig.constness.is_none()
&& f.vis == Visibility::Inherited
&& f.sig.abi.is_none()
diff --git a/cortex-m-rt/src/lib.rs b/cortex-m-rt/src/lib.rs
index bab2844..524b161 100644
--- a/cortex-m-rt/src/lib.rs
+++ b/cortex-m-rt/src/lib.rs
@@ -199,15 +199,14 @@
//! won't find it.
//!
//! - `DefaultHandler`. This is the default handler. If not overridden using `#[exception] fn
-//! DefaultHandler(..` this will cause a panic with the message "DefaultHandler #`i`", where `i` is
-//! the number of the interrupt handler.
+//! DefaultHandler(..` this will be an infinite loop.
//!
//! - `HardFaultTrampoline`. This is the real hard fault handler. This function is simply a
//! trampoline that jumps into the user defined hard fault handler named `HardFault`. The
//! trampoline is required to set up the pointer to the stacked exception frame.
//!
//! - `HardFault`. This is the user defined hard fault handler. If not overridden using
-//! `#[exception] fn HardFault(..` it will default to a panic with message "HardFault".
+//! `#[exception] fn HardFault(..` it will default to an infinite loop.
//!
//! - `__STACK_START`. This is the first entry in the `.vector_table` section. This symbol contains
//! the initial value of the stack pointer; this is where the stack will be located -- the stack
@@ -387,6 +386,41 @@
//! undefined behavior. At some point in the future we may add an attribute to safely place static
//! variables in this section.
//!
+//! ## Extra Sections
+//!
+//! Some microcontrollers provide additional memory regions beyond RAM and FLASH.
+//! For example, some STM32 devices provide "CCM" or core-coupled RAM that is
+//! only accessible from the core. In order to access these using
+//! [`link_section`] attributes from your code, you need to modify `memory.x`
+//! to declare the additional sections:
+//!
+//! [`link_section`]: https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute
+//!
+//! ```text
+//! MEMORY
+//! {
+//! FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
+//! RAM (rw) : ORIGIN = 0x20000000, LENGTH = 128K
+//! CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
+//! }
+//!
+//! SECTIONS
+//! {
+//! .ccmram (NOLOAD) : ALIGN(4)
+//! {
+//! *(.ccmram .ccmram.*);
+//! . = ALIGN(4);
+//! } > CCMRAM
+//! } INSERT AFTER .bss;
+//! ```
+//!
+//! You can then use something like this to place a variable into this specific section of memory:
+//!
+//! ```no_run,edition2018
+//! #[link_section=".ccmram.BUFFERS"]
+//! static mut BUF: [u8; 1024] = [0u8; 1024];
+//! ```
+//!
//! [attr-entry]: attr.entry.html
//! [attr-exception]: attr.exception.html
//! [attr-pre_init]: attr.pre_init.html
@@ -407,6 +441,7 @@ extern crate cortex_m_rt_macros as macros;
extern crate r0;
use core::fmt;
+use core::sync::atomic::{self, Ordering};
/// Attribute to declare an interrupt (AKA device-specific exception) handler
///
@@ -577,13 +612,13 @@ pub use macros::entry;
///
/// # Usage
///
-/// `#[exception] fn HardFault(..` sets the hard fault handler. The handler must have signature
-/// `[unsafe] fn(&ExceptionFrame) -> !`. This handler is not allowed to return as that can cause
-/// undefined behavior.
+/// `#[exception] unsafe fn HardFault(..` sets the hard fault handler. The handler must have
+/// signature `unsafe fn(&ExceptionFrame) -> !`. This handler is not allowed to return as that can
+/// cause undefined behavior.
///
-/// `#[exception] fn DefaultHandler(..` sets the *default* handler. All exceptions which have not
-/// been assigned a handler will be serviced by this handler. This handler must have signature
-/// `[unsafe] fn(irqn: i16) [-> !]`. `irqn` is the IRQ number (See CMSIS); `irqn` will be a negative
+/// `#[exception] unsafe fn DefaultHandler(..` sets the *default* handler. All exceptions which have
+/// not been assigned a handler will be serviced by this handler. This handler must have signature
+/// `unsafe fn(irqn: i16) [-> !]`. `irqn` is the IRQ number (See CMSIS); `irqn` will be a negative
/// number when the handler is servicing a core exception; `irqn` will be a positive number when the
/// handler is servicing a device specific exception (interrupt).
///
@@ -602,23 +637,25 @@ pub use macros::entry;
/// the attribute will help by making a transformation to the source code: for this reason a
/// variable like `static mut FOO: u32` will become `let FOO: &mut u32;`.
///
-/// # Examples
+/// # Safety
///
-/// - Setting the `HardFault` handler
+/// It is not generally safe to register handlers for non-maskable interrupts. On Cortex-M,
+/// `HardFault` is non-maskable (at least in general), and there is an explicitly non-maskable
+/// interrupt `NonMaskableInt`.
///
-/// ```
-/// # extern crate cortex_m_rt;
-/// # extern crate cortex_m_rt_macros;
-/// use cortex_m_rt::{ExceptionFrame, exception};
+/// The reason for that is that non-maskable interrupts will preempt any currently running function,
+/// even if that function executes within a critical section. Thus, if it was safe to define NMI
+/// handlers, critical sections wouldn't work safely anymore.
///
-/// #[exception]
-/// fn HardFault(ef: &ExceptionFrame) -> ! {
-/// // prints the exception frame as a panic message
-/// panic!("{:#?}", ef);
-/// }
+/// This also means that defining a `DefaultHandler` must be unsafe, as that will catch
+/// `NonMaskableInt` and `HardFault` if no handlers for those are defined.
///
-/// # fn main() {}
-/// ```
+/// The safety requirements on those handlers is as follows: The handler must not access any data
+/// that is protected via a critical section and shared with other interrupts that may be preempted
+/// by the NMI while holding the critical section. As long as this requirement is fulfilled, it is
+/// safe to handle NMIs.
+///
+/// # Examples
///
/// - Setting the default handler
///
@@ -626,7 +663,7 @@ pub use macros::entry;
/// use cortex_m_rt::exception;
///
/// #[exception]
-/// fn DefaultHandler(irqn: i16) {
+/// unsafe fn DefaultHandler(irqn: i16) {
/// println!("IRQn = {}", irqn);
/// }
///
@@ -955,17 +992,21 @@ pub unsafe extern "C" fn Reset() -> ! {
#[link_section = ".HardFault.default"]
#[no_mangle]
pub unsafe extern "C" fn HardFault_(ef: &ExceptionFrame) -> ! {
- panic!("HardFault");
+ loop {
+ // add some side effect to prevent this from turning into a UDF instruction
+ // see rust-lang/rust#28728 for details
+ atomic::compiler_fence(Ordering::SeqCst);
+ }
}
#[doc(hidden)]
#[no_mangle]
pub unsafe extern "C" fn DefaultHandler_() -> ! {
- const SCB_ICSR: *const u32 = 0xE000_ED04 as *const u32;
-
- let irqn = core::ptr::read(SCB_ICSR) as u8 as i16 - 16;
-
- panic!("DefaultHandler #{}", irqn);
+ loop {
+ // add some side effect to prevent this from turning into a UDF instruction
+ // see rust-lang/rust#28728 for details
+ atomic::compiler_fence(Ordering::SeqCst);
+ }
}
#[doc(hidden)]
diff --git a/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-1.rs b/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-1.rs
index 5436115..b590883 100644
--- a/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-1.rs
+++ b/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-1.rs
@@ -12,5 +12,5 @@ fn foo() -> ! {
}
#[exception]
-fn DefaultHandler(_irqn: i16, undef: u32) {}
-//~^ ERROR `DefaultHandler` must have signature `[unsafe] fn(i16) [-> !]`
+unsafe fn DefaultHandler(_irqn: i16, undef: u32) {}
+//~^ ERROR `DefaultHandler` must have signature `unsafe fn(i16) [-> !]`
diff --git a/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-2.rs b/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-2.rs
index 1cca10c..0dadd6a 100644
--- a/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-2.rs
+++ b/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-2.rs
@@ -12,7 +12,7 @@ fn foo() -> ! {
}
#[exception]
-fn DefaultHandler(_irqn: i16) -> u32 {
- //~^ ERROR `DefaultHandler` must have signature `[unsafe] fn(i16) [-> !]`
+unsafe fn DefaultHandler(_irqn: i16) -> u32 {
+ //~^ ERROR `DefaultHandler` must have signature `unsafe fn(i16) [-> !]`
0
}
diff --git a/cortex-m-rt/tests/compile-fail/default-handler-hidden.rs b/cortex-m-rt/tests/compile-fail/default-handler-hidden.rs
index e57cb31..c658e2b 100644
--- a/cortex-m-rt/tests/compile-fail/default-handler-hidden.rs
+++ b/cortex-m-rt/tests/compile-fail/default-handler-hidden.rs
@@ -18,5 +18,5 @@ mod hidden {
use cortex_m_rt::exception;
#[exception]
- fn DefaultHandler(_irqn: i16) {}
+ unsafe fn DefaultHandler(_irqn: i16) {}
}
diff --git a/cortex-m-rt/tests/compile-fail/default-handler-twice.rs b/cortex-m-rt/tests/compile-fail/default-handler-twice.rs
index ad1c3f9..bbf2edd 100644
--- a/cortex-m-rt/tests/compile-fail/default-handler-twice.rs
+++ b/cortex-m-rt/tests/compile-fail/default-handler-twice.rs
@@ -12,11 +12,11 @@ fn foo() -> ! {
}
#[exception]
-fn DefaultHandler(_irqn: i16) {}
+unsafe fn DefaultHandler(_irqn: i16) {}
pub mod reachable {
use cortex_m_rt::exception;
#[exception] //~ ERROR symbol `DefaultHandler` is already defined
- fn DefaultHandler(_irqn: i16) {}
+ unsafe fn DefaultHandler(_irqn: i16) {}
}
diff --git a/cortex-m-rt/tests/compile-fail/exception-nmi-unsafe.rs b/cortex-m-rt/tests/compile-fail/exception-nmi-unsafe.rs
new file mode 100644
index 0000000..f5de2f8
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/exception-nmi-unsafe.rs
@@ -0,0 +1,24 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[exception]
+fn DefaultHandler(_irq: i16) {}
+//~^ ERROR defining a `DefaultHandler` is unsafe and requires an `unsafe fn`
+
+#[exception]
+fn HardFault() {}
+//~^ ERROR defining a `HardFault` handler is unsafe and requires an `unsafe fn`
+
+#[exception]
+fn NonMaskableInt() {}
+//~^ ERROR defining a `NonMaskableInt` handler is unsafe and requires an `unsafe fn`
diff --git a/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-1.rs b/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-1.rs
index d3b4392..11b53dc 100644
--- a/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-1.rs
+++ b/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-1.rs
@@ -12,7 +12,7 @@ fn foo() -> ! {
}
#[exception]
-fn HardFault(_ef: &ExceptionFrame, undef: u32) -> ! {
- //~^ ERROR `HardFault` handler must have signature `[unsafe] fn(&ExceptionFrame) -> !`
+unsafe fn HardFault(_ef: &ExceptionFrame, undef: u32) -> ! {
+ //~^ ERROR `HardFault` handler must have signature `unsafe fn(&ExceptionFrame) -> !`
loop {}
}
diff --git a/cortex-m-rt/tests/compile-fail/hard-fault-twice.rs b/cortex-m-rt/tests/compile-fail/hard-fault-twice.rs
index 030b54c..03b79a5 100644
--- a/cortex-m-rt/tests/compile-fail/hard-fault-twice.rs
+++ b/cortex-m-rt/tests/compile-fail/hard-fault-twice.rs
@@ -12,7 +12,7 @@ fn foo() -> ! {
}
#[exception]
-fn HardFault(_ef: &ExceptionFrame) -> ! {
+unsafe fn HardFault(_ef: &ExceptionFrame) -> ! {
loop {}
}
@@ -20,7 +20,7 @@ pub mod reachable {
use cortex_m_rt::{exception, ExceptionFrame};
#[exception] //~ ERROR symbol `HardFault` is already defined
- fn HardFault(_ef: &ExceptionFrame) -> ! {
+ unsafe fn HardFault(_ef: &ExceptionFrame) -> ! {
loop {}
}
}
diff --git a/cortex-m-rt/tests/compile-fail/unsafe-init-static.rs b/cortex-m-rt/tests/compile-fail/unsafe-init-static.rs
index c040173..23105f1 100644
--- a/cortex-m-rt/tests/compile-fail/unsafe-init-static.rs
+++ b/cortex-m-rt/tests/compile-fail/unsafe-init-static.rs
@@ -29,12 +29,12 @@ fn SVCall() {
}
#[exception]
-fn DefaultHandler(_irq: i16) {
+unsafe fn DefaultHandler(_irq: i16) {
static mut X: u32 = init(); //~ ERROR requires unsafe
}
#[exception]
-fn HardFault(_frame: &cortex_m_rt::ExceptionFrame) -> ! {
+unsafe fn HardFault(_frame: &cortex_m_rt::ExceptionFrame) -> ! {
static mut X: u32 = init(); //~ ERROR requires unsafe
loop {}
}