I'm writing a bare-metal application for an AMR board in Rust that involves interrupt service routines. Currently, I use #naked
functions with my own assembler prolog/epilog. However, I wonder whether there is a better (and hopefully more portable) way I've missed, maybe an #interrupt
-like attribute in Rust nightly or any other compiler support. I think along the lines of GCC's __attribute__ ((interrupt ("IRQ")))
, since Rust's backend LLVM provides such an attribute.
Interrupts are simply another type of calling convention. For the AVR port of Rust, we added two new types of calling convention, one for each kind of interrupt that AVR supports.
The authoritative list of calling conventions is the source code. Rust 1.16 lists these:
#[derive(PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Clone, Copy, Debug)]
pub enum Abi {
// NB: This ordering MUST match the AbiDatas array below.
// (This is ensured by the test indices_are_correct().)
// Single platform ABIs
Cdecl,
Stdcall,
Fastcall,
Vectorcall,
Aapcs,
Win64,
SysV64,
PtxKernel,
Msp430Interrupt,
// Multiplatform / generic ABIs
Rust,
C,
System,
RustIntrinsic,
RustCall,
PlatformIntrinsic,
Unadjusted
}
The unstable book also mentions that the different calling conventions exist.
To use these, you'd declare your function with it:
#![feature(abi_msp430_interrupt)]
extern "msp430-interrupt" fn handler() {}
It's still up to you to register the function as an exception handler with the interrupt vector table (or equivalent).
Of course, you may need to submit a PR that informs the Rust frontend of the specific LLVM calling convention to use, if yours isn't already in this list.