Using linker directives to conditionally choose code
Nicholas Clifton
nickc@redhat.com
Mon Sep 8 09:36:00 GMT 2014
Hi Chris,
> I could easily accomplish this by defining strong symbols for all of
> the interrupt handlers, but that would eat up a bunch of flash space
> for interrupts I don't use. What I would like instead is to use the
> default handler for all interrupts, *unless* someone called
> register_isr{1,2}_cb(), at which point it would switch to the strong
> ISR_Handler() symbol for just that interrupt.
Have you tried using symbol aliases and archives ? Eg something like:
% cat isr1.c
void register_isr1_cb (void (*cb)(void)) { ... }
void (*isr1_handler)(void) __attribute__((alias ("ISR_Handler")));
% cat isr2.c
void register_isr2_cb (void (*cb)(void)) { ... }
void (*isr2_handler)(void) __attribute__((alias ("ISR_Handler")));
% gcc -c isr1.c isr2.c
% ar cr libisr.a isr1.o isr2.o
% cat foo.c
int global = 0'
void bar (void) { global = 1; }
void (main) { register_isr1_cb (bar); ... }
% gcc foo.c libisr.a
So that when register_isr1_cb() is pulled into the application from
libisr.a the (strong) definition of isr1_handler is also brought in.
This overrides the weak default definition of isr1_handler and results
in ISR_Handler being called directly. Since register_isr2_cb is not
called however the strong version of isr2_handler is not pulled out of
libisr.a and so the weak, default handler is used instead.
Cheers
Nick
More information about the Binutils
mailing list