This does not allow us to help you. Why did you need to update the RTOS version - I don’t think there is any difference in the way it works between the V8.x you are using and the most up to date. Was it a compiler error? Or something else? Seems you are ignoring the features in the code that are there to help you, features that might tell you immediately what the problem is. I would strongly recommend updating to the latest FreeRTOS code as it has many more asserts() to help you, then enabling the asserts. If enabling the asserts causes and issue then provide us a clear description of what that issue is.
Additionally, enable stack overflow checking, and read through everything here: FreeRTOS - Open Source RTOS Kernel for small embedded systems - especially the page about setting interrupt priorities correctly. If you use the latest code with assert it will tell you if that is wrong.
Again, you are making your own life very hard and inefficient. I noted previously you said you had a print statement in one particular condition - a common pattern seen is for print statements to cause a problem (especially stack problems, as some are very stack hungry), then the user to add more print statements in to try and debug it - it is just not a good way of trying to debug when a decent debugger would enable you to put data watch points in, dump trace logs, and maybe have a kernel aware plug-in that showed you if you should be spending time looking at stack sizes or not.
I used a print statement if the stack were to dip below 100 bytes. Original stack sizes are 100 and one 1500. I later removed this since ISRs don’t use this stack. I am working with an obsolete mcu and ide. I have to see if the Segger debugger and IDE can be made to work, the RTOS plug in did not work the first time I tried it. Is there an example of a debug task with stack monitoring?
I wanted to add about the configAssert, I tried it with the TivaC MCU. The ARM compiler gave an error. I posted about it here some months ago and the pointer was to upgrade the RTOS. With this Stellaris MCU, the assert might work as is.
Thanks.
I added this to the startup file of the Stellaris project:
void vAssertCalled( unsigned long ulLine, const char * const pcFileName )
{
static portBASE_TYPE xPrinted = pdFALSE;
volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
/* Parameters are not used. */
( void ) ulLine;
( void ) pcFileName;
{
/* You can step out of this function to debug the assertion by using
the debugger to set ulSetToNonZeroInDebuggerToContinue to a non-zero
value. */
while( ulSetToNonZeroInDebuggerToContinue == 0 )
{
UARTprintf("\nFile name = %16c\t\t %ld", pcFileName, ulLine);
}
}
}
I assume this will work without a debugger? It will give me the line number and file name calling this function. I need connector parts to use with Segger debugger, I don’t have this yet.
A couple warnings about how you are doing this, generally, when FreeRTOS hits an assert, there is an assumption that the system is broken, and typically the assert should bring down the whole system, so vAssertCalled will disable the interrupts so you don’t task switch to some other task, and perhaps hit another assert! This may give issues with your UARTprintf, as that may need interrupt to run the serial port (or at least it should if that is how you are printing elsewhere).
Second, you are going to repeated print out that error message forever until you do something about it. (that might be good, so you can connect the serial port up later to see what the problem is).
The error happened, there was no print statement in the log to show to an assert happened.
If I were to create a debug task to monitor stack usage, will it be a fourth task using a 1 ms time splice? Or can I fit this check into each of the existing tasks? It is basically the check for highwater mark correct? The better way to mark this happened is to halt when the stack size dips vs using a print statement. I want to understand what a debug task looks like in the round robin scheduler.
The only other thing I can try to do is to halt the debugger when the error code happens. Though I don’t know what this will show because this is not a trace.
It is still not clear why you think this is definitely a stack problem. Do you have configCHECK_FOR_STACK_OVERFLOW set to 2? Have you tried increasing the size of the interrupt stack (which is the same stack as defined for use by main() before the scheduler starts)?
It won’t stop, as you leave interrupts enabled, so things will still happen (unless this happened in a critical section or a interrupt).
Also, one big issue with stack overflow issues (and other memory corruption) is that you can often just end up with a ‘crashed’ machine.
This is where you really need a real debugger, so when things have gone wrong you can stop things and look to see where you are, and perhaps look through memory to try and figure out what was happening when things went wrong.
I only tried to capture an assert. What is included in the assert test in free RTOS?
I did not define configCHECK_FOR_STACK_OVERFLOW.
If I define this to 2, do I have to call this function? Where and how do I call it?
void vApplicationStackOverflowHook( TaskHandle_t xTask,
signed char *pcTaskName );
As far as the main stack, from the map file
0x00040000 __top_MFlash_256 = 0x40000 (max flash size in Stellaris)
0x20018000 __top_RAM_96 = 0x20018000 (stack top).
RAM location is 0x20000000, size 0x18000.
It seems like the max available stack is there for the application. I don’t know to tell if its otherwise, can you? #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 30000 ) )
I can use a JTAG debugger with the TivaC MCU and try capturing this error. This won’t have RTOS capability in the IDE. Segger/ozone will take longer to setup if I am able to get the RTOS plugin to work.
I will change my vAssertCalled to exactly what I found on this website. Please review this. I will put a breakpoint at ulSetToNonZeroInDebuggerToContinue = 1 and see where it takes me.
With a debugger connected, the error will likely take longer to occur.
void vAssertCalled( unsigned long ulLine, const char * const pcFileName )
{
static portBASE_TYPE xPrinted = pdFALSE;
volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
/* Parameters are not used. */
( void ) ulLine;
( void ) pcFileName;
taskENTER_CRITICAL();
{
/* You can step out of this function to debug the assertion by using
the debugger to set ulSetToNonZeroInDebuggerToContinue to a non-zero
value. */
while( ulSetToNonZeroInDebuggerToContinue == 0 )
{
ulSetToNonZeroInDebuggerToContinue = 1;
}
}
taskEXIT_CRITICAL();
}
If you define configCHECK_FOR_STACK_OVERFLOW to 1 or 2, then FreeRTOS will check the stack for overflow on every context switch. If it overflows, then FreeRTOS will call vApplicationStackOverflowHook with the information about the task that it detected the problem, so you can log that and then hang.
for configASSERT, FreeRTOS has a number of asserts in the code checking for configuration errors and misuse of the API, as well as for some ‘impossible’ things that might happen due to misuse of the configuration or the program corrupting the system state.
To see how much stack space is left for ISRs, you would need to look at the map and see the address of the highest allocated ram and compare that to the stack top location.
Excuse me for expressing some frustration, again, on Richard Damon’s behalf. Richard D has put a lot of effort into trying to support you but again you are not helping yourself first. You have been talking about stack overflow through this thread but have not used the facilities in place to help you know within one tick period (as least if you set configCHECK_FOR_STACK_OVERFLOW set to 2) if your task stack is overflowing. It would be faster for you to Google configCHECK_FOR_STACK_OVERFLOW then to write a question here on how to use it, and then wait for a reply. I just tried and the first link Google provided was FreeRTOS - stacks and stack overflow checking
There are assert() statemetns thorughout the code, each looking for a different error condition (like passing a null pointer) or misconfiguration (like having an incorrect interrupt priority - at least in recent code) - so they do lots of different things.
I tried adding the configASSERT definition to the Tiva C project. I am getting a cascade of errors Error 41 expectred an identifier: #define configASSERT( ( x ) ) if( ( x ) == 0 ) vAssertCalled( FILE, LINE ) //PN
The Tiva C project uses TI v16.9.3.LTS ARM compiler.
The Stellaris project did not give this compiler error. How can I make this error go away?
Why do you have two pairs of parenthesis around x in the definition? It should be something more like:
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__ , __LINE__ )
This line should be in FreeRTOSConfig.h
Note, configASSERT is a ‘function-like’ macro, so its defining syntax is a bit fussy, there can be NO spaces after the symbol configASSERT and the opening parenthesis, and no extra parenthesis is the parameter section. The extra () around the x, when used in the expansion section, is a good idea.
Yes, that brought down the number of errors, but it is still not compiling. For some reason when linking, the definition of vApplicationStackOverflowHook is not being found. I am able to open StackMacros.h from Tasks.c.
I originally had configASSRT defined exactly as outlined in
Attached is the current list of warnings and errors.
Thanks
If you look at the name: vApplicationStackHook(), that name tells you that you need to provide it. (First is the return type, then where it is defined, then the function). It doesn’t use a simple assert, as typically you want to get the information about which task went bad, which would be somewhat hidden in an assert.
I cobbled together this function and it compiled:
void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName )
{
TaskHandle_t bad_task_handle; // this seems to give me the crashed task handle
char *bad_task_name; // this seems to give me a pointer to the name of the crashed task
The error happened. The test did not halt either at the assert or at the stack overflow hook. I will next try breakpoints at the error code and see what I find. Unless there is some thing else I can try.
Thanks
Priya