Search code examples
c++arduinoisr

How do I specify an interrupt vector based on a parameter?


I am working with an Arduino Mega 2560 and have an application which requires the use of one of three different timers based on a parameter passed in by the caller. I need to be able to do something like this:

ISR(TIMERX_COMPA_vect){
  foo;
  bar;
}

Where X is the number of the timer passed in by the caller. I can't use preprocessor foo since the timer number is not known until the ISR is set up.

Followup

It appears that ISR() is preprocessor: avr/interrupt.h If so, what I want to do will not work. So... is there another way to add an interrupt service routine "on the fly?"


Solution

  • Based on some research on hardware interrupts, what I was trying to do does not appear possible. Generally speaking there are five steps to execute an interrupt:

    When an interrupt goes active, the microcontroller goes through the following steps:

    1. The microcontroller closes the currently executing instruction and saves the address of the next instruction (PC) on the stack.

    2. It also saves the current status of all the interrupts internally (i.e., not on the stack).

    3. It jumps to the memory location of the interrupt vector table that holds the address of the interrupts service routine.

    4. The microcontroller gets the address of the ISR from the interrupt vector table and jumps to it. It starts to execute the interrupt service subroutine, which is RETI (return from interrupt).

    5. Upon executing the RETI instruction, the microcontroller returns to the location where it was interrupted. First, it gets the program counter (PC) address from the stack by popping the top bytes of the stack into the PC. Then, it start to execute from that address.

    Since the ISR must be at the correct address (pointed to by the interrupt vector) before it is called (Step 4), it must be "completed" before being loaded into the Arduino and, thus, before run-time. So preprocessing is the latest one could use any sort of variable substitution in ISR interrupt vector assignment.