5 ms·
Why is it necessary to mark the interrupt handler and the panic formatting function as extern C functions? Is the C way of doing that set in silicon?
by madez 9y ago
Why is it necessary to mark the interrupt handler and the panic formatting function as extern C functions? Is the C way of doing that set in silicon?
- m1el 9y agoC and Rust (can) have different calling conventions. C is the de-facto standard calling convention. When you mark a function as `extern "C"`, it means that it can be called as if it is a C function.
- madez 9y agoBut what C code is running alongside the Rust code on the microcontroller that would make adhering to the C calling convention necessary? Is the hardware expecting the C calling convention?
- friendzis 9y agoI just skimmed over this, toolchain setup talks about TivaTi/Stellaris, code is for STM32F. My memory is muddy on this, so take it with a bit of salt. Cores have specific "interrupt context" (do not recall the actual name) with a specific set of call[er]-saved registers (EABI). Making fault handlers `extern C` is a way to ensure that these functions adhere to that EABI and do not clobber processor state. Probably.
- TickleSteve 9y agoThere is an interrupt-mode stack and a user-mode stack, the stacks are switched on interrupt invocation. The value pushed on to the stack is a special value that causes a pop into SP to switch stacks back on return.
- TickleSteve 9y agoyes, ARM ISRs use the C calling convention, and they should be marked as extern because they're effectively at global scope and can be invoked from anywhere.
- leggomylibro 9y agoI don't know much of anything about Rust, and I have a pretty limited knowledge of ARM, but I think that the 'Nested Vector Interrupt Controller' basically just pushes a stack frame and jumps to the memory location specified in a vector table that lives near the start of memory. That sounds like how C functions are called; does Rust do something different?
- dbaupp 9y agoThe fundamentals of pushing a stack frame and jumping is the same, but the details of how arguments are passed (e.g. is a value in registers, or on the stack) and return values returned differ between the calling conventions.