__attribute__

|



The '__attribute__ ( ( signal ) )' directive on the function prototype informs the compiler that the function is an ISR and results in two important changes in the compiler output.
  1. The 'signal' attribute ensures that every processor register that gets modified during the ISR is restored to its original value when the ISR exits. This is required as the compiler cannot make any assumptions as to when the interrupt will execute, and therefore cannot optimize which processor registers require saving and which don't.
  2. The 'signal' attribute also forces a 'return from interrupt' instruction (RETI) to be used in place of the 'return' instruction (RET) that would otherwise be used. The AVR microcontroller disables interrupts upon entering an ISR and the RETI instruction is required to re-enable them on exiting.



Avr-gcc defines an interrupt vector as a name that the linker will use to overide the weak reset addresses in the AVR interrupt vector table. For example, the USART0 receiver interrupt on an ATmega128 is defined as:

#define USART0_RX_vect       _VECTOR(18)

The _VECTOR(18) macro is expanded to:

#define USART0_RX_vect     __vector_18

and so the ISR macro used to define the corresponding interrupt handler in code expands to:

void __vector_18(void) __attribute__ ((signal, __INTR_ATTRS));

and this wll compile into the assembler output as the two lines:

.global  __vector_18
__vector_18:

The linker picks up the name as matching the corresponding interrupt vector table entry and makes the replacement into the vector table. Thus an interrupt with this number will arrive at the corresponding interrupt handler.

However in C++ the name is mangled early in the compile process and prevents the linking from occurring. Patch #6805 allows an interrupt handler name to be represented by a number, and while the name will be mangled as usual, the number survives for later linking. The patch provides for an optional numeric argument to the signal function. An interrupt function prototype using this system for the same USART0 receiver interrupt looks like:

void IntName(void) __attribute__ ((signal(18), __INTR_ATTRS)); 

The numeric signal argument is translated by this Patch into the same two assembler lines as above. The given name is still processed according to the language rules. The name is thus independent of the vector number, but the number is attached to the name. Note that for C++, by the time the signal argument is being processed the given name is mangled.

Once implemented the Patch can be used, but to be versatile it will require an additional definition for each interrupt in each processor. The current proposal is to add the new definition along with those existing. For example, the USART interrupt above for the '128 in file iom128.h will now have two lines.

#define USART0_RX_vect         _VECTOR(18)
#define USART0_RX_vect_num     18

The corresponding new interrupt macro for C++ interrupt declarations is defined in Interrupts.h as:

#define ISRN(name, number) void name(void) __attribute__ ((signal(number), __INTR_ATTRS));







And