FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [July 2013 Threads] 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.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|