We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello there,
I am having a stack overflow on a cortex-M3, using RL-ARM. I have my memory allocated as follows:
main stack size: 1042 bytes (0x0000 0412, configured in startup_stm32f10x_cl.s) heap size: 1042 bytes (0x0000 0412, configured in startup_stm32f10x_cl.s) individual task stacks: init task: 160 bytes task 1: 512 bytes task 2: 348 bytes task 3: 348 bytes task 4: 210 bytes task 5: 200 bytes task 6: 200 bytes
I have a task called "init" that exists to start the other tasks. init is getting passed to os_sys_init_user. The problem is that program execution never gets into the body of init (if I put a breakpoint on the first line of init, it never gets there).
Some other features of how I have things set up:
I am using os_sys_init_user (rather than os_sys_init) to start *all* of my tasks, including init, to make it easy for me to fine-tune the size of each task's stack. In RTX_Config.c, I have the following settings:
Number of concurrent running tasks: 7 Number of tasks with user-provided stack: 7 Task stack size [bytes]: 20 Check for stack overflow: checked Run in privileged mode: checked Number of user timers: 5
I figure if I am using user-provided stack for every task, the task size value in RTX_Config.c shouldn't matter (20 seemed to be the min value it would let me use). Is that assumption correct? I've tried upping the size of the main stack size in startup_stm32f10x_cl.s, and I've tried upping the size of the user-defined stack allocated to init. In both cases I program execution ended up in os_stk_overflow.
What can I do to fix this overflow? Any thoughts would be greatly appreciated.
thanks, David Merrill
Thanks Franc.
Just so I understand completely, I want to clarify how the stack is organized:
Is it true that regardless of how many concurrent tasks I account for in RTX_Config.c (i.e. 7, in my case), the system idle task adds one more? And if I am providing user-defined amount of stack to *all* of my 7 tasks, the "Task stack size [bytes]" value in RTX_Config.c will determine the size of the system idle task's stack? And if so, is there any reason to give more than 68 bytes, or will that definitely be enough?
Another question is: Am I correct to think that the "main stack size" (as defined in startup_stm32f10x_cl.s) is separate from the 7+1 stacks that I have already mentioned? And if so, does this main stack handle variables and function calls from the main() function + interrupts?
So really, if my assumptions are correct, the complete picture of RAM usage should be:
main stack + 7 user-defined task stacks + 1 system idle task stack + heap.
Is that correct?
Finally, if I have "check for stack overflow" enabled, will this monitor overflow on all (9) stacks?
thanks, -David
No.
Please refer to:
http://www.keil.com/support/man/docs/rlarm/rlarm_ar_cfgtask.htm
* In addition to OS_TASKCNT user tasks, the system creates one system task os_idle_demon. This task is always required by the RTX kernel. Total number of concurrent running tasks is OS_TASKCNT+1 (number of user tasks plus one system task).
http://www.keil.com/support/man/docs/rlarm/rlarm_ar_stack_man.htm
The other stack spaces need to be configured from the ARM startup file.
Maybe see these:
http://www.keil.com/forum/docs/thread14201.asp
http://www.keil.com/forum/docs/thread14778.asp
http://www.keil.com/forum/docs/thread14294.asp
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.
1. the system will always add an os_idle_demon task. This task is defined in RTX_Config.c
2. a context save uses 64 bytes of the stack. If the os_idle_demon is a simple endless loop (by default), it needs only 64 bytes to save the idle task context. However if stack checking is enabled, this is not enough. You must add 4 bytes because the top of stack is marked with a signature value. This value must not be overwritten.
3. stack checking works on all tasks user-defined + system idle task (7 + 1 tasks).
4. the kernel main stack (defined in startup file) is not checked in stack checking.
5. the heap is required for the File System, if you do not use it, you can set heap size to 0 (on assumption that your own code does not use dynamic memory)