I build as little OS for a CortexM4 CPU which is able to receive compiled binaries over UART and schedule them dynamically. I want to use that feature to craft a testsuite which uploads test programs being able to directly call OS functions like memory allocation without doing a SVC. Therefor I need to cast the fixed addresses of those OS routines to function pointers. Now, casting of memory addresses resulting in wrong / non-thumb instruction code - BL
is needed instead of BLX
, resulting in HardFaults.
void (*functionPtr_addr)(void);
functionPtr_addr = (void (*)()) (0x0800084C);
This is the assembly when calling this function
8000838: 4b03 ldr r3, [pc, #12] ; (8000848 <idle+0x14>)
800083a: 681b ldr r3, [r3, #0]
800083c: 4798 blx r3
Is there a way to force the BL instruction for such a case? It works with inline assembly, I could write macros but it would be much cleaner do it this way.
The code gets compiled and linked, among other things, with
-mcpu=cortex-m4 -mthumb
.
Toolchain:
gcc version 12.2.0 (Arm GNU Toolchain 12.2.MPACBTI-Bet1 (Build arm-12-mpacbti.16))
bl
instruction is limited in range. The compiler does not know where your code will be placed so it can't know if the instruction bl
can be used.
resulting in HardFaults.
The address passed to blx
has to be odd on Cortex-M4 uCs to execute the code in the Thumb mode. Your address is even and the uC tries to execute ARM code not supported by this core.