AVRoxide can be configured to signal error conditions (for example, out of
memory) via a series of pulses on one of the AVR’s I/O pins. This allows
you to have some idea of what is happening even without the heavy overhead
of Rust’s panic
mechanism (or in environments where you don’t have a serial
port for panic to write error information to.)
If you are building with one of the Arduino compatibility features, then by default AVRoxide will use the Arduino’s built-in LED as the debug pin. So, in simple terms - a flashing Arduino LED means an error condition has occurred.
Configuring the debug pin
You can set the pin to be used for these debug signals using the
avr_oxide::oserror::set_debug_pin()
method; simply pass it a reference
to the Pin
that you want debug codes to be output on:
avr_oxide::oserror::set_debug_pin(avr_oxide::hardware::portd::pin(5));
The codes are repeated continuously, except under two conditions:
- You have set up the Watchdog Timer device, which will eventually automatically restart the device (the error-code routine does NOT kick the watchdog.)
- You have attached a debugger/ICE to the target device, in which case after the first code has been completed AVRoxide will drop into the debugger using a
break
instruction.)
Error Code Table
Errors are communicated via series of short pulses (shown as ○ in the table below) and long pulses (shown as ✺).
If a panic serial port has been configured (via the panicout
feature), the
error will also be written to the serial port (followed by a thread dump)
as an integer:
HALT: 1397
The table below shows both the debug pin pulse codes and the integer serial panic codes:
Pulse code | Integer code | Indicated error condition |
---|---|---|
○ | 1 | Not enough RAM on the device for minimum heap.1 |
○○ | 5 | Out of memory (heap alloc - e.g. Box::new() - failed.) |
○○✺ | 117 | A StaticWrap container was dropped |
○○✺○ | 373 | StaticWrap borrowing rules were broken |
○○○ | 21 | User thread stack overflow. |
✺○○○ | 343 | Kernel stack overflow. |
✺○○✺ | 1879 | Kernel memory guard corrupted.. |
✺✺○○○ | 5495 | Oxide event queue overflow. |
○○○○ | 85 | No thread could be scheduled for execution. |
✺○○○○ | 1367 | Cannot yield thread while interrupts disabled |
○○○○○ | 341 | An internal AVRoxide error occurred. |
○○✺○○ | 1397 | Bad thread state change (blocking inside an ISR?) |
○○○○○○ | 1365 | Attempt to create a thread failed (too many threads). |
○○○○○○○ | 5461 | The application freed the same memory allocation twice. |
○✺ | 29 | Bad params to a system call (e.g. impossible clock freq). |
○✺✺ | 477 | Arithmetic error (e.g. overflow.) |
○✺✺✺ | 7645 | The application called panic!() |
○✺✺✺○ | 24029 | The application unwrapped an Error` |
○✺✺✺○○ | 89565 | The application unwrapped a None |
-
AVRoxide will create a heap using all the available device RAM after the
.data
and.BSS
segments of your program are taken into account.
If not enough RAM is available to do so, AVRoxide will refuse to start and you will need to find a way to reduce your program’s memory use (e.g. disabling the Rust built-in Panic mechanism by enabling thepanic_immediate_abort
feature in.cargo/config.toml
). ↩︎