This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Using linker directives to conditionally choose code


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]