Correct typing of Thumb functions
The SEGGER Linker strictly enforces correct typing of Thumb and Arm symbols for functions. When writing assembly language files, it is important that each function is correctly typed to inform the linker of the instruction set the function is intended to run in.
It happens that it is easy to forget to "type" the symbol. The following is an untyped symbol:
.thumb .globl Increment Increment: add r0, r0, #1 bx lr
This function increments its argument and returns. It is written to execute in the Thumb instruction set. When linking this function into a Cortex-M4 application, the SEGGER Linker complains that the function is incorrectly typed:
error: relocation R_ARM_THM_CALL to Arm-mode function not supported on this core, from .text.main+20 (main.o) to Increment (AsmFuncs.o)
This is indeed a problem. The GNU assembler requires that the function be declared as a "Thumb function" even though the Thumb instruction set is selected in the assembler. For that, you must use the .thumb_func directive:
.thumb .thumb_func .globl Increment Increment: add r0, r0, #1 bx lr
The .thumb_func directive tells the assembler that the following label is a Thumb-mode label. And once that information is provided to the linker, the error is eliminated.
Note that correct placement of the .thumb_func directive is essential. The following example, the .thumb_func directive follows the label and does not set the type of that label:
.thumb .globl Increment Increment: .thumb_func add r0, r0, #1 bx lr