Hello,
I m using Keil RTX on STM32F411. My IDE is Keil too.
I have a task to maintain and upgrade previous code where RTX is being used.
I need to debug a Stack Overflow (seen in System and Thread Viewer) and for that I need to identify the first overflow event to dig in that thread.
We can learn about hooks in freeRTOS here: https://www.youtube.com/watch?v=vBoP4Q6rf5g&list=PLnMKNibPkDnFeFV4eBfDQ9e5IrGL_dx1Q&index=20
The idea of having a callback when a Stack Overflow event happens is great.
Can some one give me a Tip, how to implement Hook in RTX or any approach to deal with Stack Overflow in RTX?
Another question is, I see a lot of Stack Overflows in " System and Thread Viewer" but would expect my System to fail totally, but instead the majority (not all) of Threads keep running.
I mean, this code shouldn't be running, one stack overflow would be enough to ruin the application. Is " System and Thread Viewer" info reliable?
br
I assume you are using RTX5 and not the older version 4.
If you set OS_STACK_CHECK at build time, then on any context switch, RTX will check that the thread that is being de-scheduled has not gone off the end of its stack. Of course in some respects, that check is too late. You really want the system to alert you to the first instruction that blows the stack. You could try using the MPU (if your cpu has it, it is optional) and use it to make non-writable the memory area below your thread stack(s). You'd need to have a very clear picture of the memory layout of the system, but you can get that from the linker script (scatter file).
Another trick I have used is where the idler thread simply enumerates all threads and calls osThreadGetStackSpace for each, maintaining a list of minimum values and printing each time a thread lowers its space remaining. You could print to SWO or some other channel.Of course, the idler only runs when all real threads are asleep/blocked, so again this technique won't show you the MOST space used by any thread, but will give clues as to when a thread approaches using all of its allocated space.
I fully agree with tobermory and I would also enable 'Stack Watermarking'. With this option, the debugger 'sees' the total stack consumption of a thread and not just at the time a thread is switched.
I using RTX version 4.
I have Stack Overflow Checking Enabled
I have Stack usage Watermark Enabled
Processor mode for thread execution Privileged Mode.
With this settings on, I see in debbug mode the stack consumption of a thread using " System and Thread Viewer", but this method seems not to be realible.
So, a Hook function like in FreeRTOS is out of question. ok
thx
If at all possible, I would update to RTX5. Its supplied API is much richer than that in RTX4. RTX4 doesn't really expose thread stack usage to application code, i.e. there is no osThreadGetStackSpace (nor osThreadGetStackSize).
I also have a legacy project using RTX4. See below where I basically ported thread stack api routines from RTOS2/RTX5 to RTX4, it may prove useful to you. Be aware that you are accessing essentially private parts of the RTX kernel directly.
/* mimic osThreadGetStackSize() from the RTOS2 api (as implemented by RTX5) */uint32_t threadGetStackSize( osThreadId t ) { P_TCB tcb = (P_TCB)t; return tcb->priv_stack ? (uint32_t) tcb->priv_stack : 0;}/* mimic osThreadGetStackSpace() from the RTOS2 api */uint32_t threadGetStackSpace( osThreadId t ) { /* No stack watermarking? Then no info on stack usage */ if( (os_stackinfo & (1 << 28)) == 0 ) return 0; const uint32_t* stack; uint32_t space, limit; P_TCB tcb = (P_TCB)t; stack = tcb->stack; limit = tcb->priv_stack ? tcb->priv_stack : (uint32_t)&__StackTop; if( *stack++ == MAGIC_WORD ) { for( space = 4U; space < limit; space += 4U ) if( *stack++ != MAGIC_PATTERN ) break; } else { space = 0U; } return space;}
Hmm, how to format this as code block?
> "...but this method seems not to be realible."
What is not reliable with this method? With stack watermarking enabled, the complete stack is filled with a value that is constantly checked in the debugger. A stack overflow might be detected too late, but you can even see post mortem that a stack overflow happened. I did not watch the ST video yet, but how would you detect a stack overflow other than during a thread switch or with a MPU?
So, I m using RTX on STMF411, compiler 5.06 and MDK5.24 from keil.
When I say the debug info via "System and Thread Viewer" is not realible, I mean that when I have my threads stack set to 400Bytes, I have a max stack usage of ~90% and some overflows, when I change the stack to 1024Bytes, I see my max stack usage again arround 90%, so I dont understand what is going on. That's why I say "System and Thread Viewer" is not realible.
If you can shed some ligth, it would be great.
I need an example project where I can duplicate this issue. Anything else would be a wild guess. If you have an example please raise a support case and we will analyze this.
I can not give you any example code... But you can take a look onto this pictures and see what I mean.
I agree that these values do not make sense. I would really need an example project to duplicate and fix this.
Keil RTX 4 is not detecting a stack overflow. When a stack overflow is detected it calls os_error() and this is a terminal routine. You could have os_error() call a callback, but os_error() is as good a place as any to start debugging this. Since os_error() is called after the error event has occured, this is not way to prevent the error. As I recall System and Thread Viewer was not great at detecting stack overflow or usage. I think it was better when you only used the default stack size, but still I never used that to determine an actual stack overflow.