2010年9月21日 星期二

AVR@IAR 中堆疊的設定

Controlling the stack size

Have you ever experienced strange errors in your code, caused by an overflowing stack? Have you had
to run an application on a system with very little memory available? Then you know why the stack must
be sufficiently large, but not too large. Traditionally, this has been solved by using a mixture of qualified
guesses and experience, or by keeping track of every function and its needs. Another way to check
whether the stack was overflowing was to use a predetermined pattern in the topmost memory cells
used and check whether they had been written to after the code had finished running.


How does it work?
The plugin uses a predetermined pattern that is written into the memory area allocated to the stack,
0xCD. Furthermore, it keeps track of everything that uses the stack.
When debugging your code, just open the View menu and choose the Stack command
 
Now you will have a new window in IAR Embedded Workbench, the Stack window.
























Configure the stack debugging by right-clicking in the Stack window, choosing Options. The IDE Options
window is now displayed with the stack options preselected.

















Here you need to decide which level of stack use that makes you nervous. 90% is preselected. Select
the boxes "Warn when exceeding stack threshold" and "Warn when stack pointer is out of bounds".
Now it's time to run the application. Run the program in such a way that you are convinced that it has
executed the code with the deepest stack usage, and then break execution. Look in the Stack window.
Now you can see the current stack, and the data that is stored. Let your mouse pointer hover over the
gray-green bar at the top of the Stack window.




















In my example, only 288 of the 1024 bytes are used, so here it's possible to reduce the stack. These
settings are made in the linker command file associated with the project, in this case
LPC2378__Flash.xcl.
The line I need to edit is
-D_CSTACK_SIZE=400
Since I know that this application only uses 288 bytes I decide to add another 10% to make it 320, or
0x140. Keep in mind that addresses in the linker command files are written in hexadecimal notation, but
without the 0x prefix.
-D_CSTACK_SIZE=140 // Changed from 400
I save the file, and then rebuild the application. When I check how much of the stack is actually used I
seem to be on the safe side; only 90% used. If I hadn't known for sure that I reached the deepest
possible call count in my test execution, I would have needed to increase the safety margin accordingly.
To find out exactly how much stack to use, you need to be certain that you can run an application in
such a way that the usage of the stack is maximized, which leads to the question: What is it that uses
the stack?
Basically, it is functions, which means that nested functions use even more stack. In functions, what
makes the heaviest use of the stack is usually local variables and parameters. A function with many
large local variables can use more stack than many nested functions that use no local variables.
Another feature of the stack debug plugin is the possibility to see what is on the stack. This is most
easily illustrated with an example. I break the program and step a few times until I get this view.











Here you can see that the top of the stack is used by two local 1-byte variables in the function
GLCD_SendCmd.
You can use the stack debug plugin to find the function that is using the stack. Set a breakpoint at a
suspected point, check the stack, step and check. In my example I set a breakpoint before the function
that I think uses the most stack space and then I step the code.

























In this example it is a library function, printf, that uses most stack.
It is worth noting that the stack debug plugin does not affect performance except for the time it takes
after debugging to transfer the data to IAR Embedded Workbench. The delay from giving a command
such as Step until the results are displayed, depends on the amount of data.
The method described here—with a pattern written into the stack when it is allocated and then checking
whether it has been overwritten—is not foolproof, though. You can allocate memory, but in case it is not
initialized it might not be detected by the plugin if it is the last item on the stack. If you write the same
data to the stack area that the plugin uses, 0xCD, the method will fail.

IAR中HEAP、CSTACK、RSTACK如何配置

CLIB heap size        堆空間大小
這設置動態記憶體大小. 如果你使用C語言用到了malloc,calloc,realloc.free等標準庫涵數,那你就要設置你的HEAP大小了.void *malloc(size_t size)涵數是分配HEAP,只要你的HEAP設置大於或等於size_t size就可以了.如過沒有用到分配動態記憶體涵數,HEAP是多少多沒有關係,不會影響你的記憶體使用. C++方面,HEAP主要是為關鍵字new來分配動態記憶體的.

Data stack(CSTACK)
CSTACK
是資料堆疊大小,用於存放局部變數和某些參數的傳遞,注意IAR設置大小裏面單位是位元組

Return address stack(RSTACK) 
RSTACK
是函數返回位址堆疊 用於存放函數返回位址和中斷中斷點地址,注意IAR設置大小裏面單位是字
RAM裏面,首先是CSTACKRSTACK,然後是NEAR_INEAR_Z 

IAR
CSTACK,NEAR_HEAPRSTACK是預先分配好的,佔用存儲空間是固定不變的,相當於定義了一個全局陣列,GCC堆疊策略與IAR不同。堆疊大小不是預先分配好的,而是把SRAM裏面剩餘空間作為堆疊空間。
可以這樣:
1)
通過設置使 IAR linker 生成 .lst 文件,在 ./debug/list 目錄下,.txt 格式或 .html 格式,設置時可選擇。
2)
打開此 .list , 記錄 "Call Graph" 表格中 CSTACK RSTACK 的最大值,這個值是實際使用值。

3) 根據此值設置 CSTACK RSTACK 的值,一般要保守一點,即稍微大一點。 

沒有留言:

張貼留言

注意:只有此網誌的成員可以留言。