Description
I lately run into an issue when in the need to declare my own PCI ISR (of unused pins) that caused compilation (on UNO) to abort due to duplicate symbol of the specific _vector.
I have seen several issues that describe such conflicts (multiple definitions of _vector) caused by declarations of the same ISRs within multiple sources. E.g.:
arduino/ArduinoCore-avr#419,
arduino/ArduinoCore-avr#378
https://forum.arduino.cc/t/disable-hwserial-library-at-compile-time/164625
https://forum.arduino.cc/t/error-multiple-definition-of-__vector_13/579477
I have seen that some of the solutions were using __attribute(weak) to enable overriding of the ISR by non weak declarations.
However, I think this method is "weak" by itself. Since we need to support user code override of ISRs we will need to make all AVR definition of the ISRs weak. And then rely on linking order?
I claim that a good solution should not do that. Instead we should treat ISR declarations as interface/API of any module that declares them. Since only the pre-processor can avoid code segments, and in the restriction of not changing current default behavior, we will need to provide optional "define" statements to disable ISR code from being included.
For example from SoftwareSerial.c Instead of:
#if defined(PCINT0_vect)
ISR(PCINT0_vect) { SoftwareSerial::handle_interrupt(); }
#endif
Use:
#if defined(PCINT0_vect)
#ifndef (SWSERIAL_NO_PCINT0)
ISR(PCINT0_vect)
{
SoftwareSerial::handle_interrupt();
}
#endif
#endif
Some further complication may arise from SoftwareSerial using the same ISR for all by using ISR_ALIASOF.
If that is an important optimization, it is possible to use more complex logic to decide if to use the alias or it is the first ISR defined.