If you want to declare .weakreference for a set of interrupt vectors such as:
.weakreference ISR_SPI_HANDLER, defaultExceptionHandler
in a startup.S file or some framework include, it's very useful except that if you then declare ISR_SPI_HANDLER as a function in your main.c file, ISR_SPI_HANDLER in the startup.S still resolves to defaultExceptionHandler because .weakreference only works in local scope (terminology? pre-linking). However, .weak functions as it's expected, and allows you to "override" the definition with a definition in main.c, but if you don't, you'll always resolve to 0x00, which is inferior obviously to resolving to a default vector.
How can I overcome this?
Do not use the .weakref
in the assembler. Instead just use ISR_SPI_HANDLER
as an external. The assembler naturally wants to optimize to PC relative jumps to known locations. You are fighting this and someone else will want the call to defaultExceptionHandler
.
Instead use the linker,
.text : {
*(.text);
ISR_SPI_HANDLER = DEFINED(ISR_SPI_HANDLER) ? ISR_SPI_HANDLER : defaultExceptionHandler;
…
}
Alternatively, split startup.S with the .weak
, .set
and defaultExceptionHandler
declaration in one file and another that is using/calling ISR_SPI_HANDLER
.
However, .weak functions as it's expected, and allows you to "override" the definition with a definition in main.c, but if you don't, you'll always resolve to 0x00, which is inferior obviously to resolving to a default vector.
The typical case is define a function and use .weak
in the same file. Ie, you need to use .weak
where the routine is defined (but another object files may override this). To achieve this and keep defaultExceptionHandler
for other uses,
.weak ISR_SPI_HANDLER
.set ISR_SPI_HANDLER, defaultExceptionHandler
For ARM Thumb code, you may need .thumb_set
instead. I believe this is the effect you wanted.
Why .weakref
? I think that this is better suited to machine generated code such as a compiler would generate.