Hi Everyone.
I am a little confused about something. Let's Suppose I'm running some concurrent tasks in RL-RTX. and let's say one of those tasks is calling a chain of functions ( a function that calls a function that calls another function).
I have 2 questions: 1. Where are the return addresses stored before jumping to the function instruction? Is it stored on the task's stack?
2. if it is stored on the task's stack, then is this (size of the return addresses) taken into account when the linker calculates "Maximum stack depth" and "Stack usage" stored in the html file in the output directory? or is that only the automatic variables?
Thank you very much in advance.
The answer to both questions is yes. However, the output if the compiler is only an estimate based on actual calls; it will not, as far as I know, indicate recursion which could have a much higher price in terms of stack usage. Another relation that cannot generally be resolved is the stack usage of function pointer. I am sure there are more - remember: it is only an estimate.
===A.==================================================================
www.keil.com/.../armlinkref_CHDGDFFF.htm
The static callgraph also gives information about stack usage. It lists the: size of the stack frame used by each function maximum size of the stack used by the function over any call sequence, that is, over any acyclic chain of function calls.
http://www.keil.com/support/man/docs/armcc/armcc_CJAIIDCG.htm
C and C++ both use the stack intensively to hold, for example: the return address of functions registers that must be preserved, as determined by the ARM Architecture Procedure Call Standard (AAPCS) local variables, including local arrays, structures, unions, and in C++, classes.
===B.==================================================================
http://www.keil.com/support/man/docs/rlarm/rlarm_ar_stack_man.htm
The Stack Management of the RTX kernel is designed for optimal memory usage. The RTX kernel system needs one stack space for the task that is currently in the RUNNING state:
Local Stack: stores parameters, automatic variables, and function return addresses. On the ARM device, this stack can be anywhere. However, for performance reasons, it is better to use the on-chip RAM for the local stack.
http://www.keil.com/support/man/docs/rlarm/rlarm_ar_cfgstack.htm
On the full context task switch, the RTX kernel stores all ARM registers on the stack. Full task context storing requires 64 bytes of stack.
=======================================================================
There are several different types of stacks.
1. the default system mode stack (which is defined in the startup file) 2. the default user mode stack (which is defined in the startup file) 3. the default user/system mode stack for interrupt service routines 4. The RTX kernel system needs one stack space for the task that is currently in the RUNNING state 5. The RTX kernel system needs one stack space for the os_idle_demon 6. The RTX kernel system needs several stack space for the tasks
I guess that, the context save of a task / an interrupt service routine is not counted by Linker the hidden stack usage of RTX kernel system is not counted by Linker
I already verified that the context save is not included in the maximum depth calculated by the linker.
Thank you for your reply.
As far as i have seen, the linker adds the following: "+ Unknown(Functions without stacksize, Cycles, Untraceable Function Pointers)" to the static call-graph html file whenever recursion occurs.
And I am also aware of the function pointer problem. the linker can, however, see the function being pointed to. and it calculates the stack usage for that function independently.
My current approach for estimating stack usage is by manually finding the function pointers in the project and then looking at the "function-being-pointed-to"'s maximum stack depth. while making sure that it itself is not using a function pointer down the line. and then finding what the "actual" worst-case usage is. and then adding 64 bytes to that for a context switch.
Thank you very much. Your reply was very useful to me.
I guess, theoretically, we should take the nested interrupts into account too. When the worst case of nested interrupts happens, it would be very stack consuming.
Stack and stack size configuration are always a mystery to me.