I've been trying to figure out an issue I'm seeing and I'm scratching my head at this point.
My issue: 1. Interrupt handler (in a file that has just the interrupt handler) is not getting linked properly. the weak definition is getting used instead.
My setup: 1. Startup code where interrupt handler is getting defined (.s file) is made into a library (startup.a) This startup code has a weak definition of the interrupt vectors.
__Vectors ... DCD NVIC_IsrHandler0 ... Default_Handler PROC EXPORT NVIC_IsrHandler0 [WEAK] ... NVIC_IsrHandler0 B . ENDP ...
2. In another library (C++ code) I do the following (libIsrHandler.a)( interrupts.cpp)
extern "C" NVIC_IsrHandler0(void) { ... my isr code }
3. I link my code using --userlib libIsrHandler --userlib startup.a
4. The the output/map file I see that the weak definition is used instead.
5. Other parts of my code uses libStartup.a for other interrupt vectors
6. Within libIsrHandler, there are other C++ files that uses other ISR's which properly gets linked (since they have other functions other than interrupt handler that get referenced)
Questions/Observations: 1. How does Keil linker handle library order? I read how Keil scans libraries, but didn't find much information on how it handles ordering. In GNU it's left to right.
2. If two libraries have circular dependencies, how is this worked out by Keil? In GCC/GNU, you can list the library twice but in ARM KEIL I see warning "file input ignored... " on the second mention of library.
3. __irq keyword did not make a difference. What I'm confused about is that the ISR handlers that are in files with functions that get referenced will get linked properly. For example fileX.cpp has function Init and fileY.cpp calls Init and these files are within libIsrHandler.a, the ISR hanlders in those files will get linked properly.
4. It seems like files that has only the interrupt handler and no other functions(CPP), linker is ignoring them and picking the weak definition instead... this is odd even with __irq. infocenter.arm.com/.../BABICJBC.html mentiones ARMV7 doesn't care about __irq .
In ARMv6-M and ARMv7-M, specifying __irq does not affect the behavior of the compiled output. However, ARM recommends using __irq on exception handlers for clarity and easier software porting.
5. My understanding of how the linker works is it scans the first library, creates a symbol table, scans the next library and completes the symbol table based on the new symbols and fills any undef or weak if needed. I'm listing libIsrHandler first then startup.a . I have tried swapping the order but didn't make a difference.
Thanks.
Use objects not libraries