Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

Float and double cause hardfault handler on STM32F417

Posted by ophelieadveez on April 26, 2017

Hi, I'm working on IAR. I'm using FreeRTOS v9.0.0 on a STM32F417 microcontroller. I encounter problems when I declare and use float variables and double variables. The following code causes an Hardfault Handler. ~~~ void vTestTask(void *pvParameters) { for(;;) { float test; test = (float)(0x22); vTaskDelay(2000U); } } ~~~ Some details: * I use heap 4. * MCU frequency 16MHz * Operating system used the systick * FPU is activated. * The heap is located in the RTOS_RESERVED region, which is located in the CCRAM (see the linker file above). * The hardfault doesn't occur when I write this code outside the task. * The hardfault occurs when vTaskDelay function ends, so it seems it's when the context task is restored.

Could you give me some hint please ? Please find abovemy FreeRTOSConfig.h file and the linker file.

Regards, Ophélie

Linker file: /###ICF### Section handled by ICF editor, don't touch! ****/ /-Editor annotation file-/ / IcfEditorFile="$TOOLKITDIR$configideIcfEditorcortexv10.xml" / /-Specials-*/ define symbol __ICFEDITintvecstart__ = 0x08000000; /-Memory Regions-/ define symbol __ICFEDITregionROMstart__ = 0x08000000; define symbol ICFEDITregionROM_end = 0x080DFFFF; define symbol ICFEDITregionRAM_start = 0x20000000; define symbol ICFEDITregionRAM_end = 0x2001FAFF; define symbol ICFEDITregionCCMRAM_start = 0x10000000; define symbol ICFEDITregionCCMRAM_end = 0x1000FFFF; /-Sizes-/ define symbol ICFEDITsizecstack = 0x500;
define symbol ICFEDITsizeheap = 0x00;
/**** End of ICF editor section. ###ICF###*/

define memory mem with size = 4G; define region ROMregion = mem:[from __ICFEDITregionROMstart__ to ICFEDITregionROM_end]; define region RAMregion = mem:[from __ICFEDITregionRAMstart__ to ICFEDITregionRAM_end]; define region CCMRAMregion = mem:[from __ICFEDITregionCCMRAMstart__ to ICFEDITregionCCMRAM_end];

define block CSTACK with alignment = 8, size = ICFEDITsizecstack { }; define block HEAP with alignment = 8, size = ICFEDITsizeheap { };

initialize by copy { readwrite }; do not initialize { section .noinit };

place at address mem:ICFEDITintvecstart { readonly section .intvec };

place in ROMregion { readonly }; place in CCMRAMregion { readwrite data section RTOSRESERVEDRAM }; place in RAM_region { readwrite, block CSTACK, block HEAP};

FreeRTOSCongig.h: ~~~

ifdef ICCARM
include "system_stm32f4xx.h"

extern void assertfailed(uint8t* file, uint32_t line); /* Function prototype defined in errorUtils.h */

endif
define configUSE_PREEMPTION 1
define configUSEPORTOPTIMISEDTASKSELECTION 1
define configUSETICKLESSIDLE 1
define configEXPECTEDIDLETIMEBEFORESLEEP 5
define configCPUCLOCKHZ SystemCoreClock
define configTICKRATEHZ 100
ifdef NDEBUG

/* TODO : remove NDEBUG once we have real board : if we remove it we lost debug, but with right SWD connection it should work */

define configSYSTICKCLOCKHZ SystemCoreClock/8
endif
define configMAX_PRIORITIES 10
define configMINIMALSTACKSIZE 128
define configMAXTASKNAME_LEN 16
define configUSE16BIT_TICKS 0
define configIDLESHOULDYIELD 1
define configUSETASKNOTIFICATIONS 1
define configUSE_MUTEXES 1
define configUSERECURSIVEMUTEXES 0
define configUSECOUNTINGSEMAPHORES 1
define configUSEALTERNATIVEAPI 0 /* Deprecated! */
define configQUEUEREGISTRYSIZE 40
define configUSEQUEUESETS 1
define configUSETIMESLICING 0
define configUSENEWLIBREENTRANT 0
define configENABLEBACKWARDCOMPATIBILITY 1
define configNUMTHREADLOCALSTORAGEPOINTERS 5
define configUSEAPPLICATIONTASK_TAG 0

