From 3b25e71a78c6ac8514f3d59dc6e124a57439dcb6 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sat, 11 Aug 2018 20:41:46 -0500 Subject: v0.5.2 --- cortex-m-rt/examples/override-exception.rs | 35 ++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 cortex-m-rt/examples/override-exception.rs (limited to 'cortex-m-rt/examples/override-exception.rs') diff --git a/cortex-m-rt/examples/override-exception.rs b/cortex-m-rt/examples/override-exception.rs new file mode 100644 index 0000000..2f100a2 --- /dev/null +++ b/cortex-m-rt/examples/override-exception.rs @@ -0,0 +1,35 @@ +//! How to override the hard fault exception handler and the default exception handler + +#![deny(unsafe_code)] +#![deny(warnings)] +#![no_main] +#![no_std] + +extern crate cortex_m; +#[macro_use(entry, exception)] +extern crate cortex_m_rt as rt; +extern crate panic_semihosting; + +use cortex_m::asm; +use rt::ExceptionFrame; + +// the program entry point +entry!(main); + +fn main() -> ! { + loop {} +} + +exception!(*, default_handler); + +fn default_handler(_irqn: i16) { + asm::bkpt(); +} + +exception!(HardFault, hard_fault); + +fn hard_fault(_ef: &ExceptionFrame) -> ! { + asm::bkpt(); + + loop {} +} -- cgit v1.2.3 From f2a155a0715cb99cbace2eca7ab5fcfa93d106d2 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sat, 18 Aug 2018 22:45:13 +0200 Subject: turn macros into attributes --- cortex-m-rt/.gitignore | 1 + cortex-m-rt/Cargo.toml | 1 + cortex-m-rt/ci/script.sh | 2 + cortex-m-rt/examples/alignment.rs | 4 +- cortex-m-rt/examples/data_overflow.rs | 4 +- cortex-m-rt/examples/device.rs | 5 +- cortex-m-rt/examples/minimal.rs | 6 +- cortex-m-rt/examples/override-exception.rs | 13 +- cortex-m-rt/examples/pre_init.rs | 8 +- cortex-m-rt/examples/state.rs | 12 +- cortex-m-rt/macros/Cargo.toml | 17 ++ cortex-m-rt/macros/src/lib.rs | 462 +++++++++++++++++++++++++++++ cortex-m-rt/src/lib.rs | 263 +--------------- 13 files changed, 517 insertions(+), 281 deletions(-) create mode 100644 cortex-m-rt/macros/Cargo.toml create mode 100644 cortex-m-rt/macros/src/lib.rs (limited to 'cortex-m-rt/examples/override-exception.rs') diff --git a/cortex-m-rt/.gitignore b/cortex-m-rt/.gitignore index c71d6db..d8748d6 100644 --- a/cortex-m-rt/.gitignore +++ b/cortex-m-rt/.gitignore @@ -1,4 +1,5 @@ **/*.rs.bk +.#* Cargo.lock bin/*.after bin/*.before diff --git a/cortex-m-rt/Cargo.toml b/cortex-m-rt/Cargo.toml index 0dfbaf7..016cdc9 100644 --- a/cortex-m-rt/Cargo.toml +++ b/cortex-m-rt/Cargo.toml @@ -12,6 +12,7 @@ version = "0.5.3" [dependencies] r0 = "0.2.1" +cortex-m-rt-macros = { path = "macros", version = "0.1.0" } [dev-dependencies] panic-semihosting = "0.3.0" diff --git a/cortex-m-rt/ci/script.sh b/cortex-m-rt/ci/script.sh index 7d1cc67..242a546 100644 --- a/cortex-m-rt/ci/script.sh +++ b/cortex-m-rt/ci/script.sh @@ -5,6 +5,8 @@ main() { cargo check --target $TARGET --features device + ( cd macros && cargo check && cargo test ) + local examples=( alignment minimal diff --git a/cortex-m-rt/examples/alignment.rs b/cortex-m-rt/examples/alignment.rs index 5635851..25d755d 100644 --- a/cortex-m-rt/examples/alignment.rs +++ b/cortex-m-rt/examples/alignment.rs @@ -4,13 +4,12 @@ #![no_main] #![no_std] -#[macro_use(entry)] extern crate cortex_m_rt as rt; extern crate panic_abort; use core::ptr; -entry!(main); +use rt::entry; static mut BSS1: u16 = 0; static mut BSS2: u8 = 0; @@ -19,6 +18,7 @@ static mut DATA2: u16 = 1; static RODATA1: &[u8; 3] = b"012"; static RODATA2: &[u8; 2] = b"34"; +#[entry] fn main() -> ! { unsafe { let _bss1 = ptr::read_volatile(&BSS1); diff --git a/cortex-m-rt/examples/data_overflow.rs b/cortex-m-rt/examples/data_overflow.rs index 396f1c8..ceec18b 100644 --- a/cortex-m-rt/examples/data_overflow.rs +++ b/cortex-m-rt/examples/data_overflow.rs @@ -5,13 +5,12 @@ #![no_main] #![no_std] -#[macro_use(entry)] extern crate cortex_m_rt as rt; extern crate panic_abort; use core::ptr; -entry!(main); +use rt::entry; // This large static array uses most of .rodata static RODATA: [u8; 48*1024] = [1u8; 48*1024]; @@ -20,6 +19,7 @@ static RODATA: [u8; 48*1024] = [1u8; 48*1024]; // without also overflowing RAM. static mut DATA: [u8; 16*1024] = [1u8; 16*1024]; +#[entry] fn main() -> ! { unsafe { let _bigdata = ptr::read_volatile(&RODATA as *const u8); diff --git a/cortex-m-rt/examples/device.rs b/cortex-m-rt/examples/device.rs index 4395db2..950a564 100644 --- a/cortex-m-rt/examples/device.rs +++ b/cortex-m-rt/examples/device.rs @@ -5,13 +5,12 @@ #![no_main] #![no_std] -#[macro_use(entry)] extern crate cortex_m_rt as rt; extern crate panic_semihosting; -// the program entry point -entry!(main); +use rt::entry; +#[entry] fn main() -> ! { loop {} } diff --git a/cortex-m-rt/examples/minimal.rs b/cortex-m-rt/examples/minimal.rs index a036046..6f60180 100644 --- a/cortex-m-rt/examples/minimal.rs +++ b/cortex-m-rt/examples/minimal.rs @@ -5,13 +5,13 @@ #![no_main] #![no_std] -#[macro_use(entry)] extern crate cortex_m_rt as rt; extern crate panic_semihosting; -// the program entry point -entry!(main); +use rt::entry; +// the program entry point +#[entry] fn main() -> ! { loop {} } diff --git a/cortex-m-rt/examples/override-exception.rs b/cortex-m-rt/examples/override-exception.rs index 2f100a2..dca31e6 100644 --- a/cortex-m-rt/examples/override-exception.rs +++ b/cortex-m-rt/examples/override-exception.rs @@ -6,28 +6,23 @@ #![no_std] extern crate cortex_m; -#[macro_use(entry, exception)] extern crate cortex_m_rt as rt; extern crate panic_semihosting; use cortex_m::asm; -use rt::ExceptionFrame; - -// the program entry point -entry!(main); +use rt::{entry, exception, ExceptionFrame}; +#[entry] fn main() -> ! { loop {} } -exception!(*, default_handler); - +#[exception(DefaultHandler)] fn default_handler(_irqn: i16) { asm::bkpt(); } -exception!(HardFault, hard_fault); - +#[exception(HardFault)] fn hard_fault(_ef: &ExceptionFrame) -> ! { asm::bkpt(); diff --git a/cortex-m-rt/examples/pre_init.rs b/cortex-m-rt/examples/pre_init.rs index 7258936..00e2f2c 100644 --- a/cortex-m-rt/examples/pre_init.rs +++ b/cortex-m-rt/examples/pre_init.rs @@ -4,19 +4,17 @@ #![no_main] #![no_std] -#[macro_use(entry, pre_init)] extern crate cortex_m_rt as rt; extern crate panic_semihosting; -pre_init!(disable_watchdog); +use rt::{entry, pre_init}; +#[pre_init] unsafe fn disable_watchdog() { // Do what you need to disable the watchdog. } -// the program entry point -entry!(main); - +#[entry] fn main() -> ! { loop {} } diff --git a/cortex-m-rt/examples/state.rs b/cortex-m-rt/examples/state.rs index dbacdaf..72ca194 100644 --- a/cortex-m-rt/examples/state.rs +++ b/cortex-m-rt/examples/state.rs @@ -5,20 +5,18 @@ #![no_main] #![no_std] -#[macro_use(entry, exception)] extern crate cortex_m_rt as rt; extern crate panic_semihosting; -// the program entry point -entry!(main); +use rt::{entry, exception}; +#[entry] fn main() -> ! { loop {} } // exception handler with state -exception!(SysTick, sys_tick, state: u32 = 0); - -fn sys_tick(state: &mut u32) { - *state += 1; +#[exception(SysTick, static STATE: u32 = 0)] +fn sys_tick() { + *STATE += 1; } diff --git a/cortex-m-rt/macros/Cargo.toml b/cortex-m-rt/macros/Cargo.toml new file mode 100644 index 0000000..85e8cd1 --- /dev/null +++ b/cortex-m-rt/macros/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "cortex-m-rt-macros" +version = "0.1.0" +authors = ["Jorge Aparicio "] + +[lib] +proc-macro = true + +[dependencies] +quote = "0.6.6" + +[dependencies.syn] +features = ["extra-traits", "full"] +version = "0.14.8" + +[dev-dependencies] +cortex-m-rt = { path = ".." } diff --git a/cortex-m-rt/macros/src/lib.rs b/cortex-m-rt/macros/src/lib.rs new file mode 100644 index 0000000..3aa494d --- /dev/null +++ b/cortex-m-rt/macros/src/lib.rs @@ -0,0 +1,462 @@ +#![deny(warnings)] + +extern crate proc_macro; +#[macro_use] +extern crate quote; +#[macro_use] +extern crate syn; + +use syn::synom::Synom; +use syn::token::{Colon, Comma, Eq, Static}; +use syn::{Expr, FnArg, Ident, ItemFn, ReturnType, Type, Visibility}; + +use proc_macro::TokenStream; + +/// Attribute to declare the entry point of the program +/// +/// **NOTE** This macro must be invoked once and must be invoked from an accessible module, ideally +/// from the root of the crate. +/// +/// The specified function will be called by the reset handler *after* RAM has been initialized. In +/// the case of the `thumbv7em-none-eabihf` target the FPU will also be enabled before the function +/// is called. +/// +/// The type of the specified function must be `fn() -> !` (never ending function) +/// +/// # Examples +/// +/// ``` no_run +/// # #![no_main] +/// # use cortex_m_rt_macros::entry; +/// #[entry] +/// fn main() -> ! { +/// loop { +/// /* .. */ +/// } +/// } +/// ``` +#[proc_macro_attribute] +pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream { + let f: ItemFn = syn::parse(input).expect("`#[entry]` must be applied to a function"); + + // check the function signature + assert!( + f.constness.is_none() + && f.vis == Visibility::Inherited + && f.unsafety.is_none() + && f.abi.is_none() + && f.decl.inputs.is_empty() + && f.decl.generics.params.is_empty() + && f.decl.generics.where_clause.is_none() + && f.decl.variadic.is_none() + && match f.decl.output { + ReturnType::Default => false, + ReturnType::Type(_, ref ty) => match **ty { + Type::Never(_) => true, + _ => false, + }, + }, + "`#[entry]` function must have signature `fn() -> !`" + ); + + assert_eq!( + args.to_string(), + "", + "`entry` attribute must have no arguments" + ); + + // XXX should we blacklist other attributes? + let attrs = f.attrs; + let ident = f.ident; + let block = f.block; + + quote!( + #[export_name = "main"] + #(#attrs)* + pub fn #ident() -> ! #block + ).into() +} + +struct ExceptionArgs { + first: Ident, + second: Option, +} + +impl Synom for ExceptionArgs { + named!(parse -> Self, do_parse!( + first: syn!(Ident) >> + second: option!(syn!(State)) >> ( + ExceptionArgs { first, second } + ) + )); +} + +struct State { + _comma: Comma, + _static: Static, + ident: Ident, + _colon: Colon, + ty: Type, + _eq: Eq, + expr: Expr, +} + +impl Synom for State { + named!(parse -> Self, do_parse!( + _comma: punct!(,) >> + _static: syn!(Static) >> + ident: syn!(Ident) >> + _colon: punct!(:) >> + ty: syn!(Type) >> + _eq: punct!(=) >> + expr: syn!(Expr) >> ( + State { _comma, _static, ident, _colon, ty, _eq, expr } + ) + )); +} + +/// Attribute to declare an exception handler +/// +/// **NOTE** This macro must be invoked from an accessible module, ideally from the root of the +/// crate. +/// +/// # Syntax +/// +/// ``` +/// # use cortex_m_rt_macros::exception; +/// #[exception(SysTick, static COUNT: u32 = 0)] +/// fn handler() { +/// // .. +/// } +/// +/// # fn main() {} +/// ``` +/// +/// where the first argument can be one of: +/// +/// - `DefaultHandler` +/// - `NonMaskableInt` +/// - `HardFault` +/// - `MemoryManagement` (a) +/// - `BusFault` (a) +/// - `UsageFault` (a) +/// - `SecureFault` (b) +/// - `SVCall` +/// - `DebugMonitor` (a) +/// - `PendSV` +/// - `SysTick` +/// +/// and the second is optional. +/// +/// (a) Not available on Cortex-M0 variants (`thumbv6m-none-eabi`) +/// +/// (b) Only available on ARMv8-M +/// +/// # Usage +/// +/// `#[exception(HardFault)]` sets the hard fault handler. The handler must have signature +/// `fn(&ExceptionFrame) -> !`. This handler is not allowed to return as that can cause undefined +/// behavior. +/// +/// `#[exception(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 `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). +/// +/// `#[exception(Name)]` overrides the default handler for the exception with the given `Name`. +/// +/// # Examples +/// +/// - Setting the `HardFault` handler +/// +/// ``` +/// # extern crate cortex_m_rt; +/// # extern crate cortex_m_rt_macros; +/// # use cortex_m_rt_macros::exception; +/// #[exception(HardFault)] +/// fn hard_fault(ef: &cortex_m_rt::ExceptionFrame) -> ! { +/// // prints the exception frame as a panic message +/// panic!("{:#?}", ef); +/// } +/// +/// # fn main() {} +/// ``` +/// +/// - Setting the default handler +/// +/// ``` +/// # use cortex_m_rt_macros::exception; +/// #[exception(DefaultHandler)] +/// fn default_handler(irqn: i16) { +/// println!("IRQn = {}", irqn); +/// } +/// +/// # fn main() {} +/// ``` +/// +/// - Overriding the `SysTick` handler +/// +/// ``` +/// extern crate cortex_m_rt as rt; +/// +/// use rt::exception; +/// +/// #[exception(SysTick, static COUNT: i32 = 0)] +/// fn sys_tick() { +/// *COUNT += 1; +/// +/// println!("{}", COUNT); +/// } +/// +/// # fn main() {} +/// ``` +#[proc_macro_attribute] +pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { + let f: ItemFn = syn::parse(input).expect("`#[exception]` must be applied to a function"); + let args: ExceptionArgs = syn::parse(args).expect( + "`exception` attribute expects the exception name as its argument. \ + e.g. `#[exception(HardFault)]`", + ); + let name = args.first; + let name_s = name.to_string(); + + enum Exception { + DefaultHandler, + HardFault, + Other, + } + + // first validation of the exception name + let exn = match &*name_s { + "DefaultHandler" => Exception::DefaultHandler, + "HardFault" => Exception::HardFault, + // 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, + _ => panic!("{} is not a valid exception name", name_s), + }; + + // XXX should we blacklist other attributes? + let attrs = f.attrs; + let ident = f.ident; + let block = f.block; + let stmts = &block.stmts; + + match exn { + Exception::DefaultHandler => { + assert!( + f.constness.is_none() + && f.vis == Visibility::Inherited + && f.unsafety.is_none() + && f.abi.is_none() + && f.decl.inputs.len() == 1 + && f.decl.generics.params.is_empty() + && f.decl.generics.where_clause.is_none() + && f.decl.variadic.is_none() + && match f.decl.output { + ReturnType::Default => true, + ReturnType::Type(_, ref ty) => match **ty { + Type::Tuple(ref tuple) => tuple.elems.is_empty(), + _ => false, + }, + }, + "`#[exception(DefaultHandler)]` function must have signature `fn(i16)`" + ); + + assert!( + args.second.is_none(), + "`#[exception(DefaultHandler)]` takes no additional arguments" + ); + + let arg = match f.decl.inputs[0] { + FnArg::Captured(ref arg) => arg, + _ => unreachable!(), + }; + + quote!( + #[export_name = #name_s] + #(#attrs)* + pub fn #ident() { + extern crate core; + + const SCB_ICSR: *const u32 = 0xE000_ED04 as *const u32; + + let #arg = unsafe { core::ptr::read(SCB_ICSR) as u8 as i16 - 16 }; + + #(#stmts)* + } + ).into() + } + Exception::HardFault => { + assert!( + f.constness.is_none() + && f.vis == Visibility::Inherited + && f.unsafety.is_none() + && f.abi.is_none() + && f.decl.inputs.len() == 1 + && match f.decl.inputs[0] { + FnArg::Captured(ref arg) => match arg.ty { + Type::Reference(ref r) => { + r.lifetime.is_none() && r.mutability.is_none() + } + _ => false, + }, + _ => false, + } + && f.decl.generics.params.is_empty() + && f.decl.generics.where_clause.is_none() + && f.decl.variadic.is_none() + && match f.decl.output { + ReturnType::Default => false, + ReturnType::Type(_, ref ty) => match **ty { + Type::Never(_) => true, + _ => false, + }, + }, + "`#[exception(HardFault)]` function must have signature `fn(&ExceptionFrame) -> !`" + ); + + assert!( + args.second.is_none(), + "`#[exception(HardFault)]` takes no additional arguments" + ); + + let arg = match f.decl.inputs[0] { + FnArg::Captured(ref arg) => arg, + _ => unreachable!(), + }; + + let pat = &arg.pat; + + quote!( + #[export_name = "UserHardFault"] + #(#attrs)* + pub unsafe extern "C" fn #ident(#arg) -> ! { + extern crate cortex_m_rt; + + // further type check of the input argument + let #pat: &cortex_m_rt::ExceptionFrame = #pat; + + #(#stmts)* + } + ).into() + } + Exception::Other => { + assert!( + f.constness.is_none() + && f.vis == Visibility::Inherited + && f.unsafety.is_none() + && f.abi.is_none() + && f.decl.inputs.is_empty() + && f.decl.generics.params.is_empty() + && f.decl.generics.where_clause.is_none() + && f.decl.variadic.is_none() + && match f.decl.output { + ReturnType::Default => true, + ReturnType::Type(_, ref ty) => match **ty { + Type::Tuple(ref tuple) => tuple.elems.is_empty(), + _ => false, + }, + }, + "`#[exception]` functions must have signature `fn()`" + ); + + if let Some(second) = args.second { + let ty = second.ty; + let expr = second.expr; + let state = second.ident; + + quote!( + #[export_name = #name_s] + #(#attrs)* + pub fn #ident() { + extern crate cortex_m_rt; + + cortex_m_rt::Exception::#name; + + static mut __STATE__: #ty = #expr; + + #[allow(non_snake_case)] + let #state: &mut #ty = unsafe { &mut __STATE__ }; + + #(#stmts)* + } + ).into() + } else { + quote!( + #[export_name = #name_s] + #(#attrs)* + pub fn #ident() { + extern crate cortex_m_rt; + + cortex_m_rt::Exception::#name; + + #(#stmts)* + } + ).into() + } + } + } +} + +/// Attribute to mark which function will be called at the beginning of the reset handler. +/// +/// The function must have the signature of `unsafe fn()`. +/// +/// The function passed will be called before static variables are initialized. Any access of static +/// variables will result in undefined behavior. +/// +/// # Examples +/// +/// ``` +/// # use cortex_m_rt_macros::pre_init; +/// #[pre_init] +/// unsafe fn before_main() { +/// // do something here +/// } +/// +/// # fn main() {} +/// ``` +#[proc_macro_attribute] +pub fn pre_init(args: TokenStream, input: TokenStream) -> TokenStream { + let f: ItemFn = syn::parse(input).expect("`#[pre_init]` must be applied to a function"); + + // check the function signature + assert!( + f.constness.is_none() + && f.vis == Visibility::Inherited + && f.unsafety.is_some() + && f.abi.is_none() + && f.decl.inputs.is_empty() + && f.decl.generics.params.is_empty() + && f.decl.generics.where_clause.is_none() + && f.decl.variadic.is_none() + && match f.decl.output { + ReturnType::Default => true, + ReturnType::Type(_, ref ty) => match **ty { + Type::Tuple(ref tuple) => tuple.elems.is_empty(), + _ => false, + }, + }, + "`#[pre_init]` function must have signature `unsafe fn()`" + ); + + assert_eq!( + args.to_string(), + "", + "`pre_init` attribute must have no arguments" + ); + + // XXX should we blacklist other attributes? + let attrs = f.attrs; + let ident = f.ident; + let block = f.block; + + quote!( + #[export_name = "__pre_init"] + #(#attrs)* + pub unsafe fn #ident() #block + ).into() +} diff --git a/cortex-m-rt/src/lib.rs b/cortex-m-rt/src/lib.rs index 10f60f6..526b28b 100644 --- a/cortex-m-rt/src/lib.rs +++ b/cortex-m-rt/src/lib.rs @@ -94,18 +94,16 @@ //! #![no_main] //! #![no_std] //! -//! #[macro_use(entry, exception)] //! extern crate cortex_m_rt as rt; //! //! // makes `panic!` print messages to the host stderr using semihosting //! extern crate panic_semihosting; //! -//! use rt::ExceptionFrame; +//! use rt::entry; //! //! // use `main` as the entry point of this application -//! entry!(main); -//! //! // `main` is not allowed to return +//! #[entry] //! fn main() -> ! { //! // initialization //! @@ -113,20 +111,6 @@ //! // application logic //! } //! } -//! -//! // define the hard fault handler -//! exception!(HardFault, hard_fault); -//! -//! fn hard_fault(ef: &ExceptionFrame) -> ! { -//! panic!("{:#?}", ef); -//! } -//! -//! // define the default exception handler -//! exception!(*, default_handler); -//! -//! fn default_handler(irqn: i16) { -//! panic!("unhandled exception (IRQn={})", irqn); -//! } //! ``` //! //! To actually build this program you need to place a `memory.x` linker script somewhere the linker @@ -397,11 +381,14 @@ #![deny(warnings)] #![no_std] +extern crate cortex_m_rt_macros as macros; extern crate r0; use core::fmt; use core::sync::atomic::{self, Ordering}; +pub use macros::{entry, exception, pre_init}; + /// Registers stacked (pushed into the stack) during an exception #[derive(Clone, Copy)] #[repr(C)] @@ -474,8 +461,6 @@ pub static __RESET_VECTOR: unsafe extern "C" fn() -> ! = Reset; #[no_mangle] pub unsafe extern "C" fn Reset() -> ! { extern "C" { - // This symbol will be provided by the user via the `entry!` macro - fn main() -> !; // These symbols come from `link.x` static mut __sbss: u32; @@ -485,11 +470,17 @@ pub unsafe extern "C" fn Reset() -> ! { static mut __edata: u32; static __sidata: u32; + } + + extern "Rust" { + // This symbol will be provided by the user via `#[entry]` + fn main() -> !; + + // This symbol will be provided by the user via `#[pre_init]` fn __pre_init(); } - let pre_init: unsafe extern "C" fn() = __pre_init; - pre_init(); + __pre_init(); // Initialize RAM r0::zero_bss(&mut __sbss, &mut __ebss); @@ -551,31 +542,6 @@ pub unsafe extern "C" fn DefaultHandler_() -> ! { #[no_mangle] pub unsafe extern "C" fn DefaultPreInit() {} -/// Macro to define the entry point of the program -/// -/// **NOTE** This macro must be invoked once and must be invoked from an accessible module, ideally -/// from the root of the crate. -/// -/// Usage: `entry!(path::to::entry::point)` -/// -/// The specified function will be called by the reset handler *after* RAM has been initialized. In -/// the case of the `thumbv7em-none-eabihf` target the FPU will also be enabled before the function -/// is called. -/// -/// The signature of the specified function must be `fn() -> !` (never ending function) -#[macro_export] -macro_rules! entry { - ($path:expr) => { - #[export_name = "main"] - pub extern "C" fn __impl_main() -> ! { - // validate the signature of the program entry point - let f: fn() -> ! = $path; - - f() - } - }; -} - /* Exceptions */ #[doc(hidden)] pub enum Exception { @@ -721,206 +687,3 @@ pub static __INTERRUPTS: [unsafe extern "C" fn(); 32] = [{ DefaultHandler }; 32]; - -/// Macro to set or override a processor core exception handler -/// -/// **NOTE** This macro must be invoked from an accessible module, ideally from the root of the -/// crate. -/// -/// # Syntax -/// -/// ``` ignore -/// exception!( -/// // Name of the exception -/// $Name:ident, -/// -/// // Path to the exception handler (a function) -/// $handler:expr, -/// -/// // Optional, state preserved across invocations of the handler -/// state: $State:ty = $initial_state:expr, -/// ); -/// ``` -/// -/// where `$Name` can be one of: -/// -/// - `*` -/// - `NonMaskableInt` -/// - `HardFault` -/// - `MemoryManagement` (a) -/// - `BusFault` (a) -/// - `UsageFault` (a) -/// - `SecureFault` (b) -/// - `SVCall` -/// - `DebugMonitor` (a) -/// - `PendSV` -/// - `SysTick` -/// -/// (a) Not available on Cortex-M0 variants (`thumbv6m-none-eabi`) -/// -/// (b) Only available on ARMv8-M -/// -/// # Usage -/// -/// `exception!(HardFault, ..)` sets the hard fault handler. The handler must have signature -/// `fn(&ExceptionFrame) -> !`. This handler is not allowed to return as that can cause undefined -/// behavior. It's mandatory to set the `HardFault` handler somewhere in the dependency graph of an -/// application. -/// -/// `exception!(*, ..)` sets the *default* handler. All exceptions which have not been assigned a -/// handler will be serviced by this handler. This handler must have signature `fn(irqn: i16)`. -/// `irqn` is the IRQ number (cf. 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). It's mandatory to set the default handler somewhere -/// in the dependency graph of an application. -/// -/// `exception!($Exception, ..)` overrides the default handler for `$Exception`. All exceptions, -/// except for `HardFault`, can be assigned some `$State`. -/// -/// # Examples -/// -/// - Setting the `HardFault` handler -/// -/// ``` -/// #[macro_use(exception)] -/// extern crate cortex_m_rt as rt; -/// -/// use rt::ExceptionFrame; -/// -/// exception!(HardFault, hard_fault); -/// -/// fn hard_fault(ef: &ExceptionFrame) -> ! { -/// // prints the exception frame as a panic message -/// panic!("{:#?}", ef); -/// } -/// -/// # fn main() {} -/// ``` -/// -/// - Setting the default handler -/// -/// ``` -/// #[macro_use(exception)] -/// extern crate cortex_m_rt as rt; -/// -/// exception!(*, default_handler); -/// -/// fn default_handler(irqn: i16) { -/// println!("IRQn = {}", irqn); -/// } -/// -/// # fn main() {} -/// ``` -/// -/// - Overriding the `SysTick` handler -/// -/// ``` -/// #[macro_use(exception)] -/// extern crate cortex_m_rt as rt; -/// -/// exception!(SysTick, sys_tick, state: u32 = 0); -/// -/// fn sys_tick(count: &mut u32) { -/// println!("count = {}", *count); -/// -/// *count += 1; -/// } -/// -/// # fn main() {} -/// ``` -#[macro_export] -macro_rules! exception { - (* , $handler:expr) => { - #[allow(unsafe_code)] - #[deny(private_no_mangle_fns)] // raise an error if this item is not accessible - #[no_mangle] - pub unsafe extern "C" fn DefaultHandler() { - extern crate core; - - // validate the signature of the user provided handler - let f: fn(i16) = $handler; - - const SCB_ICSR: *const u32 = 0xE000_ED04 as *const u32; - - // NOTE not volatile so the compiler can opt the load operation away if the value is - // unused - f(core::ptr::read(SCB_ICSR) as u8 as i16 - 16) - } - }; - - (HardFault, $handler:expr) => { - #[allow(unsafe_code)] - #[deny(private_no_mangle_fns)] // raise an error if this item is not accessible - #[no_mangle] - pub unsafe extern "C" fn UserHardFault(ef: &$crate::ExceptionFrame) { - // validate the signature of the user provided handler - let f: fn(&$crate::ExceptionFrame) -> ! = $handler; - - f(ef) - } - }; - - ($Name:ident, $handler:expr,state: $State:ty = $initial_state:expr) => { - #[allow(unsafe_code)] - #[deny(private_no_mangle_fns)] // raise an error if this item is not accessible - #[no_mangle] - pub unsafe extern "C" fn $Name() { - static mut STATE: $State = $initial_state; - - // check that this exception exists - let _ = $crate::Exception::$Name; - - // validate the signature of the user provided handler - let f: fn(&mut $State) = $handler; - - f(&mut STATE) - } - }; - - ($Name:ident, $handler:expr) => { - #[allow(unsafe_code)] - #[deny(private_no_mangle_fns)] // raise an error if this item is not accessible - #[no_mangle] - pub unsafe extern "C" fn $Name() { - // check that this exception exists - let _ = $crate::Exception::$Name; - - // validate the signature of the user provided handler - let f: fn() = $handler; - - f() - } - }; -} - -/// Macro to set the function to be called at the beginning of the reset handler. -/// -/// The function must have the signature of `unsafe fn()`. -/// -/// The function passed will be called before static variables are initialized. Any access of static -/// variables will result in undefined behavior. -/// -/// # Examples -/// -/// ``` ignore -/// pre_init!(foo::bar); -/// -/// mod foo { -/// pub unsafe fn bar() { -/// // do something here -/// } -/// } -/// ``` -#[macro_export] -macro_rules! pre_init { - ($handler:path) => { - #[allow(unsafe_code)] - #[deny(private_no_mangle_fns)] // raise an error if this item is not accessible - #[no_mangle] - pub unsafe extern "C" fn __pre_init() { - // validate user handler - let f: unsafe fn() = $handler; - f(); - } - }; -} -- cgit v1.2.3 From f68e65af8fa0bf915209ae7b3d75303c317ea109 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 31 Aug 2018 22:02:29 +0200 Subject: fix soundness issue; change the syntax of the `exception` attribute --- cortex-m-rt/examples/override-exception.rs | 8 +- cortex-m-rt/examples/state.rs | 6 +- cortex-m-rt/macros/Cargo.toml | 2 + cortex-m-rt/macros/src/lib.rs | 185 +++++++++++++++++------------ 4 files changed, 121 insertions(+), 80 deletions(-) (limited to 'cortex-m-rt/examples/override-exception.rs') diff --git a/cortex-m-rt/examples/override-exception.rs b/cortex-m-rt/examples/override-exception.rs index dca31e6..3e0af25 100644 --- a/cortex-m-rt/examples/override-exception.rs +++ b/cortex-m-rt/examples/override-exception.rs @@ -17,13 +17,13 @@ fn main() -> ! { loop {} } -#[exception(DefaultHandler)] -fn default_handler(_irqn: i16) { +#[exception] +fn DefaultHandler(_irqn: i16) { asm::bkpt(); } -#[exception(HardFault)] -fn hard_fault(_ef: &ExceptionFrame) -> ! { +#[exception] +fn HardFault(_ef: &ExceptionFrame) -> ! { asm::bkpt(); loop {} diff --git a/cortex-m-rt/examples/state.rs b/cortex-m-rt/examples/state.rs index 72ca194..573914f 100644 --- a/cortex-m-rt/examples/state.rs +++ b/cortex-m-rt/examples/state.rs @@ -16,7 +16,9 @@ fn main() -> ! { } // exception handler with state -#[exception(SysTick, static STATE: u32 = 0)] -fn sys_tick() { +#[exception] +fn SysTick() { + static mut STATE: u32 = 0; + *STATE += 1; } diff --git a/cortex-m-rt/macros/Cargo.toml b/cortex-m-rt/macros/Cargo.toml index 85e8cd1..d0644ee 100644 --- a/cortex-m-rt/macros/Cargo.toml +++ b/cortex-m-rt/macros/Cargo.toml @@ -8,6 +8,8 @@ proc-macro = true [dependencies] quote = "0.6.6" +rand = "0.5.5" +proc-macro2 = "0.4.15" [dependencies.syn] features = ["extra-traits", "full"] diff --git a/cortex-m-rt/macros/src/lib.rs b/cortex-m-rt/macros/src/lib.rs index 3aa494d..5cba510 100644 --- a/cortex-m-rt/macros/src/lib.rs +++ b/cortex-m-rt/macros/src/lib.rs @@ -1,14 +1,19 @@ -#![deny(warnings)] +// #![deny(warnings)] +#![allow(warnings)] extern crate proc_macro; +extern crate rand; #[macro_use] extern crate quote; #[macro_use] extern crate syn; +extern crate proc_macro2; +use proc_macro2::Span; +use rand::Rng; use syn::synom::Synom; use syn::token::{Colon, Comma, Eq, Static}; -use syn::{Expr, FnArg, Ident, ItemFn, ReturnType, Type, Visibility}; +use syn::{Expr, FnArg, Ident, Item, ItemFn, ReturnType, Stmt, Type, Visibility}; use proc_macro::TokenStream; @@ -124,15 +129,15 @@ impl Synom for State { /// /// ``` /// # use cortex_m_rt_macros::exception; -/// #[exception(SysTick, static COUNT: u32 = 0)] -/// fn handler() { +/// #[exception] +/// fn SysTick() { /// // .. /// } /// /// # fn main() {} /// ``` /// -/// where the first argument can be one of: +/// where the name of the function must be one of: /// /// - `DefaultHandler` /// - `NonMaskableInt` @@ -146,25 +151,29 @@ impl Synom for State { /// - `PendSV` /// - `SysTick` /// -/// and the second is optional. -/// /// (a) Not available on Cortex-M0 variants (`thumbv6m-none-eabi`) /// /// (b) Only available on ARMv8-M /// /// # Usage /// -/// `#[exception(HardFault)]` sets the hard fault handler. The handler must have signature +/// `#[exception] fn HardFault(..` sets the hard fault handler. The handler must have signature /// `fn(&ExceptionFrame) -> !`. This handler is not allowed to return as that can cause undefined /// behavior. /// -/// `#[exception(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 `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). +/// `#[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 +/// `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). +/// +/// `#[exception] fn Name(..` overrides the default handler for the exception with the given `Name`. +/// When overriding these other exception it's possible to add state to them by declaring `static +/// mut` variables at the beginning of the body of the function. These variables will be safe to +/// access from the function body. /// -/// `#[exception(Name)]` overrides the default handler for the exception with the given `Name`. +/// Exception handlers can only be called by the hardware. Other parts of the program can't refer to +/// the exception handler much less invoke them as if they were functions. /// /// # Examples /// @@ -174,8 +183,8 @@ impl Synom for State { /// # extern crate cortex_m_rt; /// # extern crate cortex_m_rt_macros; /// # use cortex_m_rt_macros::exception; -/// #[exception(HardFault)] -/// fn hard_fault(ef: &cortex_m_rt::ExceptionFrame) -> ! { +/// #[exception] +/// fn HardFault(ef: &cortex_m_rt::ExceptionFrame) -> ! { /// // prints the exception frame as a panic message /// panic!("{:#?}", ef); /// } @@ -187,8 +196,8 @@ impl Synom for State { /// /// ``` /// # use cortex_m_rt_macros::exception; -/// #[exception(DefaultHandler)] -/// fn default_handler(irqn: i16) { +/// #[exception] +/// fn DefaultHandler(irqn: i16) { /// println!("IRQn = {}", irqn); /// } /// @@ -202,8 +211,11 @@ impl Synom for State { /// /// use rt::exception; /// -/// #[exception(SysTick, static COUNT: i32 = 0)] -/// fn sys_tick() { +/// #[exception] +/// fn SysTick() { +/// static mut COUNT: i32 = 0; +/// +/// // `COUNT` is safe to access and has type `&mut i32` /// *COUNT += 1; /// /// println!("{}", COUNT); @@ -214,12 +226,14 @@ impl Synom for State { #[proc_macro_attribute] pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { let f: ItemFn = syn::parse(input).expect("`#[exception]` must be applied to a function"); - let args: ExceptionArgs = syn::parse(args).expect( - "`exception` attribute expects the exception name as its argument. \ - e.g. `#[exception(HardFault)]`", + + assert_eq!( + args.to_string(), + "", + "`exception` attribute must have no arguments" ); - let name = args.first; - let name_s = name.to_string(); + + let ident = f.ident; enum Exception { DefaultHandler, @@ -227,22 +241,32 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { Other, } - // first validation of the exception name - let exn = match &*name_s { + let ident_s = ident.to_string(); + let exn = match &*ident_s { "DefaultHandler" => Exception::DefaultHandler, "HardFault" => Exception::HardFault, // 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, - _ => panic!("{} is not a valid exception name", name_s), + _ => panic!("{} is not a valid exception name", ident_s), }; // XXX should we blacklist other attributes? let attrs = f.attrs; - let ident = f.ident; let block = f.block; - let stmts = &block.stmts; + let stmts = block.stmts; + + let mut rng = rand::thread_rng(); + let hash = (0..16) + .map(|i| { + if i == 0 || rng.gen() { + ('a' as u8 + rng.gen::() % 25) as char + } else { + ('0' as u8 + rng.gen::() % 10) as char + } + }).collect::(); + let hash = Ident::new(&hash, Span::call_site()); match exn { Exception::DefaultHandler => { @@ -262,12 +286,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { _ => false, }, }, - "`#[exception(DefaultHandler)]` function must have signature `fn(i16)`" - ); - - assert!( - args.second.is_none(), - "`#[exception(DefaultHandler)]` takes no additional arguments" + "`#DefaultHandler` function must have signature `fn(i16)`" ); let arg = match f.decl.inputs[0] { @@ -276,9 +295,9 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { }; quote!( - #[export_name = #name_s] + #[export_name = #ident_s] #(#attrs)* - pub fn #ident() { + pub extern "C" fn #hash() { extern crate core; const SCB_ICSR: *const u32 = 0xE000_ED04 as *const u32; @@ -318,11 +337,6 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { "`#[exception(HardFault)]` function must have signature `fn(&ExceptionFrame) -> !`" ); - assert!( - args.second.is_none(), - "`#[exception(HardFault)]` takes no additional arguments" - ); - let arg = match f.decl.inputs[0] { FnArg::Captured(ref arg) => arg, _ => unreachable!(), @@ -333,7 +347,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { quote!( #[export_name = "UserHardFault"] #(#attrs)* - pub unsafe extern "C" fn #ident(#arg) -> ! { + pub extern "C" fn #hash(#arg) -> ! { extern crate cortex_m_rt; // further type check of the input argument @@ -360,43 +374,66 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { _ => false, }, }, - "`#[exception]` functions must have signature `fn()`" + "`#[exception]` functions other than `DefaultHandler` and `HardFault` must \ + have signature `fn()`" ); - if let Some(second) = args.second { - let ty = second.ty; - let expr = second.expr; - let state = second.ident; - - quote!( - #[export_name = #name_s] - #(#attrs)* - pub fn #ident() { - extern crate cortex_m_rt; - - cortex_m_rt::Exception::#name; + // Collect all the `static mut` at the beginning of the function body. We'll make them + // safe + let mut istmts = stmts.into_iter(); + + let mut statics = vec![]; + let mut stmts = vec![]; + while let Some(stmt) = istmts.next() { + match stmt { + Stmt::Item(Item::Static(var)) => if var.mutability.is_some() { + statics.push(var); + } else { + stmts.push(Stmt::Item(Item::Static(var))); + }, + _ => { + stmts.push(stmt); + break; + } + } + } - static mut __STATE__: #ty = #expr; + stmts.extend(istmts); + + let vars = statics + .into_iter() + .map(|var| { + let ident = var.ident; + // `let` can't shadow a `static mut` so we must give the `static` a different + // name. We'll create a new name by appending an underscore to the original name + // of the `static`. + let mut ident_ = ident.to_string(); + ident_.push('_'); + let ident_ = Ident::new(&ident_, Span::call_site()); + let ty = var.ty; + let expr = var.expr; + + quote!( + static mut #ident_: #ty = #expr; + #[allow(non_snake_case, unsafe_code)] + let #ident: &mut #ty = unsafe { &mut #ident_ }; + ) + }).collect::>(); - #[allow(non_snake_case)] - let #state: &mut #ty = unsafe { &mut __STATE__ }; + quote!( + #[export_name = #ident_s] + #(#attrs)* + pub fn #hash() { + extern crate cortex_m_rt; - #(#stmts)* - } - ).into() - } else { - quote!( - #[export_name = #name_s] - #(#attrs)* - pub fn #ident() { - extern crate cortex_m_rt; + // check that this exception actually exists + cortex_m_rt::Exception::#ident; - cortex_m_rt::Exception::#name; + #(#vars)* - #(#stmts)* - } - ).into() - } + #(#stmts)* + } + ).into() } } } -- cgit v1.2.3 From 85ba898dc80d14dc35dd21abab7684bb1ea0f4c8 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Mon, 17 Sep 2018 23:38:18 +0200 Subject: use panic-halt instead of panic-{abort,semihosting} the former requires a feature gate; the later pulls in the cortex-m crate --- cortex-m-rt/Cargo.toml | 3 +-- cortex-m-rt/examples/alignment.rs | 2 +- cortex-m-rt/examples/data_overflow.rs | 2 +- cortex-m-rt/examples/device.rs | 2 +- cortex-m-rt/examples/divergent-default-handler.rs | 2 +- cortex-m-rt/examples/divergent-exception.rs | 2 +- cortex-m-rt/examples/entry-static.rs | 2 +- cortex-m-rt/examples/main.rs | 2 +- cortex-m-rt/examples/minimal.rs | 2 +- cortex-m-rt/examples/override-exception.rs | 2 +- cortex-m-rt/examples/pre_init.rs | 2 +- cortex-m-rt/examples/rand.rs | 2 +- cortex-m-rt/examples/state.rs | 2 +- cortex-m-rt/examples/unsafe-default-handler.rs | 2 +- cortex-m-rt/examples/unsafe-entry.rs | 2 +- cortex-m-rt/examples/unsafe-exception.rs | 2 +- cortex-m-rt/examples/unsafe-hard-fault.rs | 2 +- cortex-m-rt/tests/compile-fail/default-handler-bad-signature-1.rs | 2 +- cortex-m-rt/tests/compile-fail/default-handler-bad-signature-2.rs | 2 +- cortex-m-rt/tests/compile-fail/default-handler-hidden.rs | 2 +- cortex-m-rt/tests/compile-fail/default-handler-twice.rs | 2 +- cortex-m-rt/tests/compile-fail/entry-args.rs | 2 +- cortex-m-rt/tests/compile-fail/entry-bad-signature-1.rs | 2 +- cortex-m-rt/tests/compile-fail/entry-bad-signature-2.rs | 2 +- cortex-m-rt/tests/compile-fail/entry-bad-signature-3.rs | 2 +- cortex-m-rt/tests/compile-fail/entry-hidden.rs | 2 +- cortex-m-rt/tests/compile-fail/entry-soundness.rs | 2 +- cortex-m-rt/tests/compile-fail/entry-twice.rs | 2 +- cortex-m-rt/tests/compile-fail/exception-args.rs | 2 +- cortex-m-rt/tests/compile-fail/exception-bad-signature-1.rs | 2 +- cortex-m-rt/tests/compile-fail/exception-bad-signature-2.rs | 2 +- cortex-m-rt/tests/compile-fail/exception-hidden.rs | 2 +- cortex-m-rt/tests/compile-fail/exception-soundness.rs | 2 +- cortex-m-rt/tests/compile-fail/exception-twice.rs | 2 +- cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-1.rs | 2 +- cortex-m-rt/tests/compile-fail/hard-fault-hidden.rs | 2 +- cortex-m-rt/tests/compile-fail/hard-fault-twice.rs | 2 +- cortex-m-rt/tests/compile-fail/pre-init-args.rs | 2 +- cortex-m-rt/tests/compile-fail/pre-init-bad-signature-1.rs | 2 +- cortex-m-rt/tests/compile-fail/pre-init-bad-signature-2.rs | 2 +- cortex-m-rt/tests/compile-fail/pre-init-hidden.rs | 2 +- cortex-m-rt/tests/compile-fail/pre-init-twice.rs | 2 +- 42 files changed, 42 insertions(+), 43 deletions(-) (limited to 'cortex-m-rt/examples/override-exception.rs') diff --git a/cortex-m-rt/Cargo.toml b/cortex-m-rt/Cargo.toml index 41a958d..ae72260 100644 --- a/cortex-m-rt/Cargo.toml +++ b/cortex-m-rt/Cargo.toml @@ -16,8 +16,7 @@ cortex-m-rt-macros = { path = "macros", version = "0.1.1" } [dev-dependencies] cortex-m = "0.5.4" -panic-abort = "0.3.0" -panic-semihosting = "0.4.0" +panic-halt = "0.2.0" [dev-dependencies.rand] default-features = false diff --git a/cortex-m-rt/examples/alignment.rs b/cortex-m-rt/examples/alignment.rs index 25d755d..4421e69 100644 --- a/cortex-m-rt/examples/alignment.rs +++ b/cortex-m-rt/examples/alignment.rs @@ -5,7 +5,7 @@ #![no_std] extern crate cortex_m_rt as rt; -extern crate panic_abort; +extern crate panic_halt; use core::ptr; diff --git a/cortex-m-rt/examples/data_overflow.rs b/cortex-m-rt/examples/data_overflow.rs index ceec18b..ea48b23 100644 --- a/cortex-m-rt/examples/data_overflow.rs +++ b/cortex-m-rt/examples/data_overflow.rs @@ -6,7 +6,7 @@ #![no_std] extern crate cortex_m_rt as rt; -extern crate panic_abort; +extern crate panic_halt; use core::ptr; diff --git a/cortex-m-rt/examples/device.rs b/cortex-m-rt/examples/device.rs index 950a564..dc1c738 100644 --- a/cortex-m-rt/examples/device.rs +++ b/cortex-m-rt/examples/device.rs @@ -6,7 +6,7 @@ #![no_std] extern crate cortex_m_rt as rt; -extern crate panic_semihosting; +extern crate panic_halt; use rt::entry; diff --git a/cortex-m-rt/examples/divergent-default-handler.rs b/cortex-m-rt/examples/divergent-default-handler.rs index cbb8bb1..22fa437 100644 --- a/cortex-m-rt/examples/divergent-default-handler.rs +++ b/cortex-m-rt/examples/divergent-default-handler.rs @@ -4,7 +4,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, exception}; diff --git a/cortex-m-rt/examples/divergent-exception.rs b/cortex-m-rt/examples/divergent-exception.rs index 9998884..cb2247b 100644 --- a/cortex-m-rt/examples/divergent-exception.rs +++ b/cortex-m-rt/examples/divergent-exception.rs @@ -3,7 +3,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, exception}; diff --git a/cortex-m-rt/examples/entry-static.rs b/cortex-m-rt/examples/entry-static.rs index 1b2e118..55e7a89 100644 --- a/cortex-m-rt/examples/entry-static.rs +++ b/cortex-m-rt/examples/entry-static.rs @@ -6,7 +6,7 @@ #![no_std] extern crate cortex_m_rt as rt; -extern crate panic_semihosting; +extern crate panic_halt; use rt::entry; diff --git a/cortex-m-rt/examples/main.rs b/cortex-m-rt/examples/main.rs index e5ce3d1..b8ab66e 100644 --- a/cortex-m-rt/examples/main.rs +++ b/cortex-m-rt/examples/main.rs @@ -5,7 +5,7 @@ #![no_std] extern crate cortex_m_rt as rt; -extern crate panic_semihosting; +extern crate panic_halt; #[no_mangle] pub unsafe extern "C" fn main() -> ! { diff --git a/cortex-m-rt/examples/minimal.rs b/cortex-m-rt/examples/minimal.rs index 6f60180..bd0a6ad 100644 --- a/cortex-m-rt/examples/minimal.rs +++ b/cortex-m-rt/examples/minimal.rs @@ -6,7 +6,7 @@ #![no_std] extern crate cortex_m_rt as rt; -extern crate panic_semihosting; +extern crate panic_halt; use rt::entry; diff --git a/cortex-m-rt/examples/override-exception.rs b/cortex-m-rt/examples/override-exception.rs index 3e0af25..6da6c5e 100644 --- a/cortex-m-rt/examples/override-exception.rs +++ b/cortex-m-rt/examples/override-exception.rs @@ -7,7 +7,7 @@ extern crate cortex_m; extern crate cortex_m_rt as rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m::asm; use rt::{entry, exception, ExceptionFrame}; diff --git a/cortex-m-rt/examples/pre_init.rs b/cortex-m-rt/examples/pre_init.rs index 00e2f2c..2c931bb 100644 --- a/cortex-m-rt/examples/pre_init.rs +++ b/cortex-m-rt/examples/pre_init.rs @@ -5,7 +5,7 @@ #![no_std] extern crate cortex_m_rt as rt; -extern crate panic_semihosting; +extern crate panic_halt; use rt::{entry, pre_init}; diff --git a/cortex-m-rt/examples/rand.rs b/cortex-m-rt/examples/rand.rs index e0cfd31..ec3afaa 100644 --- a/cortex-m-rt/examples/rand.rs +++ b/cortex-m-rt/examples/rand.rs @@ -7,7 +7,7 @@ extern crate cortex_m_rt as rt; use rt::entry; -extern crate panic_semihosting; +extern crate panic_halt; extern crate rand; use rand::Rng; diff --git a/cortex-m-rt/examples/state.rs b/cortex-m-rt/examples/state.rs index 573914f..ee6224d 100644 --- a/cortex-m-rt/examples/state.rs +++ b/cortex-m-rt/examples/state.rs @@ -6,7 +6,7 @@ #![no_std] extern crate cortex_m_rt as rt; -extern crate panic_semihosting; +extern crate panic_halt; use rt::{entry, exception}; diff --git a/cortex-m-rt/examples/unsafe-default-handler.rs b/cortex-m-rt/examples/unsafe-default-handler.rs index 48bd31e..a805c12 100644 --- a/cortex-m-rt/examples/unsafe-default-handler.rs +++ b/cortex-m-rt/examples/unsafe-default-handler.rs @@ -3,7 +3,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, exception}; diff --git a/cortex-m-rt/examples/unsafe-entry.rs b/cortex-m-rt/examples/unsafe-entry.rs index feb6f44..9dcbf33 100644 --- a/cortex-m-rt/examples/unsafe-entry.rs +++ b/cortex-m-rt/examples/unsafe-entry.rs @@ -3,7 +3,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::entry; diff --git a/cortex-m-rt/examples/unsafe-exception.rs b/cortex-m-rt/examples/unsafe-exception.rs index d67f06f..4212610 100644 --- a/cortex-m-rt/examples/unsafe-exception.rs +++ b/cortex-m-rt/examples/unsafe-exception.rs @@ -3,7 +3,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, exception}; diff --git a/cortex-m-rt/examples/unsafe-hard-fault.rs b/cortex-m-rt/examples/unsafe-hard-fault.rs index b091d47..b1d48f3 100644 --- a/cortex-m-rt/examples/unsafe-hard-fault.rs +++ b/cortex-m-rt/examples/unsafe-hard-fault.rs @@ -3,7 +3,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, exception, ExceptionFrame}; 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 037e9c8..72ea0fa 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 @@ -2,7 +2,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, exception}; 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 8fc4a7e..2e46a6b 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 @@ -2,7 +2,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, exception}; 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 059c10b..e57cb31 100644 --- a/cortex-m-rt/tests/compile-fail/default-handler-hidden.rs +++ b/cortex-m-rt/tests/compile-fail/default-handler-hidden.rs @@ -5,7 +5,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, exception}; 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 7d6ad98..ad1c3f9 100644 --- a/cortex-m-rt/tests/compile-fail/default-handler-twice.rs +++ b/cortex-m-rt/tests/compile-fail/default-handler-twice.rs @@ -2,7 +2,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, exception}; diff --git a/cortex-m-rt/tests/compile-fail/entry-args.rs b/cortex-m-rt/tests/compile-fail/entry-args.rs index 07cb4bd..b0d293c 100644 --- a/cortex-m-rt/tests/compile-fail/entry-args.rs +++ b/cortex-m-rt/tests/compile-fail/entry-args.rs @@ -2,7 +2,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::entry; diff --git a/cortex-m-rt/tests/compile-fail/entry-bad-signature-1.rs b/cortex-m-rt/tests/compile-fail/entry-bad-signature-1.rs index 5eeb49f..5fe9a1a 100644 --- a/cortex-m-rt/tests/compile-fail/entry-bad-signature-1.rs +++ b/cortex-m-rt/tests/compile-fail/entry-bad-signature-1.rs @@ -2,7 +2,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::entry; diff --git a/cortex-m-rt/tests/compile-fail/entry-bad-signature-2.rs b/cortex-m-rt/tests/compile-fail/entry-bad-signature-2.rs index 18bbaed..2b71a57 100644 --- a/cortex-m-rt/tests/compile-fail/entry-bad-signature-2.rs +++ b/cortex-m-rt/tests/compile-fail/entry-bad-signature-2.rs @@ -2,7 +2,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::entry; diff --git a/cortex-m-rt/tests/compile-fail/entry-bad-signature-3.rs b/cortex-m-rt/tests/compile-fail/entry-bad-signature-3.rs index 09b75e9..463e5b7 100644 --- a/cortex-m-rt/tests/compile-fail/entry-bad-signature-3.rs +++ b/cortex-m-rt/tests/compile-fail/entry-bad-signature-3.rs @@ -2,7 +2,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::entry; diff --git a/cortex-m-rt/tests/compile-fail/entry-hidden.rs b/cortex-m-rt/tests/compile-fail/entry-hidden.rs index 7d74063..836db0d 100644 --- a/cortex-m-rt/tests/compile-fail/entry-hidden.rs +++ b/cortex-m-rt/tests/compile-fail/entry-hidden.rs @@ -5,7 +5,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; mod hidden { use cortex_m_rt::entry; diff --git a/cortex-m-rt/tests/compile-fail/entry-soundness.rs b/cortex-m-rt/tests/compile-fail/entry-soundness.rs index 5e40a8f..9fc8ec1 100644 --- a/cortex-m-rt/tests/compile-fail/entry-soundness.rs +++ b/cortex-m-rt/tests/compile-fail/entry-soundness.rs @@ -2,7 +2,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, exception}; diff --git a/cortex-m-rt/tests/compile-fail/entry-twice.rs b/cortex-m-rt/tests/compile-fail/entry-twice.rs index b2819f6..757083a 100644 --- a/cortex-m-rt/tests/compile-fail/entry-twice.rs +++ b/cortex-m-rt/tests/compile-fail/entry-twice.rs @@ -2,7 +2,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::entry; diff --git a/cortex-m-rt/tests/compile-fail/exception-args.rs b/cortex-m-rt/tests/compile-fail/exception-args.rs index 85613ff..472a583 100644 --- a/cortex-m-rt/tests/compile-fail/exception-args.rs +++ b/cortex-m-rt/tests/compile-fail/exception-args.rs @@ -2,7 +2,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, exception}; diff --git a/cortex-m-rt/tests/compile-fail/exception-bad-signature-1.rs b/cortex-m-rt/tests/compile-fail/exception-bad-signature-1.rs index 966493e..e1fbf31 100644 --- a/cortex-m-rt/tests/compile-fail/exception-bad-signature-1.rs +++ b/cortex-m-rt/tests/compile-fail/exception-bad-signature-1.rs @@ -2,7 +2,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, exception}; diff --git a/cortex-m-rt/tests/compile-fail/exception-bad-signature-2.rs b/cortex-m-rt/tests/compile-fail/exception-bad-signature-2.rs index 8504771..ed46cf6 100644 --- a/cortex-m-rt/tests/compile-fail/exception-bad-signature-2.rs +++ b/cortex-m-rt/tests/compile-fail/exception-bad-signature-2.rs @@ -2,7 +2,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, exception}; diff --git a/cortex-m-rt/tests/compile-fail/exception-hidden.rs b/cortex-m-rt/tests/compile-fail/exception-hidden.rs index 053c81c..6f57089 100644 --- a/cortex-m-rt/tests/compile-fail/exception-hidden.rs +++ b/cortex-m-rt/tests/compile-fail/exception-hidden.rs @@ -5,7 +5,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, exception}; diff --git a/cortex-m-rt/tests/compile-fail/exception-soundness.rs b/cortex-m-rt/tests/compile-fail/exception-soundness.rs index 07d73fa..aae2476 100644 --- a/cortex-m-rt/tests/compile-fail/exception-soundness.rs +++ b/cortex-m-rt/tests/compile-fail/exception-soundness.rs @@ -2,7 +2,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, exception}; diff --git a/cortex-m-rt/tests/compile-fail/exception-twice.rs b/cortex-m-rt/tests/compile-fail/exception-twice.rs index 5377fce..aabbe5a 100644 --- a/cortex-m-rt/tests/compile-fail/exception-twice.rs +++ b/cortex-m-rt/tests/compile-fail/exception-twice.rs @@ -2,7 +2,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, exception}; 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 83fda5f..c2e9c31 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 @@ -2,7 +2,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, exception, ExceptionFrame}; diff --git a/cortex-m-rt/tests/compile-fail/hard-fault-hidden.rs b/cortex-m-rt/tests/compile-fail/hard-fault-hidden.rs index 31237c4..956310b 100644 --- a/cortex-m-rt/tests/compile-fail/hard-fault-hidden.rs +++ b/cortex-m-rt/tests/compile-fail/hard-fault-hidden.rs @@ -5,7 +5,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, exception, ExceptionFrame}; 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 90270e5..0bb6c8c 100644 --- a/cortex-m-rt/tests/compile-fail/hard-fault-twice.rs +++ b/cortex-m-rt/tests/compile-fail/hard-fault-twice.rs @@ -2,7 +2,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, exception, ExceptionFrame}; diff --git a/cortex-m-rt/tests/compile-fail/pre-init-args.rs b/cortex-m-rt/tests/compile-fail/pre-init-args.rs index 716b211..94d87bd 100644 --- a/cortex-m-rt/tests/compile-fail/pre-init-args.rs +++ b/cortex-m-rt/tests/compile-fail/pre-init-args.rs @@ -2,7 +2,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, pre_init}; diff --git a/cortex-m-rt/tests/compile-fail/pre-init-bad-signature-1.rs b/cortex-m-rt/tests/compile-fail/pre-init-bad-signature-1.rs index 58d3022..249f477 100644 --- a/cortex-m-rt/tests/compile-fail/pre-init-bad-signature-1.rs +++ b/cortex-m-rt/tests/compile-fail/pre-init-bad-signature-1.rs @@ -2,7 +2,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, pre_init}; diff --git a/cortex-m-rt/tests/compile-fail/pre-init-bad-signature-2.rs b/cortex-m-rt/tests/compile-fail/pre-init-bad-signature-2.rs index e47ed59..e942542 100644 --- a/cortex-m-rt/tests/compile-fail/pre-init-bad-signature-2.rs +++ b/cortex-m-rt/tests/compile-fail/pre-init-bad-signature-2.rs @@ -2,7 +2,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, pre_init}; diff --git a/cortex-m-rt/tests/compile-fail/pre-init-hidden.rs b/cortex-m-rt/tests/compile-fail/pre-init-hidden.rs index f512d62..63ab90b 100644 --- a/cortex-m-rt/tests/compile-fail/pre-init-hidden.rs +++ b/cortex-m-rt/tests/compile-fail/pre-init-hidden.rs @@ -5,7 +5,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; mod hidden { use cortex_m_rt::pre_init; diff --git a/cortex-m-rt/tests/compile-fail/pre-init-twice.rs b/cortex-m-rt/tests/compile-fail/pre-init-twice.rs index 5fb1ade..74a3f6b 100644 --- a/cortex-m-rt/tests/compile-fail/pre-init-twice.rs +++ b/cortex-m-rt/tests/compile-fail/pre-init-twice.rs @@ -2,7 +2,7 @@ #![no_std] extern crate cortex_m_rt; -extern crate panic_semihosting; +extern crate panic_halt; use cortex_m_rt::{entry, pre_init}; -- cgit v1.2.3 From bb868f4a90c6eff142801bc1a19b135483eed312 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sun, 23 Aug 2020 22:33:15 +0200 Subject: Fix examples --- cortex-m-rt/examples/divergent-default-handler.rs | 3 +-- cortex-m-rt/examples/override-exception.rs | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'cortex-m-rt/examples/override-exception.rs') 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 {} -- cgit v1.2.3