FreeRTOS + TCP and FPU on STM32F407ZE

Using FreeRTOS v10.2.1 and FreeRTOS+TCP v2.0.11 grafted onto an STM32CubeIDE Project Using STM32F407ZE OK I’m probably doing something stupid, but I had firmware that was working fine until I put some floating point math in it. quick rundown, I have this board, it has an Ethernet port it and uses ADC1 to read an analog pressure sensor. I’m converting the ADC counts to a KPA value to send back to the computer. its a simple ADCCOUNT / COUNTSPER_KPA. the ethernet listens on a port using FreeRTOS+TCP receives a command to do something, processes command then returns the result. one of my commands is get pressure, where I do the ADC->kPa conversion and send it back. this works fine, until the client disconnects then the firmware gets locked at: configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); in heap_4.c line 278 stack is: vPortFree() at heap_4.c prvDeleteTCB() at tasks.c prvCheckTasksWaitingTermination() at tasks.c prvIdleTask() at tasks.c pxPortInitiaseStack at port.c –end– upon removing any calls to floating point math, the code runs without problems, and dumps the task accordingly. I was unable to recreate the problem on a new project with no TCP/IP so it may be related to that (FreeRTOS+TCP)? Thanks for any input I get on this. below is crapy pseudocode that is similar to what im doing Pseudo code: ~~~

define COUNTSPERKPA 0.00811f

float adcTokPa(uint16t advvalue) { return ((float)adcvalue)/COUNTSPER_KPA; } void sendresponse(Sockett client,float value) {
        FreeRTOS_Send(client,&value,sizeof(float),0);
} void connectionhandler(void *params) { Sockett *client_ptr = (Socket_t * )params; Socket_t client = *client_ptr; uint16_t cmd;
   for(;;) {
           bytesRecv = FreeRTOS_recv(client,&cmd,sizeof(uint16_t),0);
           if(bytesRecv != sizeof(uint16_t)) {
                  if( bytesRecv < 0 ) {
                          //Some kind of Socket Error
                          //shutdown FreeRTOS Socket
                              vTaskDelete(NULL); //Should delete this connection handler
                  }
           } else {
             switch(cmd) {
                     //
                     case 42:
                             send_response(client,adcTokPa(adv_value));
                             break;
                      default:
                              break;
             }
           }


   }
} void listentask(void * params) { for(;;) { Sockett client = FreeRTOSAccept(); xCreateTask(connectionhandler,”ConHandle”,128,&client,CONTASKPRIO,NULL); } } ~~~ }

FreeRTOS + TCP and FPU on STM32F407ZE

Does your part have an flu? If so you need to be using the FreeRTOS/source/portable/arm_cm4f port and tell the compiler which cpu model is available on the chip. That will enable the fpu, which must be done before use. Not sure if that helps. Do the floating point instructors work from main() before the scheduler starts?

FreeRTOS + TCP and FPU on STM32F407ZE

FPU, not flu! Auto correct on my cellphone.

FreeRTOS + TCP and FPU on STM32F407ZE

The part you mentioned (i.e. STM32F407ZE) does have an FPU (Floating Point Unit) and therefore you need to make sure that you are using CM4F port. Thanks.

FreeRTOS + TCP and FPU on STM32F407ZE

but the fpu works fine. its when a client disconnects from the socket that it gets stuck in heap_4 everything works fine, until you try and disconnect.if i take the floating point math out. disconnects work fine. I will double check on monday that the floating point math is correct. as in the math actually works out. sorry if im not being clear on this, it doesn’t seem to be a straightforward problem. I was just really wondering if in FreeRTOS there is some connection between deleting a task and the FPU or deleting a task that has a socket that also used the FPU. it doesn’t make any sense. but if I remove all floating point math, I can delete the task successfully and it doesn’t hang.

FreeRTOS + TCP and FPU on STM32F407ZE

FreeRTOS must save/restore also FPU registers when switching task context if application is built with (hard) FPU support enabled. Even if no floating point math is directly used, nowadays compilers make use of FPU registers for various purposes if allowed/enabled. So you must use the matching CM4F Port.

FreeRTOS + TCP and FPU on STM32F407ZE

both port.c and portmacro.h come from the CM4F port, Its possible I missed something else? everything works fine until it goes to delete the task that uses the FPU registers. then it hangs at : ~~~ configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); in heap_4.c line 278 ~~~ I’m working on stripping out all code, and just leaving the code that causes the issue so I can post it.

FreeRTOS + TCP and FPU on STM32F407ZE

ok, added project to github This project uses CubeIDE 1.0 https://github.com/bghost4/FPUFAIL the code hits a configASSERT after a disconnect deletes the connection_handler task

FreeRTOS + TCP and FPU on STM32F407ZE

When floating point math is used, we store FPU registers on the task’s stack during context switch. This means that more stack space is used as compared to the case when FPU is not used. I see that you have 128 words stack size for all the tasks which may not be enough and result in memory corruption because of stack overflow. Would you please try increasing the stack size for the tasks which use floating point math? Please also set configCHECKFORSTACK_OVERFLOW in your FreeRTOSConfig.h to catch stack overflows: www.freertos.org/Stacks-and-stack-overflow-checking.html Which hardware are you using? Is it a development board or is it your custom hardware? Thanks.

FreeRTOS + TCP and FPU on STM32F407ZE

it is custom hardware. I do have a f407 discovery board with the add on header I could try and port the code to. at first glance it seems to have worked.

FreeRTOS + TCP and FPU on STM32F407ZE

Indeed thats what it was, Thanks for the help.

FreeRTOS + TCP and FPU on STM32F407ZE

I am glad that it worked for you. Just FYI, you can use uxTaskGetStackHighWaterMark to find the minimum stack required for each task: http://www.freertos.org/uxTaskGetStackHighWaterMark.html Thanks.