Quality RTOS & Embedded Software

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




Loading

vApplicationStackOverflowHook although stack size should be big enough

Posted by danielriegel on March 17, 2017

Hi,

we're using freeRTOS 6.0.0 together with a Renesas RH850 microcontroller (R7F7010233AFP), which has 32kb RAM. I've got an implementation where several tasks (1ms, 10ms, 100ms, 200ms, 500ms, 1s) are running. When I add e.g. SCI transmit function call in 100ms I recognize in my MULTI debugger that it hangs in vApplicationStackOverflowHook which calls OS_ApplStackOverflowHook and has an endless loop.

In FreeRTOSConfig.h I set configMINIMALSTACKSIZE to 1024 and configTOTALHEAPSIZE to 0x5500.

When it stays in endless loop and hangs I see this call stack: 0 vApplicationStackOverflowHook(pxTask=0, pcTaskName=0x34) [srcappostasks.c:149,2] 1 vTaskSwitchContext() [srcosfreeRTOSRTOStasks.c:1593,26] 2 INTOSTM0() [srcosfreeRTOSRTOSportableGHSRH850F1Lportasm.850:245,10] 3 .intvectApp() [srcbspRH850startupdr7f701057startup.850:136,1]

So it was called from 1ms interrupt which handles the tasks. Both pointers pxTask and pcTaskName are at 0x0:

Could you give me a hint what I can do? How can I find the reason of the stack overflow? Which values should I change to fix the overflow?

Would be really great if you can help me!

Best regards, Daniel


vApplicationStackOverflowHook although stack size should be big enough

Posted by rtel on March 17, 2017

we're using freeRTOS 6.0.0

Yikes, the current version in 9.0.1. We cannot really support V6.

In FreeRTOSConfig.h I set configMINIMALSTACKSIZE to 1024 and configTOTALHEAPSIZE to 0x5500.

That only changes the size of the stack used by the Idle task.

Could you give me a hint what I can do?

