HardFault _Handler STM32F2 prvPortStartFirstTask

I am just calling vTaskStartScheduler() after creating my tasks and get Hard_Fault_Handler when caused by prvPortStartFirstTask


I am compiling my project with Eclipse STM32F2, FreeRTOS202212.01 lwip1.3.2

Does anybody hace an idea of why is this happening?

Do you change the priority of SVC? If yes, can you either not do so or ensure that it is highest priority? If not, can you step through the prvPortStartFirstTask and see which line is causing the fault?

Hello, Yes I have the priority changed . Those are my values defined in FreeRTOSConfig.h

 /* This is the raw value as per the Cortex-M3 NVIC.  Values can be 255
(lowest) to 0 (1?) (highest). */
#define configKERNEL_INTERRUPT_PRIORITY         255
#define configMAX_SYSCALL_INTERRUPT_PRIORITY    191 /* equivalent to 0xb0, or priority 11. */
#if FREERTOS_V100400
#define configMAX_API_CALL_INTERRUPT_PRIORITY	191 //Same as configMAX_SYSCALL_INTERRUPT_PRIORITY renamed
#endif
/* This is the value being used as per the ST library which permits 16
priority values, 0 to 15.  This must correspond to the
configKERNEL_INTERRUPT_PRIORITY setting.  Here 15 corresponds to the lowest
NVIC value of 255. */
#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY	15

/* Stack overflow checking */
//#define configCHECK_FOR_STACK_OVERFLOW          2 //99? comprobar
#define INCLUDE_uxTaskGetStackHighWaterMark     1

#if FREERTOS_V100400

/* FreeRTOS MPU specific definitions. */
#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
#define configTOTAL_MPU_REGIONS                                8 /* Default value. */
#define configTEX_S_C_B_FLASH                                  0x07UL /* Default value. */
#define configTEX_S_C_B_SRAM                                   0x07UL /* Default value. */
#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY            1

#endif

In my module main.c I have the following:

 /* Pass the array into vPortDefineHeapRegions(). */
  vPortDefineHeapRegions( xHeapRegions );

  /* Relocate Vector Table in the FW address 0x08060000 0x08040000, after BOOT area */
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, MAP_OFFSET); //0x60000 0x40000
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

When debugging I can see that the HardFault_handler occurs when executing prvPortStartFirstTask() a SVC_Handler() is executed and there my code call to vPortSVHandler() an occurrs de HardFault.

Previously I have the project working fine with FreeRTOS8.2.3 but the problems started when trying to upgrade…

Please tell me if I can provide more information to you to clarify what is happening.
Thansk a lot in advance!

Can you share your complete FreeRTOSConfig.h?

Do you mean to say that prvPortStartFirstTask executes svc instruction and as a result, the control should to SVC handler (which is vPortSVHandler) but instead it goes to Hard Fault handler?

Can you try setting the SVC priority to 0? Should be possible by doing something like the following:

 NVIC_SetPriority(SVCall_IRQn, 0);

I am sorry but I am not sure I am undertanding properly I have the follwoing configuration

const HeapRegion_t xHeapRegions =
{
{ ( uint8_t * ) 0x20002710UL, 0x1CCF0 }, // 118K
{ ( uint8_t * ) 0x68000000UL+XRAM_OFFSET, 0x1C000 }, // 112K
{ NULL, 0 } /* Terminates the array. */
};

// Pass the array into vPortDefineHeapRegions().
vPortDefineHeapRegions( xHeapRegions );

/* Relocate Vector Table in the FW address 0x08060000 0x08040000, after BOOT area */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, MAP_OFFSET); //0x60000 0x40000
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

I am afraid that I can not share the file but I will try to paste the code here
I have removed the comments to minimize the size…
There are some sentences
#if FREERTOS_V100400
#if FREERTOS_2022
are both symbols defined for the entire project that I created to be able to compile my project with different versions of FreeRTOS

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

#define configUSE_PREEMPTION 1
#if FREERTOS_V100400

#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configUSE_TICKLESS_IDLE 0
//#define configSYSTICK_CLOCK_HZ not needed //para micro ARM M3 no me hace falta
//#define configIDLE_SHOULD_YIELD 1 //de momento no utilizo
#define configUSE_TASK_NOTIFICATIONS 0 //can send receive task array notifications. New functionality not used yet

