-
Notifications
You must be signed in to change notification settings - Fork 238
/
Copy pathuno-panic.rs
98 lines (87 loc) · 3.2 KB
/
uno-panic.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/*!
* Example of a custom panic handler.
*
* The panic handler will print out where the panic occurred and then blink the oboard LED rapidly
* to make the user aware of the problem.
*/
#![no_std]
#![no_main]
use arduino_hal::prelude::*;
// Documentation build does not like this and fails with the following error, even though
// everything is fine when compiling the binary.
//
// error[E0152]: found duplicate lang item `panic_impl`
//
// Ignore the panic handler in documentation builds. This is not needed in downstream code, it is
// an artifact of the avr-hal examples structure.
#[cfg(not(doc))]
#[panic_handler]
fn panic(info: &core::panic::PanicInfo) -> ! {
// disable interrupts - firmware has panicked so no ISRs should continue running
avr_device::interrupt::disable();
// get the peripherals so we can access serial and the LED.
//
// SAFETY: Because main() already has references to the peripherals this is an unsafe
// operation - but because no other code can run after the panic handler was called,
// we know it is okay.
let dp = unsafe { arduino_hal::Peripherals::steal() };
let pins = arduino_hal::pins!(dp);
let mut serial = arduino_hal::default_serial!(dp, pins, 57600);
ufmt::uwriteln!(&mut serial, "Firmware panic!\r").unwrap_infallible();
// Accessing the panic info unfortunately means that the optimizer can no longer remove panic
// messages from the resulting binary. This leads to an explosion of SRAM usage, quickly
// surpassing available space.
//
// If you need precise panic info, currently your best bet is disabling `overflow-checks` and
// `debug-assertions` in the build profile and structuring your code such that panics never
// include a message payload. For example, instead of calling `.unwrap()`, use these macros:
//
// #[macro_export]
// macro_rules! unwrap_result {
// ($v:expr) => {
// match $v {
// Ok(v) => v,
// Err(_) => panic!(),
// }
// };
// }
//
// #[macro_export]
// macro_rules! unwrap_option {
// ($v:expr) => {
// match $v {
// Some(v) => v,
// None => panic!(),
// }
// };
// }
// Print panic location:
// if let Some(loc) = info.location() {
// ufmt::uwriteln!(
// &mut serial,
// " At {}:{}:{}\r",
// loc.file(),
// loc.line(),
// loc.column(),
// )
// .unwrap_infallible();
// }
// Blink LED rapidly
let mut led = pins.d13.into_output();
loop {
led.toggle();
arduino_hal::delay_ms(100);
}
}
#[arduino_hal::entry]
fn main() -> ! {
let dp = arduino_hal::Peripherals::take().unwrap();
let pins = arduino_hal::pins!(dp);
let mut serial = arduino_hal::default_serial!(dp, pins, 57600);
ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").unwrap_infallible();
ufmt::uwriteln!(&mut serial, "Panic in 5 seconds!\r").unwrap_infallible();
arduino_hal::delay_ms(5000);
// Panic messages cannot yet be captured because they rely on core::fmt
// which is way too big for AVR
panic!();
}