Increase the size of the stack allocated to the offending task. The name of the task will be passed into the stack overflow hook function, but you may find in V6 the name gets corrupted by the stack overflow (that doesn't happen in later versions) and you will instead use the task's handle (which is also passed into the hook function).


vApplicationStackOverflowHook although stack size should be big enough

Posted by danielriegel on March 17, 2017

Yikes, the current version in 9.0.1. We cannot really support V6.

Yes, I know but I can't change it at the moment.

That only changes the size of the stack used by the Idle task.

No, I use this define also for 1ms tasks etc. > Increase the size of the stack allocated to the offending task. The name of the task will be passed into the stack overflow hook function, but you may find in V6 the name gets corrupted by the stack overflow (that doesn't happen in later versions) and you will instead use the task's handle (which is also passed into the hook function).

How can I change the allocated stack for a task? How can I get the task's handle? (pxTask is 0x0)


vApplicationStackOverflowHook although stack size should be big enough

Posted by rtel on March 20, 2017

The size of the stack is specified when you create the task. In version 6 probably the only way of getting the task's handle is using the last parameter in the call to xTaskCreate() used to create the task.


vApplicationStackOverflowHook although stack size should be big enough

Posted by danielriegel on March 20, 2017

xTaskCreate() has the following define in version 6: ~~~c

define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( NULLPTR ), ( NULLPTR ) )

~~~

Do you mean last parameter "pxCreatedTask" for the handler? How can I retrieve the handler when it hangs in function "vApplicationStackOverflowHook()"? (isn't pxTask then 0x00?)

I create e.g. the 100ms task with following call: ~~~c res = xTaskCreate(OSTask100ms, "Task100ms", configMINIMALSTACKSIZE100MS, NULLPTR, OSPRIORITYTASK100ms, NULL_PTR); ~~~

where configMINIMALSTACKSIZE_100MS is ~~~c

define configMINIMALSTACKSIZE_100MS ( ( unsigned short ) 1024 )

~~~

In some other posts I read of a typical minimal stack size of 60, mine is 1024 although it seems to be too small. Is "usStackDepth" only minimal stack size which could be much higher in run mode or is it the actual-fixed stack size?


vApplicationStackOverflowHook although stack size should be big enough

Posted by richard_damon on March 20, 2017

Since you passed a NULLPTR as the parameter pxCreatedTask, you program didn't save the value of the handle. The overflow hook is passed two values, the handle for the task that was detected to have overflowed the stack, and a pointer to the name of the task (assuming that the overflow hasn't damaged the Task Control Block so badly that it is still retreivable, in the earlier versions, the TCB was the first thing that an overflowing stack would overwrite). The stack size you provide is the actual size of the stack that the task will use, once created, you really can't change it, as the memory you would need to expand it into is used. Using a name like MINIMALSTACKSIZETASKNAME is a misnomer. The define configMINIMALSTACKSIZE is intended to define the minimum amount of stack needed by a very simple task (like the idle task), and other tasks might have their stack requirements specified as this minimal size + the amount of additional stack needed by that task for its use. When looking at a task to figure this out, look at the task function (and everything that it calls) and count up how much space its variables will use, especially be aware of any arrays defined in the task, as they can take up a lot of room.


vApplicationStackOverflowHook although stack size should be big enough

Posted by danielriegel on March 20, 2017

I've got several #defines of configMINIMALSTACKSIZE with different appendix for the tasks.

On task creation now I pass: ~~~c res = xTaskCreate(OSTask100ms, "Task100ms", configMINIMALSTACKSIZE100MS, NULLPTR, OSPRIORITYTASK100ms, &mgltaskhandle_100ms); ~~~

Now I get some values: https://abload.de/img/5lsugg.png

What can I derive from that? Still seems it was called from interrupt...

Another question: My freeRTOS runs with one 1ms timer tick. What happens if 100ms tasks needs more than 1ms and the 1ms task should start? Is the 100ms task interrupted? What happens if 1ms task needs more than 1ms? Will it be interrupted by itself and will not (maybe never) run to the end of it?

Further topic: I started to use uxTaskGetStackHighWaterMark() and at the beginning it seems to use 100-150 "words" in stack (my size is 1024, it returns e.g. 902). When I add a new function I get stack overflows and can't call that function anymore, so that won't help...


vApplicationStackOverflowHook although stack size should be big enough

Posted by rtel on March 20, 2017

Have you read the API documentation for the functions you are using? You can get the pdf reference manual here: http://www.freertos.org/Documentation/RTOS_book.html or simply read the documentation online: http://www.freertos.org/a00125.html


vApplicationStackOverflowHook although stack size should be big enough

Posted by rtel on March 20, 2017

Another question: My freeRTOS runs with one 1ms timer tick. What happens if 100ms tasks needs more than 1ms and the 1ms task should start? Is the 100ms task interrupted? What happens if 1ms task needs more than 1ms? Will it be interrupted by itself and will not (maybe never) run to the end of it?

These are fundamental questions you need to understand before using [any] RTOS. I would recommend reading through at least the first few chapters in the "Mastering the FreeRTOS Real Time Kernel" book - you will find a link on the same page as the reference manual (see my post of a few moments ago for the URL). It is quite a quick easy read and will give you a good grounding. I don't want to spend time typing in answers here when the information is already provided in a few words within the book.

Further topic: I started to use uxTaskGetStackHighWaterMark() and at the beginning it seems to use 100-150 "words" in stack (my size is 1024, it returns e.g. 902). When I add a new function I get stack overflows and can't call that function anymore, so that won't help...

If you have 900 words free before you call the function, and calling the function causes a stack overflow, then it would seem the problem is with the function. If the stack has overflowed then you should not be trying to call anything anymore as, unless you are using a port with memory protection, a stack overflow is not a recoverable error.

What is the function doing to use so much stack? For example, is it trying to allocate a large array on the stack?


vApplicationStackOverflowHook although stack size should be big enough

Posted by heinbali01 on March 20, 2017

Hi Daniel, without having read the entire text here above, please make sure that the (GCC) compiler doesn't create code for stack checking. The reason that I ask this, is that users reported that GCC's stack checking doesn't work well in their embedded projects. Regards.


vApplicationStackOverflowHook although stack size should be big enough

Posted by danielriegel on March 21, 2017

@Real Time Engineers ltd.: Yes, I'll read the documentation (our project is a bit in hurry and I thought to get some faster infos...) I'll examine the function, but there aren't any big local variable arrays, nested calls etc. I had the behavior also with other "normal" functions. Could you check my debugger screenshot with values of pxCurrentTCB? What is the criteria for "stack overflow"? My pxTopOfStack is 0xfedfd208, what does it mean? I see in StackMacros.h: ~~~c /* Is the currently saved stack pointer within the stack limit? */ if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) { vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); } ~~~

@Hein Tibosch: We don't use GCC but Greenhills compiler for our Renesas RH850. Maybe it generates code for stack checking, too. I will check that, thanks for the hint.


vApplicationStackOverflowHook although stack size should be big enough

Posted by richard_damon on March 21, 2017

Thinking about the values you are posting, one likely option is you have corrupted the FreeRTOS control variables, either with bad interrupt levels or a wild write. (pxTask = 0 is likely impossible otherwise).Perhaps also this might be the results of using the idle hook and blocking in it, which is a no-no (The Idle task must NEVER block, as something must always be able to run).


vApplicationStackOverflowHook although stack size should be big enough

Posted by danielriegel on March 21, 2017

We don't block idle hook, it's running as far as I see normally: https://abload.de/img/6nqu6y.png I can't imagine that we "wild write". Our interrupt priority should be set correctly.

For every task I set a minimal stack size of 1024, is that really too less (we don't have huge local arrays in the functions...)? Futhermore I pass a task-handler variable at xTaskCreate(), but value pxTask has a value of e.g. 0xfedfd588 Which task handle should that be? My task handler variable is listed in map file as: ~~~c .bss fedfa2d4+000004 mgltaskhandle100ms ~~~ I can't find any variable in memory location 0xfedfd588.

What about the call stack? https://abload.de/img/769um8.png


vApplicationStackOverflowHook although stack size should be big enough

Posted by rtel on March 21, 2017

We don't use GCC but Greenhills compiler for our Renesas RH850

Ok - this is not code you have obtained from us. We can try to assist the best we can, but have not seen the port, have no idea how good or correct it is, and cannot say for certain whether you are doing anything wrong of if the port is just bad. (Greenhills have never exactly been 'co-operative' with us)

[From Richard Damon] Thinking about the values you are posting, one likely option is you have corrupted the FreeRTOS control

I concur with this. Your TCB is completely corrupted. That is consistent with a stack overflow in FreeRTOS V6 (but not later versions of FreeRTOS) where the first thing to be corrupted by a stack overflow would be the TCB. That is not necessarily the only cause though. Anything writing over the TCB is likely to also write over the end of the stack, as they are next to each other (....in version 6) which could be picked up as a stack overflow. I'm not sure how intelligent the stack overflow detection is in FreeRTOS V6. Later versions use a couple of methods and of overflow detection and make it easier to debug.


vApplicationStackOverflowHook although stack size should be big enough

Posted by danielriegel on March 22, 2017

The port isn't done from Greenhills, but the company which did says they don't have a reason to update to version 9 because their version (6) runs stable (well, that's really not my opinion ;-))

How do you recognize that my TCB is corrupt? Do you think if TCB is corrupt there was a stack overflow? Or do both things don't have to do with each other?

Currently I set my minimal stack sizes of my tasks to ~~~c

define configMINIMALSTACKSIZE ( ( unsigned short ) 2000 )
define configMINIMALSTACKSIZE_1MS ( ( unsigned short ) 1024 )
define configMINIMALSTACKSIZE_10MS ( ( unsigned short ) 150 )
define configMINIMALSTACKSIZE_100MS ( ( unsigned short ) 300 )
define configMINIMALSTACKSIZE_200MS ( ( unsigned short ) 150 )
define configMINIMALSTACKSIZE_500MS ( ( unsigned short ) 150 )
define configMINIMALSTACKSIZE_1S ( ( unsigned short ) 150 )

~~~ Now it seems to run stable but it troubles me...


vApplicationStackOverflowHook although stack size should be big enough

Posted by richard_damon on March 22, 2017

First, as has been mentioned before, calling these the 'MINIMALSTACKSIZE' is a misnomer. These are THE stack size of the task, it will NEVER get bigger. The entry configMINIMALSTACKSIZE is suppose to represent the minimum stack size that any task will need to just support minimal processing (which is what the idle task does, so it uses that define for its stack). I tend to define the stack size for other tasks as (configMINIMALSTACKSIZE+n) where n is an estimate of how much stack that task needs to do its work. The fact that you have all the stack having smaller stacks than configMINIMALSTACKSIZE is bothersome to me, and says either you have put something using a lot of stack into the idle hook, or the sizes are set wrong.

A corrupted TCB, at least for the earlier versions of FreeRTOS, was easily caused by a stack overrun for processors with descending stacks, as first the TCB was allocated, and then the stack so the TCB was just before the stack in memory. It isn't the only way to corrupt it, but it is an easy way. Later version reversed the order of the allocations so a task would clobber something else instead, giving you a better chance to figure out what happened.


vApplicationStackOverflowHook although stack size should be big enough

Posted by mkupke on April 25, 2017

Independent of the FreeRTOS version you are using, I'm interested in the port - assembler files to save and restore context etc. - for the RH850 F1L. I tried to get it work with the V850 port, but that fails due to incompatibile things.

Can you provide the port you are using for the F1L?

Br, Martin...


vApplicationStackOverflowHook although stack size should be big enough

Posted by danielriegel on April 26, 2017

@Richard: Yes, I understand the misnomer, let's call it just "configSTACKSIZE". I don't know why I need such a bick stack size in idle hook, but with smaller one I'm running into stackoverflow...

Now we updated to V9.0.0 but it seems that I can't reduce the stack sizes since it'll run into stackoverflow, too. But as you wrote the corrupted TCB problem shouldn't exist now. I just run again into OS_ApplStackOverflowHook() and see these values: https://s22.postimg.org/a5gugzju9/image.png https://s22.postimg.org/a5gugzju9/image.png Could you help me interpreting the values? Is it correct, that the stackoverflow occured in 500ms task? (That would be a great information :-))

@Martin: Which files do you mean? https://s22.postimg.org/fi5ov47qp/image.png I'm not sure if I may give you the files. Where can I find assembler files to save and restore context?

Regards, Daniel


vApplicationStackOverflowHook although stack size should be big enough

Posted by richard_damon on April 26, 2017

Since pxTask is an odd value (0x7007), and this should be word aligned, I suspect that you have corrupted the FreeRTOS conttrol store, and when walking the task list the system got into a bad state.. This sort of problem can be hard to pin down. but it does say that the last task that was running was Task_500m, which well could be (but not neccisarily) the task that did tthe damage.


vApplicationStackOverflowHook although stack size should be big enough

Posted by heinbali01 on April 26, 2017

You wrote:

Yes, I understand the misnomer, let's call it just "configSTACKSIZE". I don't know why I need such a bick stack size in idle hook, but with smaller one I'm running into stackoverflow...

If you understand a bit of the assembler code, please try to debug and see what happens to the stack pointer when various routines are being called. I still get the impression that your compiler is doing stack- or other runtime-checking, and it uses the stack for that purpose.

The idle task never makes heavy use of the stack. tskIDLE_STACK_SIZE equals configMINIMAL_STACK_SIZE, which is usually 100 to 128 words, and that should be more than enough.


vApplicationStackOverflowHook although stack size should be big enough

Posted by danielriegel on May 3, 2017

@Hein: Yes, you're right because I use e.g. c uxTaskGetStackHighWaterMark(mgl_task_handle_1ms ); to check stack consumption. But I won't need it when software will be finished.

Now I think I managed to get it work without further research of the cause of stackoverflow. The Renesas RH850 has got another 32kb "Retention RAM" which is intended to use in deep stop modes but can also be used in run mode. Maybe it needs some more cycles to proceed and will not be as fast as normal RAM, but I can use it for RTOS! I put RTOS ucHeap in heap_2.c into Retention RAM by a #pragma command and am able to increase it a lot more without influencing the general RAM usage: ```c

pragma ghs section bss = ".os_stack"
/* Allocate the memory for the heap.  The struct is used to force byte
alignment without using any non-portable code. */
static union xRTOS_HEAP
{
    #if portBYTE_ALIGNMENT == 8
        volatile portDOUBLE dDummy;
    #else
        volatile unsigned long ulDummy;
    #endif
    unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];
} xHeap;
pragma ghs section bss = default

``` I think that's my solution so far (until I programmed so much that I need more RAM again :-))

Thank you guys for your hints!


[ 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