Taming the stack usage of embedded applications
TASTE primarily addresses safety-critical on-board software. For embedded targets, it uses RTEMS.
A common theme that arises while supporting our TASTE users, is crashes or issues that relate to stack usage.
This article discusses how TASTE helps you to "tame" the stack requirements of your targets.
Note that as of Nov 21st, 2016, the TASTE build system reserves up-front the amount of stack space specified in the Concurrency View (set by default to 50K per thread, but can be modified on a per-thread basis via the Concurrency View editor
taste-edit-concurrency-view). This should address most stack issues.
To ease your debugging of stack issues, you should use the techniques we offer to execute under QEMU so you don't have to work on target (much faster executions, and therefore, iteration cycles - debug/run, debug/run, etc).
Check if your crashes reproduces there - if they don't, the crash is probably related to your HW setup.
So you run your binary under QEMU, and it just crashes upon startup.
Your application may need more stack to bootstrap - i.e. your startup functions may be trying to reserve more stack space than available; which means you need to tell RTEMS to reserve more total stack for your application.
You can modify the runtime (PolyORB-HI-C) to tell it to use more stack space.
The relevant file is po_hi_common.h and is located in the TASTE VM in /home/assert/tool-src/po-hi-c/include. Open this file and uncomment the following line:
--- po_hi_common.h (revision 8033) +++ po_hi_common.h (working copy) @@ -58,6 +58,7 @@ */ + #define CONFIGURE_EXTRA_TASK_STACKS (__PO_HI_NB_TASKS * 30000 ) #ifdef __PO_HI_NB_PORTS #define CONFIGURE_MAXIMUM_POSIX_MUTEXES __PO_HI_NB_TASKS + 10 + __PO_HI_NB_PORTS #define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES __PO_HI_NB_TASKS + 10 + __PO_HI_NB_PORTS
Then you need to recompile the runtime:
$ cd ~/tool-src ; make
This modification would give you an additional 30K of stack for each of your configured tasks (__PO_HI_NB_TASKS is automatically set from your design, so don't worry about it). If you want you can of course add a specific number here, that doesn't depend on the number of tasks in your design.
Or maybe one of your tasks appears to mysteriously die during runtime... could it be that it runs out of stack?
You have two tools to use here.
One is to augment your user code with something like this:
extern void rtems_stack_checker_report_usage(); rtems_stack_checker_report_usage();
At runtime, you will be able to see how close your tasks are to exhausting their stack allocation:
Stack usage by thread ID NAME LOW HIGH CURRENT AVAILABLE USED 0x09010001 IDLE 0040044620 - 004004561F 00400455C0 4080 Unavailable 0x0B010001 0040045628 - 0040047627 00400472E8 8176 Unavailable 0x0B010002 00400476C0 - 0040053A0F 00400536C8 49984 Unavailable
The first two lines will be RTEMS-related tasks - everything after them will show you numbers that won't exceed 50K; the default stack size of TASTE tasks (unless you edited your Concurrency view). The lower the "AVAILABLE" column goes, the closer your task is to exhausting its stack.
RTEMS can also place stack canaries (magic values) at the top of each task's stack, and then check that these values are proper - if not, one task has exceeded its space and overflown. To enable this checker, go in po_hi_common.h and uncomment...
Then rebuild POHIC and Ocarina (with "cd ~/tool-src ; make"). This will enable the checks, which will report back immediately the moment they detect a stack overrun.
What if I need more stack per task?
If you do, you'll need to edit your Concurrency view - spawn
taste-edit-concurrency-view and edit the stack requirements to your needs.
Faster way to recompile POHIC and Ocarina
The "cd ~/tool-src ; make" rebuilds everything - if you need a faster rebuild cycle for POHIC and Ocarina, every time you change something in po_hi_common.h you can also selectively build these two only:
$ cd ~/tool-src $ make configure-po-hi-c build-po-hi-c install-po-hi-c \ configure-po-hi-ada build-po-hi-ada install-po-hi-ada \ configure-ocarina build-ocarina install-ocarina
Good luck with your bug hunting!