This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Using linker directives to conditionally choose code
- From: Chris Lalancette <clalancette at gmail dot com>
- To: dvalin at internode dot on dot net
- Cc: binutils <binutils at sourceware dot org>
- Date: Sun, 14 Sep 2014 09:45:21 -0400
- Subject: Re: Using linker directives to conditionally choose code
- Authentication-results: sourceware.org; auth=none
- References: <CABMb9Gs4VyPv2WoaU5mEwaVmHHXu44HNdF=R2xpyhnD1_meyXw at mail dot gmail dot com> <20140906092744 dot GA2033 at ratatosk>
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