#define configTASK_NOTIFICATION_ARRAY_ENTRIES 1 //for backward compatibility
#define configUSE_RECURSIVE_MUTEXES 1

#define configQUEUE_REGISTRY_SIZE 0 //set 1 for debuggin queues adding names to queues…
#define configUSE_QUEUE_SETS 1 //for block/pend multiple queues and semphores
#define configUSE_TIME_SLICING 0 //Task scheduler executes highest priority task bat not switch between task of equal priority
#define configUSE_NEWLIB_REENTRANT 0 //set to 1 if requiered. OJO Newlib is included in FreeRTOS but is not used by the FreeRTOS maintainers themselves

#define configENABLE_BACKWARD_COMPATIBILITY 1 //redefine vbles y funciones q se han cambiado de normbresi no compila poner a 1 es para declarar los defines para q sea compatible con ver pre 8.0.0

#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0 //new funtionality not used. Can be used to keep data in a task
#if FREERTOS_2022

#define configUSE_MINI_LIST_ITEM 1
#endif

#define configSTACK_DEPTH_TYPE uint16_t //no need to use it.Can be used to define stack size when create a task

#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
#endif
#if FREERTOS_2022
#define configHEAP_CLEAR_MEMORY_ON_FREE 1
#define configSTATS_BUFFER_MAX_LENGTH 0xFFFF

#define configUSE_NEWLIB_REENTRANT 0

#endif
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0

#define configCPU_CLOCK_HZ 120000000
#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
#define configMAX_PRIORITIES 7
#define configMINIMAL_STACK_SIZE 256
//#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 119 * 1024 ) )
#define configMAX_TASK_NAME_LEN 16
#if FREERTOS_2022
#define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_64_BITS
#endif

#define configUSE_TRACE_FACILITY 1
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1

#define HEAP_MINIMUM_SIZE 0x500

#define configUSE_MALLOC_FAILED_HOOK 0
//#if FREERTOS_V100400
#if FREERTOS_2022
#define configSUPPORT_STATIC_ALLOCATION 0
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configAPPLICATION_ALLOCATED_HEAP 0 //if used
//#define configTOTAL_HEAP_SIZE 10240 not need for use of heap_5.c
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 //Natalia estaba a 0 pero puede venir bien No poner a 1 no compila
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configUSE_MALLOC_FAILED_HOOK 0
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
#define configUSE_SB_COMPLETED_CALLBACK 0
#define configCHECK_FOR_STACK_OVERFLOW 2

#define configGENERATE_RUN_TIME_STATS 0

#endif

#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES 0
#if FREERTOS_2022

#define configASSERT( x )
if( ( x ) == 0 )
{
taskDISABLE_INTERRUPTS();
for( ; ; )
;
}
#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0

#define configTOTAL_MPU_REGIONS 8

#define configTEX_S_C_B_FLASH 0x07UL

#define configTEX_S_C_B_SRAM 0x07UL

#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 1

#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 0

#define configUSE_MPU_WRAPPERS_V1 0

#define configPROTECTED_KERNEL_OBJECT_POOL_SIZE 10

#define configSYSTEM_CALL_STACK_SIZE 128

#define configENABLE_ACCESS_CONTROL_LIST 1

#define configRUN_MULTIPLE_PRIORITIES 0
#define configUSE_CORE_AFFINITY 0

#define configTASK_DEFAULT_CORE_AFFINITY tskNO_AFFINITY

#define configUSE_TASK_PREEMPTION_DISABLE 0

#define configUSE_PASSIVE_IDLE_HOOK 0

#define configTIMER_SERVICE_TASK_CORE_AFFINITY tskNO_AFFINITY

#define secureconfigMAX_SECURE_CONTEXTS 5

#define configKERNEL_PROVIDED_STATIC_MEMORY 1
#endif

//#if FREERTOS_V100400
#if FREERTOS_2022
#define configUSE_TIMERS 1 //1
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-1) //0 //3
#define configTIMER_QUEUE_LENGTH 10 //0//10
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE //0
#endif

#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1

