Code: Select all
void * random_interrupt_handler(int dummy)
{
if(dummy)
return &&handler;
handler:
asm(//ISR prologue goes here);
//C code
asm(//ISR epilogue goes here);
}
The good: The handler's prologue and epilogue consist entirely of our handwritten inline assembly, unlike the Wiki's black magic code, where part of the prologue is generated by the compiler and part is written by us, and we have to write an epilogue that matches the part of the prologue the compiler constructs.
The bad: The compiler will give a warning about returning the address of a local variable because we return &&handler. We also have to keep track of the number and size of local variables we use and make sure our prologue and epilogue create an appropriate stack for them (this is the flip side of "the good").
The ugly: Ideally, the first line of the function would simply be "return &&handler;". Unfortunately, that results in the handler code being "optimized" away by the compiler, even if options like -fno-dce are used. Therefore, we need to test a dummy variable with an if statement to convince the compiler that the handler code is actually needed. The wrapper function must always be called with "dummy" being non-zero, otherwise it will fall through to the interrupt handler, which is bad for obvious reasons.
I'd like to get people's opinions on how this compares to the "black magic" method listed on the Wiki. My impression is that it's less dependent on compiler internals (in that it doesn't depend on how the compiler generates stack handling code). Would you agree?