Is there a way to check in the produced binary, whether my function was linked in correctly and will be called instead of the __default_handler?
(I assume you're not using a JTAG or SWD debugger)
One way is to check the vector table in the disassembly file (in build/<your_board>.disas using libmaple from Git). In libmaple, the vector table symbol is __stm32_vector_table
; it should be the first symbol in the text section (and hence will be at the top of the file). Look up the ADC handler address in the vector table, and make sure it's the address of __irq_adc
(which you can also look up in the disassembly).
Here's a worked example.
This is the vector table from a disassembled program with __irq_adc() defined:
08000000 <__stm32_vector_table>:
8000000: 00 50 00 20 1d 23 00 08 71 08 00 08 75 08 00 08 .P. .#..q...u...
8000010: 79 08 00 08 7d 08 00 08 81 08 00 08 d7 1a 00 08 y...}...........
8000020: d7 1a 00 08 d7 1a 00 08 d7 1a 00 08 d7 1a 00 08 ................
8000030: d7 1a 00 08 d7 1a 00 08 d7 1a 00 08 09 04 00 08 ................
8000040: d7 1a 00 08 d7 1a 00 08 d7 1a 00 08 d7 1a 00 08 ................
8000050: d7 1a 00 08 d7 1a 00 08 8d 01 00 08 ad 01 00 08 ................
8000060: cd 01 00 08 ed 01 00 08 0d 02 00 08 59 1d 00 08 ............Y...
8000070: 79 1d 00 08 99 1d 00 08 b9 1d 00 08 d9 1d 00 08 y...............
8000080: f9 1d 00 08 19 1e 00 08 1d 01 00 08 d7 1a 00 08 ................
8000090: 29 0a 00 08 d7 1a 00 08 d7 1a 00 08 2d 02 00 08 )...........-...
80000a0: c5 1f 00 08 f1 1f 00 08 1d 20 00 08 59 20 00 08 ......... ..Y ..
80000b0: b5 20 00 08 31 21 00 08 ad 21 00 08 cd 1e 00 08 . ..1!...!......
80000c0: e5 1e 00 08 d9 1e 00 08 f1 1e 00 08 d7 1a 00 08 ................
80000d0: d7 1a 00 08 e1 22 00 08 f5 22 00 08 09 23 00 08 ....."..."...#..
80000e0: 65 02 00 08 d7 1a 00 08 d7 1a 00 08 e...........
This contains:
1. The initial stack pointer,
2. The addresses of the interrupt handlers, in the order specified by Table 63 in RM0008. (Starting with the reset vector, then NMI, etc.)
Each entry is 4 bytes long. The byte-order is little-endian. The first entry in the above example (the initial stack pointer value) is thus 0x20005000, and the reset vector is at address 0x0800231d. Note that the last bit in the reset vector address is set. This is the "thumb bit"; it's an ARM feature meaning that the address to be branched to contains thumb-2 (mixed 16- and 32-bit) instructions instead of 32-bit only (this is fine since instructions want 2 or 4 byte alignment). The actual address of the reset vector is thus 0x0800231c.
__irq_adc() is at offset 0x88 from the start of __stm32_vector_table, so in this example, the corresponding value is 0x0800011d. Masking out the thumb bit, the ADC handler address is 0x0800011c. And sure enough, when I search the disassembly file for "__irq_adc", this turns up:
0800011c <__irq_adc>:
800011c: 4770 bx lr
(My handler is a trivial one that returns immediately, so it just contains a standard "return to caller" bx lr
instruction).