#if FREERTOS_V100400
#define INCLUDE_xResumeFromISR 0
#define INCLUDE_xTaskGetSchedulerState 0
#define INCLUDE_xTaskGetCurrentTaskHandle 0
//#define INCLUDE_uxTaskGetStackHighWaterMark 0
#define INCLUDE_xTaskGetIdleTaskHandle 0
#define INCLUDE_eTaskGetState 0
#define INCLUDE_xEventGroupSetBitFromISR 0
#define INCLUDE_xTimerPendFunctionCall 0
#define INCLUDE_xTaskAbortDelay 0
#define INCLUDE_xTaskGetHandle 0
#define INCLUDE_xTaskResumeFromISR 0
#endif
#define configKERNEL_INTERRUPT_PRIORITY 255
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 /* equivalent to 0xb0, or priority 11. */
#if FREERTOS_V100400
#define configMAX_API_CALL_INTERRUPT_PRIORITY 191 //Same as configMAX_SYSCALL_INTERRUPT_PRIORITY renamed
#endif
#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15

/* Stack overflow checking */
//#define configCHECK_FOR_STACK_OVERFLOW 2 //99? comprobar
#define INCLUDE_uxTaskGetStackHighWaterMark 1

#if FREERTOS_V100400

/* FreeRTOS MPU specific definitions. /
#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
#define configTOTAL_MPU_REGIONS 8 /
Default value. /
#define configTEX_S_C_B_FLASH 0x07UL /
Default value. /
#define configTEX_S_C_B_SRAM 0x07UL /
Default value. */
#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 1

#endif

#endif

Thanks in advance.
I don’t know if is relevant or not but just to let you know I am compiling the project with Eclipse/arm-none-eabi-gcc and I am using WolfSSL and LWIP1.3.2

I am happy to inform that I am just allowed to add files. So please find attached FreeRTOSConfig.h- There you can fing FreeRTOS_2022 and FREERTOS_V100400 that are symbols globally defined for my whole project
Please find attached as well port.c and portmacro.h files to integrate FreeRTOS with my ARM M3 micro: STM32F2 and project compiled with Eclipse arm-none-eabi-gcc
port.c (35.5 KB)
portmacro.h (9.9 KB)
FreeRTOSConfig.h (30.5 KB)

Some of files of my project that may be relevant
main.c /HWConf.c
I would like to add that I am using LWIP and WolfSSL in my project as well
main.c (22.4 KB)

HWConf.c (76.9 KB)
Anymore information that could be useful please don’t doubt to ask.
Thanks a million

Thanks for sharing these files. Nothing looks off at a first glance. Can you try the following:

  1. Try executing SVC after relocating the vector table in main.c:
      /*Initialize Hardware System */
      InitializeSystem(ENABLE);
      __asm volatile( "svc 0" );
    
    Step through the assembly and see if the control reaches vPortSVCHandler.
  2. If the control reaches vPortSVCHandler in the first step and you do not see Hard Fault, remove the svc instruction and add it before starting the scheduler in main.c:
    __asm volatile( "svc 0" );
    /* Start the scheduler */
    vTaskStartScheduler();
    
    Step through the assembly and see if the control reaches vPortSVCHandler.
  3. Remove the svc instruction.
  4. Add the following code before starting the scheduler in main.c:
    NVIC_SetPriority(SVCall_IRQn, 0);
    /* Start the scheduler */
    vTaskStartScheduler();
    
    See if you still get Hard Fault.

Hello, thanks for your help

The first and the second try worked fine adding __asm volatile(“svc 0”); but the last one I am sorry to tell you that I still get Hard Fault… When debuggin the SVCall_IRQn has got the value -5

It seems to get Hard_Fault and continue but it is not true has I see that the task are not really started… I add here a capture of what I can see may help you know what could be happening…

Thanks a lot. I continue trying

I have tried to write NVIC_SetPriority(SVCall_IRQn, configMAX_PRIORITIES); or NVIC_SetPriority(SVCall_IRQn, 0); before calling vTaskStartScheduler() but it is not working. I am still getting Hard_Fault…
Have you got any idea of why this could be happening? Could I give you more information about my project to help you know what I am doing wrong? I am a little bit lost

Thansk in advance

I would recommend reducing your application to blinky, ie deactivate everything related to Networking, peripheral etc, then make sure you get a single dummy task to work, then build up your sytem until you get the error. My suspicion is that one of your isrs faults as soon as interrupts are enabled.

Also, you can inspect the fault stack frame by dumping the memory r13 points to at fault handler entry. That gives you a little more info what happened.

Hello, I am trying to do what you are saying. I have created a small project with minimum initialized removing ethernet… and using FreeRTOS10.4.0 instead of FreeRTOS202212.0.01 but I having the same Hard_Fault.

Does anybody knows it could be the compiling options?

When you are at the entry of the hard fault handler, dump your registers and dump the memory r13 points to. It contains the fault stack frame, among other things the address where it faulted. You can look up that address in your symbol table to determine the symptomatic fault cause.

You can look here fo reference: How to debug a HardFault on an ARM Cortex-M MCU | Interrupt (memfault.com)

This page also describes how to dump register in fault handler - Debugging and diagnosing hard faults on ARM Cortex-M CPUs.

Hello, I have been looking at the pages you suggested trying to solve the problem, but I am stuck…
I am thinking that the problem may be due to the heap configuration, could be?
I wouls like to share with you the way I have it configurated is you could please have a look?
EditorIP_WolfSSL_Eclipse.7z (156.9 KB)
HW_UES_ENCODER_FP1.7z (17.4 KB)

is that the minimum code you reduced your system to to repro the problem, or again the full blown suite? If you want us to find the needle in your hay stack, make sure to make your hay stack as small as possible.

What exactly happened that made you discard the stack frame analysis?

I have shared the full project because I have created a reduced project with the minimun and it is not working but it is worst because I can not debug… that’s why I am sharing the whole one

OK. I am going to reduce and share a reduce version, without the ethernet part

1 Like

After all your changes to upgrade FreeRTOS, can you still build this codebase for kernel v8.2.3? And if so, does the application still work properly?

Just before executing SVC 0, function prvPortStartFirstTask() attempts to reset the main stack pointer MSP from the vector table. However, your application seems to be using a different vector table from the one the processor boots from. Does this application-specific vector table have a suitable value for MSP at offset 0 in the table?

Hi jefft,

Thanks for you help.

  1. I have gone back to FreeRTOS v8.2.3 and it happens to me the same.

    I have tried to compile the old project without changes using FreeRTOS v8.2.3 and have the
    same problem

I changed my PC a month ago and I tried to put the same Eclipse Compiler,using arm-none-
eabi-gcc compiler… but I am afraid that I have something wrong in my compiler.

When trying to compile for release: I am able to compile the problem but for being able to obtain the hex file “I have had to remove two keywords from the make file “-map” and “-info” and maybe there are important. but otherwise I get some problem”.

And if i try to compile for debug I see that the scheduller doesn’t start properly.
unfortunately I am not able to recover my last configuration, as I haven’t got my old PC anymore…

  1. Refering to what you are talking about MSP

I have the following code at my main.c
/* Allocate two blocks of RAM for use by the heap. The first is a block of
0x10000 bytes starting from address 0x80000000, and the second a block of
0xa0000 bytes starting from address 0x90000000. The block starting at
0x80000000 has the lower start address so appears in the array fist. /
const HeapRegion_t xHeapRegions[] =
{
{ ( uint8_t * ) 0x20002710UL, 0x1CCF0 }, // 118K
{ ( uint8_t * ) 0x68000000UL+XRAM_OFFSET, 0x1C000 }, // 112K
{ NULL, 0 } /
Terminates the array. */
};

/* Pass the array into vPortDefineHeapRegions(). */
vPortDefineHeapRegions( xHeapRegions );

/* Relocate Vector Table in the FW address 0x08060000 0x08040000, after BOOT area */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, MAP_OFFSET); //0x60000 0x40000
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

where I hope I tell the Compiler where is place my vector table:
NVIC_VectTab_FLASH 0x08000000
MAP_OFFSET 0x00060000

so I think that should be right?

I am including here my compiler configuration …just in case you could find something wrong…
HW_UES_ENCODER_FP1.7z (12.2 KB)

Any more information please ask
Thanks a million
kind regards
Natalia

In startup_stm32f2xx-XRAM.s, there is some strange handling of the initial MSP value. (I assume you are using that file and not startup_stm32f2xx.S.)

As an experiment can you try removing this line in prvPortStartFirstTask(). Or just comment it out like this:

// " msr msp, r0 \n" /* Set the msp back to the start of the stack. */

Hi Jeff,

I am looking at my project definition an I think that I tell the linker use this -T"${ ProjDirPath }\startup\stm32_flash_xram_4Mb.ld" file.

Please find attached the linker options I have…

I don’t know how to check if I am using startuo_stm32f2xx.S or startup_stm32f2xx-XRAM.s… I will try to discover

I have just tried to debug the project removing //“msr msp, r0 \n” as you suggested for not setting the msp back to the start of stack