/* Memory allocation related definitions. */

define configSUPPORTSTATICALLOCATION 0
define configSUPPORTDYNAMICALLOCATION 1
define configTOTALHEAPSIZE (17 * 1024)
define configAPPLICATIONALLOCATEDHEAP 1

/* Hook function related definitions. */

define configUSEIDLEHOOK 0
define configUSETICKHOOK 0
ifndef NDEBUG
define configCHECKFORSTACK_OVERFLOW 2
else
define configCHECKFORSTACK_OVERFLOW 0
endif
define configUSEMALLOCFAILED_HOOK 0
define configUSEDAEMONTASKSTARTUPHOOK 0

/* Run time and task stats gathering related definitions. */

define configGENERATERUNTIME_STATS 0
define configUSETRACEFACILITY 0
define configUSESTATSFORMATTING_FUNCTIONS 0

/* Co-routine related definitions. */

define configUSECOROUTINES 0
define configMAXCOROUTINE_PRIORITIES 2

/* Software timer related definitions. */

define configUSE_TIMERS 1
define configTIMERTASKPRIORITY 5
define configTIMERQUEUELENGTH 5
define configTIMERTASKSTACKDEPTH configMINIMALSTACK_SIZE

/* The lowest interrupt priority that can be used in a call to a "set priority" function. */

define configLIBRARYLOWESTINTERRUPT_PRIORITY 15

/* The highest interrupt priority that can be used by any interrupt service routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER PRIORITY THAN THIS! (higher priorities are lower numeric values. */

define configLIBRARYMAXSYSCALLINTERRUPTPRIORITY 5

/* Interrupt nesting behaviour configuration. / / Cortex-M specific definitions. */

ifdef _NVICPRIO_BITS

/* _NVICPRIO_BITS will be specified when CMSIS is being used. */

define configPRIOBITS __NVICPRIO_BITS
else
define configPRIOBITS 4 /* 15 priority levels - __NVICPRIO_BITS value is 4 */
endif
define configKERNELINTERRUPTPRIORITY ( configLIBRARYLOWESTINTERRUPTPRIORITY << (8 - configPRIOBITS) )
define configMAXSYSCALLINTERRUPTPRIORITY ( configLIBRARYMAXSYSCALLINTERRUPTPRIORITY << (8 - configPRIOBITS) )

/* Define to trap errors during development. */

define configASSERT( x ) if( ( x ) == 0 ) { assert_failed(FILE, LINE); }

/* Optional functions - most linkers will remove unused functions anyway. */

define INCLUDE_vTaskPrioritySet 1
define INCLUDE_uxTaskPriorityGet 1
define INCLUDE_vTaskDelete 1
define INCLUDE_vTaskSuspend 1
define INCLUDE_xResumeFromISR 1
define INCLUDE_vTaskDelayUntil 1
define INCLUDE_vTaskDelay 1
define INCLUDE_xTaskGetSchedulerState 1
define INCLUDE_xTaskGetCurrentTaskHandle 1
define INCLUDE_uxTaskGetStackHighWaterMark 0
define INCLUDE_xTaskGetIdleTaskHandle 0
define INCLUDE_eTaskGetState 0
define INCLUDE_xEventGroupSetBitFromISR 1
define INCLUDE_xTimerPendFunctionCall 0
define INCLUDE_xTaskAbortDelay 0
define INCLUDE_xTaskGetHandle 0
define INCLUDE_xTaskResumeFromISR 1

~~~


Float and double cause hardfault handler on STM32F417

Posted by rtel on April 26, 2017

