Using linker directives to conditionally choose code

Chris Lalancette clalancette@gmail.com
Sun Sep 14 13:45:00 GMT 2014


Thanks for the response.

On Sat, Sep 6, 2014 at 5:27 AM, Erik Christiansen
<dvalin@internode.on.net> wrote:
> On 05.09.14 15:01, Chris Lalancette wrote:
>> In the current system, all of the interrupt handlers are defined as
>> weak symbols, defaulting to an empty handler.  If you want to actually
>> handle the interrupt, you override the weak symbol with a strong
>> symbol, and handle the interrupt in your code.
>
> That method is commonly used, on a variety of platforms. It seems very
> generic, simple to use, and efficient at runtime. (Since code selection
> occurs at link time.) If a non-empty generic handler is preferred, then
> the substitution is trivial. (I tend to provide an alarm, since
> occurrence of an unhandled interrupt is a serious design/cpu_config
> error.)

Right.  At the moment I just crash with a stack trace, but an alarm is
a good idea.

>
>>     However, I'm trying to do something a little more generic, without
>> using (much) more flash space.  What I would like to do is to define a
>> "registration" interface where users of the API would register a
>> callback, and then there would be generic versions of the interrupt
>> handlers that would figure out which interrupt happened, clear it out,
>> and call the appropriate callback(s).
>
> ISTM that "generic" in this context means "runtime reconfigurable".
> (In that the existing link-time selection defaults to a generic handler,
> via the weak symbols, in the absence of overriding strong symbols. I.e.
> it does what your subject line asks for.)
>
>>  Something like:
>>
>> static (void)(*isr1_cb)(void);
>> static (void)(*isr2_cb)(void);
>>
>> void ISR_Handler(void)
>> {
>>     figure_out_which_interrupt_fired();
>>
>>     if (isr1_fired && isr1_cb)
>>         isr1_cb();
>>     if (isr2_fired && isr2_cb)
>>         isr2_cb();
>>
>>     clear_out_isr1_and_isr2();
>> }
>
> All the run-time "figure_out_which_interrupt_fired()" and "if
> (isr1_fired && isr1_cb)" rigmarole slows interrupt handling, and may be
> unacceptable in many hard real-time embedded applications. Have you
> considered achieving the runtime reconfigurability by simply using a
> function pointer at each interrupt handler? That avoids merging all
> interrupts into one, then thrashing about to untangle them again.
>
> Run-time arbitration of which ISR to run also precludes making these
> decisions at link-time, obviously. That leaves me struggling to
> understand how it would be possible to use "linker directives to
> conditionally choose code" in the described scenario?
>
> If I've missed something, then apologies.

I agree with you in that I don't really want to use a single interrupt
handler for all of my interrupts.  However, I should have explained
more about the processor.  On this processor, there are several
interrupts that multiple peripherals share (say, SPI2 and CAN1), and
that you *must* untangle in software.  However, the places in the code
that handle these are separate, and I'd like to make it so that you
can enable one, or both, or neither, and the right thing will happen.
That's the genesis of my question.

Thanks,
Chris



More information about the Binutils mailing list