ruduino icon indicating copy to clipboard operation
ruduino copied to clipboard

Interrupt handler symbol name incorrect?

Open nh2 opened this issue 6 years ago • 6 comments

The README shows

pub unsafe extern "avr-interrupt" fn _ivr_timer1_compare_a() {

as interrupt handler for timer1 but that didn't work for me on the Arduino Uno Rev3.

Every time the interrupt arrived, the board did a full reset because no interrupt handler was correctly defined.

This worked:

pub unsafe extern "C" fn __vector_11() {

as that is what ISR(TIMER1_COMPA_vect) (see e.g. here) expands to when used from the Arduino IDE.

nh2 avatar Aug 06 '18 10:08 nh2

I just learned it should be

pub unsafe extern "avr-interrupt" fn __vector_11() {

instead of

pub unsafe extern "C" fn __vector_11() {

because otherwise the ISR can be called only once.

I suspect that is about

Patching into the vector table is only one part of the problem. The compiler uses, by convention, a set of registers when it's normally executing compiler-generated code. It's important that these registers, as well as the status register, get saved and restored. The extra code needed to do this is enabled by tagging the interrupt function with __attribute__((signal)).

from http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html

In particular TIFR1 becomes 6 with extern "C" and 4 with extern "avr-interrupt".

nh2 avatar Aug 07 '18 01:08 nh2

By the way, I implemented Arduino's micros() logic and counter/interrupt approach in Rust for a project here, in case anybody is interested:

https://github.com/nh2/quadcopter-simulation/blob/8a3652b8a704877156e91c0691ce8ce37588eb53/arduino-accel-rust/src/main.rs#L216

Would be nice to move much of that into ruduino later.

nh2 avatar Aug 08 '18 00:08 nh2

I wonder if the interrupt vector symbol name depends on the assembly code chosen for the IVT table.

For example, here's the objdump output of a hello world executable compiled with avr-gcc with an -mmcu specified. This will correspond to some assembly code (probably in the device-specific CRT) that will jump to interrupt functions like jmp __vector_11. I don't think we have an interrupt table included by default in avr-rust executables - there isn't any CRT loading done in Rust.

00000000 <__vectors>:
   0:   0c 94 34 00     jmp     0x68    ; 0x68 <__ctors_end>
   4:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
   8:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
   c:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  10:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  14:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  18:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  1c:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  20:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  24:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  28:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  2c:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  30:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  34:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  38:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  3c:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  40:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  44:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  48:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  4c:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  50:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  54:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  58:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  5c:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  60:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  64:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>

Perhaps the README is using a different IVT jump table with different interrupt function symbol names?

It raises a good question - how to go about standardising it

dylanmckay avatar Sep 01 '18 12:09 dylanmckay

if the interrupt vector symbol name depends on the assembly code chosen for the IVT table.

Yes, it certainly does. The one shown comes from my custom assembly, which has the aim of not linking to any avr-gcc code whatsoever. This means I get to pick more expressive names.

shepmaster avatar Nov 06 '18 16:11 shepmaster

Raised #12 for coming up with a single, ecosystem-wide way to define interrupts.

dylanmckay avatar Nov 07 '18 03:11 dylanmckay

Does the function actually need to be declared unsafe?

lord-ne avatar Aug 25 '21 19:08 lord-ne