Thanks for providing so much detail. In this case there are two things that will effect how floating point variables are handled, first is the port are using and second is the compiler's command line (where the MCU to build for and the floating point unit the MCU has must be specified). Can you please ensure you are using the code from the FreeRTOS/Source/portable/[compiler]/ARMCM4F directory and not the ARMCM3 directory, and also show the command line you are using.


Float and double cause hardfault handler on STM32F417

Posted by ophelieadveez on April 26, 2017

We are using the code from the ARM_CM4F directory. We work on IAR so we don't use command line. We set VFPv4 (FPU) on the project settings. Floating point variables were working with the FreeRTOS version 8.3.2.


Float and double cause hardfault handler on STM32F417

Posted by rtel on April 26, 2017

Put a break point on the first line of the function that implements the task - before anything has been pushed onto the stack - normally putting a break point on the opening bracket '{' does the trick (you can view the asm code when the break point has been it to ensure the stack has not been modified) - then let me know the value of the stack pointer.


Float and double cause hardfault handler on STM32F417

Posted by ophelieadveez on April 27, 2017

Please find attached a view from IAR. My task is LoRaManagerTask and you can see the start of stack and the top of stack. Is the stack of a task filled from the top to the start ? I realize these addresses were 4 bytes aligned. It might be a problem in my case.

Attachments

Capture.PNG (6016 bytes)

Float and double cause hardfault handler on STM32F417

Posted by ophelieadveez on May 2, 2017

Any news ?


Float and double cause hardfault handler on STM32F417

Posted by rtel on May 2, 2017

Sorry - didn't realise you had posted again.

Unfortunately the screen shot does not provide the information required as it shows the top of the stack at the time the screen shot was taken. I need to see the stack pointer when it enters the task function, before the stack pointer has been moved to accomodate any stack used by the task itself.


Float and double cause hardfault handler on STM32F417

Posted by ophelieadveez on May 4, 2017

Which variable should I study to get the stack pointer value ?


Float and double cause hardfault handler on STM32F417

Posted by rtel on May 4, 2017

You need to view the stack pointer register in the debugger.

Put a break point on the opening bracket of a task function, as below:

