feat: add display UI with splash screen, dashboard, and RSSI sparkline
Implement full SSD1306 OLED display support: - Splash screen on boot (1.5s) with project name, version, board - Dashboard showing radio state, config, counters, RSSI/SNR - RSSI history sparkline (64-sample ring buffer, 2px-wide bars) - DisplayOn/DisplayOff host commands routed via dedicated channel - Pure render functions against generic DrawTarget (no hardware coupling) - Display on/off control bypasses radio task entirely Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
17624 files changed
+4564928
-38
No files matched your search
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
# How to run
|
||||
|
||||
To run the compile tests, use the following command on the root of the project:
|
||||
|
||||
```
|
||||
cargo test --package cortex-m-rt --test compiletest --features device
|
||||
```
|
||||
@@ -0,0 +1,16 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, exception};
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[exception]
|
||||
unsafe fn DefaultHandler(_irqn: i16, undef: u32) {}
|
||||
//~^ ERROR `DefaultHandler` must have signature `unsafe fn(i16) [-> !]`
|
||||
@@ -0,0 +1,18 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, exception};
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[exception]
|
||||
unsafe fn DefaultHandler(_irqn: i16) -> u32 {
|
||||
//~^ ERROR `DefaultHandler` must have signature `unsafe fn(i16) [-> !]`
|
||||
0
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// ignore-test :sadface: it's not possible to prevent this user error at compile time
|
||||
// see rust-lang/rust#53975 for details
|
||||
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, exception};
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
mod hidden {
|
||||
use cortex_m_rt::exception;
|
||||
|
||||
#[exception]
|
||||
unsafe fn DefaultHandler(_irqn: i16) {}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, exception};
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[exception]
|
||||
unsafe fn DefaultHandler(_irqn: i16) {}
|
||||
|
||||
pub mod reachable {
|
||||
use cortex_m_rt::exception;
|
||||
|
||||
#[exception] //~ ERROR symbol `DefaultHandler` is already defined
|
||||
unsafe fn DefaultHandler(_irqn: i16) {}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, exception, interrupt};
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
enum interrupt {
|
||||
UART0,
|
||||
}
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
static mut X: u32 = 0;
|
||||
static mut X: i32 = 0; //~ ERROR the name `X` is defined multiple times
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[exception]
|
||||
fn SVCall() {
|
||||
static mut X: u32 = 0;
|
||||
static mut X: i32 = 0; //~ ERROR the name `X` is defined multiple times
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn UART0() {
|
||||
static mut X: u32 = 0;
|
||||
static mut X: i32 = 0; //~ ERROR the name `X` is defined multiple times
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::entry;
|
||||
|
||||
#[entry(foo)] //~ ERROR This attribute accepts no arguments
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::entry;
|
||||
|
||||
#[entry]
|
||||
fn foo() {}
|
||||
//~^ ERROR `#[entry]` function must have signature `[unsafe] fn() -> !`
|
||||
@@ -0,0 +1,11 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::entry;
|
||||
|
||||
#[entry]
|
||||
fn foo(undef: i32) -> ! {}
|
||||
//~^ ERROR `#[entry]` function must have signature `[unsafe] fn() -> !`
|
||||
@@ -0,0 +1,13 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::entry;
|
||||
|
||||
#[entry]
|
||||
extern "C" fn foo() -> ! {
|
||||
//~^ ERROR `#[entry]` function must have signature `[unsafe] fn() -> !`
|
||||
loop {}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// ignore-test :sadface: it's not possible to prevent this user error at compile time
|
||||
// see rust-lang/rust#53975 for details
|
||||
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
mod hidden {
|
||||
use cortex_m_rt::entry;
|
||||
|
||||
// this function needs to be "reachable" (all modules between it and the crate root must be
|
||||
// `pub`) or linking will fail
|
||||
#[entry]
|
||||
fn foo() -> ! { //~ ERROR function is never used
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, exception};
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
static mut COUNT: u64 = 0;
|
||||
|
||||
loop {
|
||||
if *COUNT % 2 == 0 {
|
||||
*COUNT += 1;
|
||||
} else {
|
||||
*COUNT *= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[exception]
|
||||
fn SysTick() {
|
||||
// If this was allowed it would lead to a data race as `SysTick` can preempt `foo`
|
||||
foo(); //~ ERROR cannot find function `foo` in this scope
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::entry;
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[entry] //~ ERROR symbol `main` is already defined
|
||||
fn bar() -> ! {
|
||||
loop {}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, exception};
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[exception(SysTick)] //~ ERROR This attribute accepts no arguments
|
||||
fn SysTick() {}
|
||||
@@ -0,0 +1,16 @@
|
||||
#![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 SysTick(undef: u32) {}
|
||||
//~^ ERROR `#[exception]` handlers other than `DefaultHandler` and `HardFault` must have signature `[unsafe] fn() [-> !]`
|
||||
@@ -0,0 +1,18 @@
|
||||
#![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 SysTick() -> u32 {
|
||||
//~^ ERROR `#[exception]` handlers other than `DefaultHandler` and `HardFault` must have signature `[unsafe] fn() [-> !]`
|
||||
0
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// ignore-test :sadface: it's not possible to prevent this user error at compile time
|
||||
// see rust-lang/rust#53975 for details
|
||||
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, exception};
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
mod hidden {
|
||||
use cortex_m_rt::exception;
|
||||
|
||||
#[exception]
|
||||
fn SysTick() {}
|
||||
}
|
||||
@@ -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`
|
||||
@@ -0,0 +1,29 @@
|
||||
#![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 SysTick() {
|
||||
static mut COUNT: u64 = 0;
|
||||
|
||||
if *COUNT % 2 == 0 {
|
||||
*COUNT += 1;
|
||||
} else {
|
||||
*COUNT *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
#[exception]
|
||||
fn SVCall() {
|
||||
// If this was allowed it would lead to a data race as `SVCall` could preempt `SysTick`
|
||||
SysTick(); //~ ERROR cannot find function, tuple struct or tuple variant `SysTick` in this scope [E0425]
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#![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 SysTick() {}
|
||||
|
||||
pub mod reachable {
|
||||
use cortex_m_rt::exception;
|
||||
|
||||
#[exception] //~ ERROR symbol `SysTick` is already defined
|
||||
fn SysTick() {}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#![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 SecureFault() {}
|
||||
//~^ ERROR no variant or associated item named `SecureFault`
|
||||
@@ -0,0 +1,18 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, exception, ExceptionFrame};
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[exception]
|
||||
unsafe fn HardFault(_ef: &ExceptionFrame, undef: u32) -> ! {
|
||||
//~^ ERROR `HardFault` handler must have signature `unsafe fn(&ExceptionFrame) -> !`
|
||||
loop {}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, exception, ExceptionFrame};
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[exception(trampoline = true)]
|
||||
unsafe fn HardFault() -> ! {
|
||||
//~^ ERROR `HardFault` handler must have signature `unsafe fn(&ExceptionFrame) -> !`
|
||||
loop {}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, exception, ExceptionFrame};
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[exception(trampoline = false)]
|
||||
unsafe fn HardFault(_ef: &ExceptionFrame) -> ! {
|
||||
//~^ ERROR `HardFault` handler must have signature `unsafe fn() -> !`
|
||||
loop {}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// ignore-test :sadface: it's not possible to prevent this user error at compile time
|
||||
// see rust-lang/rust#53975 for details
|
||||
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, exception, ExceptionFrame};
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
mod hidden {
|
||||
use cortex_m_rt::{exception, ExceptionFrame};
|
||||
|
||||
#[exception]
|
||||
fn HardFault(_ef: &ExceptionFrame) -> ! {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, exception, ExceptionFrame};
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[exception(trampoline = false)]
|
||||
unsafe fn HardFault() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
pub mod reachable {
|
||||
use cortex_m_rt::{exception, ExceptionFrame};
|
||||
|
||||
#[exception] //~ ERROR symbol `_HardFault` is already defined
|
||||
unsafe fn HardFault(_ef: &ExceptionFrame) -> ! {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, exception, ExceptionFrame};
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[exception]
|
||||
unsafe fn HardFault(_ef: &ExceptionFrame) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
pub mod reachable {
|
||||
use cortex_m_rt::{exception, ExceptionFrame};
|
||||
|
||||
#[exception] //~ ERROR symbol `_HardFault` is already defined
|
||||
unsafe fn HardFault(_ef: &ExceptionFrame) -> ! {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, interrupt};
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
enum interrupt {
|
||||
USART1,
|
||||
}
|
||||
|
||||
#[interrupt(true)] //~ ERROR This attribute accepts no arguments
|
||||
fn USART1() {}
|
||||
@@ -0,0 +1,21 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, interrupt};
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
enum interrupt {
|
||||
USART1,
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn USART1(undef: i32) {}
|
||||
//~^ ERROR `#[interrupt]` handlers must have signature `[unsafe] fn() [-> !]`
|
||||
@@ -0,0 +1,23 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, interrupt};
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
enum interrupt {
|
||||
USART1,
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn USART1() -> i32 {
|
||||
//~^ ERROR `#[interrupt]` handlers must have signature `[unsafe] fn() [-> !]`
|
||||
0
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, interrupt};
|
||||
|
||||
#[entry]
|
||||
fn entry() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
enum interrupt {
|
||||
USART1,
|
||||
}
|
||||
|
||||
// NOTE this looks a bit better when using a device crate:
|
||||
// "no variant named `foo` found for type `stm32f30x::Interrupt` in the current scope"
|
||||
#[interrupt]
|
||||
fn foo() {} //~ ERROR no variant or associated item named `foo` found for enum `interrupt` in the current scope [E0599]
|
||||
@@ -0,0 +1,15 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, interrupt};
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[interrupt] //~ ERROR failed to resolve: use of undeclared crate or module `interrupt`
|
||||
fn USART1() {}
|
||||
@@ -0,0 +1,34 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, interrupt};
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
enum interrupt {
|
||||
USART1,
|
||||
USART2,
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn USART1() {
|
||||
static mut COUNT: u64 = 0;
|
||||
|
||||
if *COUNT % 2 == 0 {
|
||||
*COUNT += 1;
|
||||
} else {
|
||||
*COUNT *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn USART2() {
|
||||
USART1(); //~ ERROR cannot find function, tuple struct or tuple variant `USART1` in this scope [E0425]
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, interrupt};
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
enum interrupt {
|
||||
USART1,
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn USART1() {}
|
||||
|
||||
pub mod reachable {
|
||||
use cortex_m_rt::interrupt;
|
||||
|
||||
enum interrupt {
|
||||
USART1,
|
||||
}
|
||||
|
||||
#[interrupt] //~ ERROR symbol `USART1` is already defined
|
||||
fn USART1() {}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
//! Tests that no `&'static mut` to static mutable resources can be obtained, which would be
|
||||
//! unsound.
|
||||
//!
|
||||
//! Regression test for https://github.com/rust-embedded/cortex-m-rt/issues/212
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, exception, interrupt, ExceptionFrame};
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
enum interrupt {
|
||||
UART0,
|
||||
}
|
||||
|
||||
#[exception]
|
||||
fn SVCall() {
|
||||
static mut STAT: u8 = 0;
|
||||
|
||||
let _stat: &'static mut u8 = STAT;
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn UART0() {
|
||||
static mut STAT: u8 = 0;
|
||||
|
||||
let _stat: &'static mut u8 = STAT;
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
}
|
||||
|
||||
#[entry]
|
||||
fn you_died_of_dis_entry() -> ! {
|
||||
static mut STAT: u8 = 0;
|
||||
|
||||
// Allowed. This is sound for the entry point since it is only ever called once, and it makes
|
||||
// resources far more useful.
|
||||
let _stat: &'static mut u8 = STAT;
|
||||
|
||||
loop {}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, pre_init};
|
||||
|
||||
#[pre_init(foo)] //~ ERROR This attribute accepts no arguments
|
||||
unsafe fn foo() {}
|
||||
|
||||
#[entry]
|
||||
fn baz() -> ! {
|
||||
loop {}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, pre_init};
|
||||
|
||||
#[pre_init]
|
||||
fn foo() {}
|
||||
//~^ ERROR `#[pre_init]` function must have signature `unsafe fn()`
|
||||
|
||||
#[entry]
|
||||
fn bar() -> ! {
|
||||
loop {}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, pre_init};
|
||||
|
||||
#[pre_init]
|
||||
unsafe fn foo(undef: i32) {}
|
||||
//~^ ERROR `#[pre_init]` function must have signature `unsafe fn()`
|
||||
|
||||
#[entry]
|
||||
fn bar() -> ! {
|
||||
loop {}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// ignore-test :sadface: it's not possible to prevent this user error at compile time
|
||||
// see rust-lang/rust#53975 for details
|
||||
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
mod hidden {
|
||||
use cortex_m_rt::pre_init;
|
||||
|
||||
// this function needs to be "reachable" (all modules between it and the crate root must be
|
||||
// `pub`) or the function will be ignored
|
||||
#[entry]
|
||||
unsafe fn pre_init() {} //~ ERROR function is never used
|
||||
}
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
//~ ERROR function is never used
|
||||
loop {}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, pre_init};
|
||||
|
||||
#[pre_init]
|
||||
unsafe fn foo() {}
|
||||
|
||||
#[pre_init] //~ ERROR symbol `__pre_init` is already defined
|
||||
unsafe fn bar() {}
|
||||
|
||||
#[entry]
|
||||
fn baz() -> ! {
|
||||
loop {}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
//! Makes sure that the expansion of the attributes doesn't put the resource initializer in an
|
||||
//! implicit `unsafe` block.
|
||||
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, exception, interrupt};
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
enum interrupt {
|
||||
UART0,
|
||||
}
|
||||
|
||||
const unsafe fn init() -> u32 { 0 }
|
||||
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
static mut X: u32 = init(); //~ ERROR requires unsafe
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[exception]
|
||||
fn SVCall() {
|
||||
static mut X: u32 = init(); //~ ERROR requires unsafe
|
||||
}
|
||||
|
||||
#[exception]
|
||||
unsafe fn DefaultHandler(_irq: i16) {
|
||||
static mut X: u32 = init(); //~ ERROR requires unsafe
|
||||
}
|
||||
|
||||
#[exception]
|
||||
unsafe fn HardFault(_frame: &cortex_m_rt::ExceptionFrame) -> ! {
|
||||
static mut X: u32 = init(); //~ ERROR requires unsafe
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn UART0() {
|
||||
static mut X: u32 = init(); //~ ERROR requires unsafe
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, exception, interrupt};
|
||||
|
||||
#[inline] //~ ERROR this attribute is not allowed on a cortex-m-rt entry point
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[inline] //~ ERROR this attribute is not allowed on an exception handler controlled by cortex-m-rt
|
||||
#[exception]
|
||||
fn SysTick() {}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
enum interrupt {
|
||||
USART1,
|
||||
USART2,
|
||||
}
|
||||
|
||||
#[inline] //~ ERROR this attribute is not allowed on an interrupt handler controlled by cortex-m-rt
|
||||
#[interrupt]
|
||||
fn USART1() {}
|
||||
|
||||
#[cfg(feature = "device")]
|
||||
#[cfg_attr(feature = "device", inline)] //~ ERROR this attribute is not allowed on an interrupt handler controlled by cortex-m-rt
|
||||
#[interrupt]
|
||||
fn USART2() {}
|
||||
@@ -0,0 +1,32 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, exception, interrupt};
|
||||
|
||||
#[export_name = "not_allowed"] //~ ERROR this attribute is not allowed on a cortex-m-rt entry point
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[export_name = "not_allowed"] //~ ERROR this attribute is not allowed on an exception handler controlled by cortex-m-rt
|
||||
#[exception]
|
||||
fn SysTick() {}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
enum interrupt {
|
||||
USART1,
|
||||
USART2,
|
||||
}
|
||||
|
||||
#[export_name = "not_allowed"] //~ ERROR this attribute is not allowed on an interrupt handler controlled by cortex-m-rt
|
||||
#[interrupt]
|
||||
fn USART1() {}
|
||||
|
||||
#[cfg(feature = "device")]
|
||||
#[cfg_attr(feature = "device", export_name = "not_allowed")] //~ ERROR this attribute is not allowed on an interrupt handler controlled by cortex-m-rt
|
||||
#[interrupt]
|
||||
fn USART2() {}
|
||||
@@ -0,0 +1,32 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, exception, interrupt};
|
||||
|
||||
#[no_mangle] //~ ERROR this attribute is not allowed on a cortex-m-rt entry point
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[no_mangle] //~ ERROR this attribute is not allowed on an exception handler controlled by cortex-m-rt
|
||||
#[exception]
|
||||
fn SysTick() {}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
enum interrupt {
|
||||
USART1,
|
||||
USART2,
|
||||
}
|
||||
|
||||
#[no_mangle] //~ ERROR this attribute is not allowed on an interrupt handler controlled by cortex-m-rt
|
||||
#[interrupt]
|
||||
fn USART1() {}
|
||||
|
||||
#[cfg(feature = "device")]
|
||||
#[cfg_attr(feature = "device", no_mangle)] //~ ERROR this attribute is not allowed on an interrupt handler controlled by cortex-m-rt
|
||||
#[interrupt]
|
||||
fn USART2() {}
|
||||
@@ -0,0 +1,32 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, exception, interrupt};
|
||||
|
||||
#[must_use] //~ ERROR this attribute is not allowed on a cortex-m-rt entry point
|
||||
#[entry]
|
||||
fn foo() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[must_use] //~ ERROR this attribute is not allowed on an exception handler controlled by cortex-m-rt
|
||||
#[exception]
|
||||
fn SysTick() {}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
enum interrupt {
|
||||
USART1,
|
||||
USART2,
|
||||
}
|
||||
|
||||
#[must_use] //~ ERROR this attribute is not allowed on an interrupt handler controlled by cortex-m-rt
|
||||
#[interrupt]
|
||||
fn USART1() {}
|
||||
|
||||
#[cfg(feature = "device")]
|
||||
#[cfg_attr(feature = "device", must_use)] //~ ERROR this attribute is not allowed on an interrupt handler controlled by cortex-m-rt
|
||||
#[interrupt]
|
||||
fn USART2() {}
|
||||
@@ -0,0 +1,13 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m_rt;
|
||||
extern crate panic_halt;
|
||||
|
||||
use cortex_m_rt::{entry, exception};
|
||||
|
||||
#[exception]
|
||||
#[entry] //~ ERROR this attribute is not allowed on an exception handler
|
||||
fn SVCall() -> ! {
|
||||
loop {}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
extern crate compiletest_rs as compiletest;
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn run_mode(mode: &'static str) {
|
||||
let mut config = compiletest::Config::default();
|
||||
|
||||
config.mode = mode.parse().expect("Invalid mode");
|
||||
config.src_base = PathBuf::from(format!("tests/{}", mode));
|
||||
config.target_rustcflags = Some(
|
||||
"-L ../target/debug -L ../target/debug/deps -C panic=abort --cfg feature=\"device\""
|
||||
.to_owned(),
|
||||
);
|
||||
config.clean_rmeta(); // If your tests import the parent crate, this helps with E0464
|
||||
|
||||
compiletest::run_tests(&config);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compile_test() {
|
||||
run_mode("compile-fail");
|
||||
}
|
||||
Reference in new issue
Block a user