Home > Software engineering >  ARM GCC Cortex M4: Calling address as function generates BLX instead of BL
ARM GCC Cortex M4: Calling address as function generates BLX instead of BL

Time:01-31

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))

CodePudding user response:

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.

  • Related