Question:vApplicationStackOverflowHook

yukunduan wrote on Thursday, October 15, 2015:

I met a problem about vApplicationStackOverflowHook.
First my colleague creates a task using printf function.And I also use printf function to print the name of overflow task
in vApplicationStackOverflowHook .
The best solution I can think out is create a mutex at first of all.Then adding a macro like this :

	#define _USER_DEBUG_PRINTF(...)			
                                                       xSemaphoreTake( gsv_printf_semaphore, MAX_BLOCK_TIME );\
														printf(__VA_ARGS__);\
                                                        xSemaphoreGive( gsv_printf_semaphore)

So anywhere i need to print some message ,I use _USER_DEBUG_PRINTF() instand of printf();

Well Do you have some idear to protect printf in a new way?

Besides,if there is any way to create a protect about printf without change my colleague’s code?

yukunduan wrote on Thursday, October 15, 2015:

Well,when i change all printf function that i use in the project to _USER_DEBUG_PRINTF.
Then I find It,s still crash at the same character printed in the serial port.
But It,s go to a configASSERT:in function vPortEnterCritical
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );

yukunduan wrote on Thursday, October 15, 2015:

Well if there is any possiable the the task’s stack is over flow but don’t call fuction vApplicationStackOverflowHook?

yukunduan wrote on Thursday, October 15, 2015:

and what’s mean of

configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );

?
and why portVECTACTIVE_MASK if 0x1fUL?

yukunduan wrote on Thursday, October 15, 2015:

I enlarge the stack space when I create the task.The work is going successfully.

rtel wrote on Thursday, October 15, 2015:

Well Do you have some idear to protect printf in a new way?

If you are in the stack overflow hook, then you have a fatal error, so
no other tasks should be running - so in that case you don’t need to
protect the function.

If two tasks want to use the function in normal operation then you could
use a mutex, or scheduler suspension - although scheduler suspension
will prevent task switches for the duration of the printf call.

printf() is a common source of problems - especially in generic GCC
libraries which will use masses of stack. If printf() causes an
application to crash then using it again to try to diagnose the crash
can make things worse.

But It,s go to a configASSERT:in function vPortEnterCritical
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );

This is telling you that you have called a non interrupt-safe API
function from an interrupt - information that can be gleaned from the
comment immediately above that line:

/* This is not the interrupt safe version of the enter critical function so
assert() if it is being called from an interrupt context.  Only API
functions that end in "FromISR" can be used in an interrupt.  Only assert if
the critical nesting count is 1 to protect against recursive calls if the
assert function also uses a critical section. */

yukunduan wrote on Thursday, October 15, 2015:

Thank you.
First:
Well Do you have some idear to protect printf in a new way?
First.beacuse i’m using the HAL borad dirver provided by ST.The new versions provide uart transfer function like this HAL_UART_Transmit ,and there is a struct to save the uart’s state HAL_UART_STATE_READY or HAL_UART_STATE_BUSY_RX etc.And I fear when overflow hook function using uart,but other function change the uart sate to BUSY.So,I add the mutex in andwhere i using printf.
And I quite agree with your point.I will cancel the protect of printf in overflow hook function.
Second:

    But It,s go to a configASSERT:in function vPortEnterCritical
    configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );

I mean why
#define portVECTACTIVE_MASK 0x01f?
0x1f is 31 in decimalism.So I saw the nvic Vector table of STM_F4 datasheet is DMA1_Stream4.So I think if it should be 0x0e or 0x7ff?
Third:
Why I met two problem :
1.error in assert ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ;
2.error in hardfault
But I enlarge the stack of this two tasks,The system going succesfully.
And I define configCHECK_FOR_STACK_OVERFLOW 2
Why they didn’t run into this function vApplicationStackOverflowHook?

yukunduan wrote on Thursday, October 15, 2015:

And how to allocate a suitable stack for my task?

richard_damon wrote on Thursday, October 15, 2015:

To expand a bit on what RTE said, the stack overflow hook is called on a task reschedule, which (on some ports) can be either in an interrupt or not (I beleive in some it is always in interrupt context). Also, a stack HAS overflowed at this point, so the system is likely unstable, so you shouldn’t do much with normal calls, but disable interrupts and halt the system and maybe print a simple message with a simple I/O driver that uses polling (printf is likely not a good choice here, in fact I rarely find it the right choice in embedded projects).

When you create your tasks, there is a parameter to control how much space is allocated to its stack. It is a bit of an art to set this,you need to look at your task design and estimate how much it is going to need, and add a bit of a safety margin. You can then when the system is running check the slack and see if you have grossly over allocated some task (make sure you have exercised it enough to get it near worse case though) and back off.

yukunduan wrote on Friday, October 16, 2015:

Thank you.