void MyTask( void *pvParameters ) { // << Put the break point here int32_t MyVariable;

When the break point is hit open the registers view in IAR and tell me the value of R13.


Float and double cause hardfault handler on STM32F417

Posted by ophelieadveez on May 5, 2017

The value of R13 is 0x20000EB8.


Float and double cause hardfault handler on STM32F417

Posted by rtel on May 5, 2017

That value is as it should be, divisible by 8, so I'm afraid I don't know why the floats are not working, but it doesn't seem to be related to the code executing in a task.


Float and double cause hardfault handler on STM32F417

Posted by maxicor88 on May 9, 2017

Hello, I am Maximiliano, I am having the same issue as Tlemsani Ophélie. Is any news on this. I checked the stack pointer an is divisible by 8.

My project is based on stm32f334, also a cortexm4


Float and double cause hardfault handler on STM32F417

Posted by maxicor88 on May 9, 2017

Well, I think I got my problem, I double checked if my compiler was understanding I wanted to use the fpu unit, and found out it was one flag missing, in my case was "-mfpu=fpv4-sp-d16"

I hope it also solves your project.

Regards


Float and double cause hardfault handler on STM32F417

Posted by ophelieadveez on May 9, 2017

Hello Maximiliano. I have already activated VFPv4 on my IAR project. I have attached a view of IAR. Is it the same as the flag you are talking about ?

Attachments

Capture.PNG (26923 bytes)

Float and double cause hardfault handler on STM32F417

Posted by ophelieadveez on May 10, 2017

And where did you add the missing flag ?


Float and double cause hardfault handler on STM32F417

Posted by ophelieadveez on May 10, 2017

I added the flag but I still have the problem. I have tried on another IAR project. The error is the same. I have tried the same code on the last IAR version (32Kbyte Kickstart, ARM 8.11.1) with the last version of the compiler but I still have an hardfault handler. Do you have a workspace example on IAR working on a Cortex M4?


Float and double cause hardfault handler on STM32F417

Posted by rtel on May 10, 2017

Are you actually enabling the floating point unit? The first post in this thread said is FPU was active, but it is worth double checking. I have used the floating point unit extensively in all our testing and the only problem I have ever had was when sprintf()'ing a floating point value when the stack was misaligned (4-byte instead of 8-byte).


Float and double cause hardfault handler on STM32F417

Posted by ophelieadveez on May 10, 2017

Yes I have enabled the floating point unit. We have used FreeRTOS for 4 years. Floating point unit were working on FreeRTOS version 8.2.0 and when we decided to use FreeRTOS version 9.0.0 we had this problem. Do you have a workspace example on IAR working on a Cortex M4? I can also send you my IAR worspace.


Float and double cause hardfault handler on STM32F417

Posted by rtel on May 10, 2017

Probably the closest for you as its using an ST part, albeit an M7, is in the following directory (same as the M4F port barring a silicon bug fix unrelated to the FPU): FreeRTOS/Demo/CORTEXM7STM32F7STM32756G-EVALIAR_Keil

There are non ST IAR M4F projects in the following directories:

FreeRTOS/demo/CORTEXM4FInfineonXMC4000IAR FreeRTOS/demo/CORTEXM4FMSP432LaunchPadIARCCSKeil

and probably others.

All of these test the floating point unit.


Float and double cause hardfault handler on STM32F417

Posted by ophelieadveez on May 11, 2017

Hi,

I found the root cause but I don't really get it. The problem is linked with the xPortPendSVHandler. If I specify in startupstm32f417xx.s that I want to use xPortPendSVHandler instead of PendSVHandler, everything works correclty. But if I want to use instead PendSVHandler and call xPortPendSVHandler inside the handler (that's what I was doing) the programm crashes. I found there http://www.freertos.org/FreeRTOSSupportForumArchive/February2012/freertosSTM32F2hardfault5015439.html that we can't do that way for PendSVHandler, but can you explain why ? I was using this method because I want to have special treatment in SysTickHandler (in addition with calling xPortSysTickHandler) so to have an unified way to handle things I did it for the 3 handlers (SysTickHandler, PendSVHandler and SVCHandler).

Thanks,


Float and double cause hardfault handler on STM32F417

Posted by rtel on May 11, 2017

It would have been really helpful if you had said that to start with. If vPortPendSVHandler() was not the first thing to execute on interrupt entry then I'm surprised it worked at all as that is the function that performs the switch from one task to another - that means it must save a task's context exactly as it was when the interrupt was entered, and performing any processing in between entering the interrupt and saving the context that changes the context will be problematic when the task next runs.


Float and double cause hardfault handler on STM32F417

Posted by ophelieadveez on May 11, 2017

I didn't know it was the root cause. Otherwise, I would have noticed you. Please find below my code for the interrupt. Why is it not working? ~~~ void PendSV_Handler(void) { xPortPendSVHandler(); } ~~~


Float and double cause hardfault handler on STM32F417

Posted by rtel on May 11, 2017

xPortPendSVHandler() saves the context of the task that was interrupted - the context being (in part) the values held in CPU registers. Entering PendSV_Handler() will change the register values before xPortPendSVHandler() is executed, with the possibility that the register values saved within xPortPendSVHandler() are already corrupt.


Float and double cause hardfault handler on STM32F417

Posted by ophelieadveez on May 11, 2017

Thanks for the answer. But, why is it working without floating point ?


Float and double cause hardfault handler on STM32F417

Posted by rtel on May 11, 2017

When you use floating point instructions a bit gets set in one of the control registers, which in turn changes the stack frame when you enter interrupts. I would have to study the code output by the compiler to see exactly why you were getting the symptoms you were, but it is likely you actually have a problem in all cases but were only noticing when the stack frame was different and/or when floating point registers corruptions were causing faults.


Float and double cause hardfault handler on STM32F417

Posted by ophelieadveez on May 12, 2017

Ok, thanks for your response. I fixed my problem.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS