Quality RTOS & Embedded Software

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


Loading

vTaskDelay(250) causes a “Hard Fault&...

Posted by Mike on July 1, 2013
I’m using the latest FreeRTOS version 7.4.2 and after a short while when vTaskDelay(250) is called I get a “Hard Fault” error.

Following the vTaskDelay function (where INCLUDE_vTaskDelay has been set to ‘1’), I see that portYIELD_WITHIN_API() calls vPortYield where portNVIC_INT_CTRL_REG (Interrupt Control State Register at 0xe000ed04) PENDSVSET bit is set causing a PendSV interrupt.

The vPortSVCHandler calls the vTaskSwitchContex function .

So far all is well and this function returns to the vPortSVCHandler.

However at the end of vPortSVCHandler, the “lr” register is set to 0xfffffffd such that the last instruction “bx lr”, not surprisingly, causes a Hard Fault interrupt. GDB gives me:

3 HardFaultHandler() main.c 0x8000210
2 0xfffffffc
1 0xfffffffc

This address is consistent with the “bx lr” instruction for Thumb code (LSB set to ‘1’)

Can anyone give me a clue to what’s going on?

RE: vTaskDelay(250) causes a “Hard Fault&...

Posted by Richard on July 1, 2013
“The vPortSVCHandler calls the vTaskSwitchContex function .”


Which port are you using? I don't think any of the official ports do that. Do you mean PendSV handler, rather than the SVC handler?

“However at the end of vPortSVCHandler, the “lr” register is set to 0xfffffffd such that the last instruction “bx lr”, not surprisingly, causes a Hard Fault interrupt.”


That looks like a valid exec return code, so if the MCU is genuinely using that instruction to return from an interrupt then the return address should be popped off the stack, and the MCU should to be returning to 0xfffffffd. If that is happening it looks like the MCU is in the wrong mode when it executes the instruction.

Regards.

RE: vTaskDelay(250) causes a “Hard Fault&...

Posted by Mike on July 1, 2013
I am using a STM32F205. I'm using the port.c and portmacro.h from portable\GCC\ARM_CM3

I have just two tasks, one to send a few characters to a UART, and another which currently sends some characters out to a SPI port and then waits. As soon as the next vTaskDelay function comes along this error occurs. In all other respects everything seems to be working!

Many thanks for your insight. I am relatively knew to the processor.

Regards

Mike Perkins

RE: vTaskDelay(250) causes a “Hard Fault&...

Posted by Dave on July 1, 2013
Have you set the interrupt priorities correctly?

http://www.freertos.org/RTOS-Cortex-M3-M4.html (note red text for STM32 users)
http://www.freertos.org/FAQHelp.html

If so, please post your UART and SPI interrupt configuration code and your interrupt handling code.

RE: vTaskDelay(250) causes a “Hard Fault&...

Posted by Richard on July 1, 2013
Mike,

I've seen exactly this problem several times on the 205 and it was generally caused by the main 'C' stack being too small or corrupted.

RE: vTaskDelay(250) causes a “Hard Fault&...

Posted by Dave on July 1, 2013
To elaborate, the main C stack gets reused as the interrupt stack, so is the stack used in PendSV and SVC handlers.

RE: vTaskDelay(250) causes a “Hard Fault&...

Posted by Mike on July 1, 2013
First of thanks Dave for asking about interrupt priorities. These were set to 6 and 7 after
NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
was run. Obviously subpriority is set to 0.

Travfrof, your supposition was correct. I had increased the stack for the "main_task" from 128 to 256 and still had the same error. Now after changing it to 1024 it now runs and I can fine tweak it according to my needs.

Dave, I thought the task in use at the time have to provide sufficient stack for the PendSV and SVC handlers, whether a task_delay or any other form of blocking? I'm guessing there might be some confusion with main and main_task? Doesn't Main should effectively end once
vTaskStartScheduler();
is run? Also won't it will have the stack pointer associated with the linker file, and not be allocated a "size"?

Thanks again.

Mike Perkins

RE: vTaskDelay(250) causes a “Hard Fault&...

Posted by Richard on July 1, 2013
The stack in use when you call main() is recycled for use by all interrupt handlers.

The stack used by tasks is allocated when the task is created.

So when an interrupt occurs the stack pointer is switched from the stack used by the interrupted task, so the stack that was originally used by main(). If that was not done then each task would have to allocate enough [extra] space on its stack for the maximum possible interrupt nesting depth, rather than having this space allocated just one.

Note the run time stack overflow checking only checks the task stacks because the scheduler knows how big each task stack is. It does not check the interrupt stack because it does not know (in a portable way) how big that is.

Regards.

RE: vTaskDelay(250) causes a “Hard Fault&...

Posted by Richard on July 1, 2013
Richard, just to be clear, if I start main and immediately create a few auto variables - they will be put in the main 'C' stack.

Once the scheduler runs, those auto-variables still occupy the stack right so when the OS starts using it, the stack is actually that much shorter?

Mike, be aware that any initialization you are doing before starting the scheduler uses the main stack so it has to be large enough to handle deep calls to initialization routines - especially if those routines create temporary arrays.

RE: vTaskDelay(250) causes a “Hard Fault&...

Posted by Richard on July 1, 2013
No, when the scheduler starts the stack pointer is set back to the start of the stack, so interrupts have the whole stack available. There is no way back to main() once the scheduler has started so there is no point in preserving any variables that were put on main's stack before the scheduler was started.

Regards.

RE: vTaskDelay(250) causes a “Hard Fault&...

Posted by Mike on July 1, 2013
Richard, I can see what you mean.

However, in my case I don't believe it was "main" that had a stack limitation that caused the crash. More likely my principle task, which I confusingly have called my "main_task" since when I increased the stack it then worked.

I am starting to presume that the stack size must also include variables declared in the task.

RE: vTaskDelay(250) causes a “Hard Fault&...

Posted by Richard on July 2, 2013
FreeRTOS does provide run time stack overflow protection, for task stacks at least, but it has to be turned on.

“I am starting to presume that the stack size must also include variables declared in the task.”


If you mean that when you declare an auto/stack variable inside a task, or in a function called by a task, then yes. The compiler does that though, not the RTOS. Tasks are just C function and completely unknown to the compiler.

Regards.


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


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

Latest News

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

Meet Richard Barry and learn about running FreeRTOS on RISC-V at FOSDEM 2019

Version 10.1.1 of the FreeRTOS kernel is available for immediate download. MIT licensed.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


Careers

FreeRTOS and other embedded software careers at AWS.



FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Renesas

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

Xilinx Microblaze and Zynq partner