Cortex M4F, FPU, and ThreadX

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
user_108962310
Level 4
Level 4
10 likes received 10 likes given 5 likes given

Hi folks,

I would like to get the FPU working on the STM32F4xx chip that I am using, but I am stuck, and I believe the problem has to do with the version of ThreadX that is bundled with the SDK.

I found this old thread, but it seemed like there was no resolution: How to use HW FPU on STM32F4xx?

I have had partial success by adding a USE_FPU_CM4F flag to the build system, and then changing the chip-specific flags in wiced_toolchain_ARM_GNU.mk:

# Chip specific flags for GCC

ifeq ($(HOST_ARCH),ARM_CM4)

# flag added to support building for CM4 micros with FPU; define in platform makefile

ifeq ($(USE_FPU_CM4F),1)

__FPU_PRESENT := 1

__FPU_USED := 1

CPU_CFLAGS     := -mthumb -mcpu=cortex-m4 -mfloat-abi=softfp

CPU_CXXFLAGS   := -mthumb -mcpu=cortex-m4 -mfloat-abi=softfp

CPU_ASMFLAGS   := -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16

CPU_LDFLAGS    := -mthumb -mcpu=cortex-m4 -Wl,-A,thumb

else

CPU_CFLAGS     := -mthumb -mcpu=cortex-m4

CPU_CXXFLAGS   := -mthumb -mcpu=cortex-m4

CPU_ASMFLAGS   := -mcpu=cortex-m4 -mfpu=softvfp

CPU_LDFLAGS    := -mthumb -mcpu=cortex-m4 -Wl,-A,thumb

endif #USE_FPU_CM4F

endif #ARM_CM4

Then, in my platform makefile, I define USE_FPU_CM4F . The idea was that I wouldn't have to define a whole new CM4F variant in the build system, just tweak the CM4 one a little bit. Based on what I read about GCC flags, this should work, since soft-fp will still be link-compatible with existing libraries built without FPU support. And the choice of -mfpu was just from other STM32F4xx examples I found.

Then, in system_stm32f4xx.c,  at the top of SystemInit(), FPU access is enabled:

/* FPU settings ------------------------------------------------------------*/

#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)

    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */

#endif

So, then the compiler does indeed generate FPU instructions, and they even appear to run OK.


BUT: the system hits a hard fault after running for not very long.
Using ETM on the target, I am seeing a crash that appears to originate in tx_thread_create, when the PC is popped, it gets a bad address, spirals out of control, and eventually ends up at a hard fault. See attached screenshot. I could provide a longer trace history privately, if that would help.

I contacted ExpressLogic to get some insight into this, and they indicate that for FPU usage, there must be a call to void tx_thread_fpu_enable(void) to set up correct FPU context saves.
Unfortunately, looking at the tx_port.h file provided in the WICED SDK, it seems like there is a single file that covers both CM3 and CM4, and there's no mention of this function anywhere. Looking at the headers from the objdump of ThreadX.ARM , there's no mention of the tx_thread_fpu_enable() function anywhere.
And the ThreadX User Guide doesn't mention it, either.

So ... any chance that there is a solution for this?

It seems like it is going to take an upgrade to ThreadX. Or possibly a rebuild of the existing archive(s), with the FPU enables functions not being dropped.

1 Solution

We understand the point that you are mentioning. I will put forward an internal request to enable the FPU support in the next version (5.8) of  ThreadX library.

View solution in original post

10 Replies