Tips-and-Tricks

Version 16 (Anthony Rowe, 09/14/2007 05:57 pm)

1 1 Anthony Rowe
2 16 Anthony Rowe
3 16 Anthony Rowe
h2. Nano-RK Tips and Tricks
4 16 Anthony Rowe
5 1 Anthony Rowe
Many of these suggestions are generally good practice for any resource constained development.
6 1 Anthony Rowe
7 16 Anthony Rowe
*Don't Allocate Large Data Structures Inside Functions*
8 16 Anthony Rowe
* Allocating large data structures in functions puts them on the stack.  Typically your task's stack is only 128 bytes, so putting things like a network buffer on the stack will almost certainly cause a stack overflow. Instead, make large data structures global.
9 1 Anthony Rowe
10 16 Anthony Rowe
*Take Care When Passing Large Data Types to Functions*
11 16 Anthony Rowe
* When passing large data structures, make sure to pass them by reference using pointers so that they do not get pushed on the precious stack.
12 1 Anthony Rowe
13 16 Anthony Rowe
*Avoid Recursive Function Calls*
14 16 Anthony Rowe
* Recursive function calls are also heavy when it comes to stack consumption.  Try to avoid them whenever possible
15 5 Anthony Rowe
16 16 Anthony Rowe
*Use "inline" For Speed And To Save Stack Space*
17 16 Anthony Rowe
** When it seems fit, use "inline" to avoid pushing things onto the stack for small functions.
18 13 Anthony Rowe
19 16 Anthony Rowe
*Be Very Careful With Dynamic Memory*
20 16 Anthony Rowe
* Malloc does work, but if you frequently malloc and free memory you will create fragmentation.  Eventually this fragmentation can lead to malloc failing.  This is especially bad when you run your application for a few minutes and it seems fine, but then fails after a few hours.  In general, avoid using malloc whenever possible. If you must, use it in situations where the code can safely continue if allocation fails.
21 1 Anthony Rowe
22 16 Anthony Rowe
*Use nrk_kprintf() Whenever Possible*
23 16 Anthony Rowe
* Strings used in normal printf() are stored in RAM!  nrk_kprintf() stores them in FLASH memory using the PSTR() macro.  Only use regular printf() when the string is dynamic (i.e. you use %d to print variables etc).  
24 9 Anthony Rowe
25 16 Anthony Rowe
*Watch out for strings*
26 16 Anthony Rowe
* Strings declared anywhere consume DATA and hence use RAM.  They are also stealthy in that they don't show up using avr-nm.  Try to avoid them at all cost.  Many times it is better to pass a numerical value to a function that has a big kprintf() switch inside it.
27 1 Anthony Rowe
28 16 Anthony Rowe
*How Much Memory Is My Code Using?*
29 16 Anthony Rowe
* After you compile, you should get a printout that tells you the size of your .data, .text and .bss sections.  .data is the amount of RAM that your program uses that is defined at startup to a particular value.  This means that it has to be stored in both RAM and ROM. .text is the amount of code your program uses.  .bss is the amound of zeroed out RAM your program uses.  Since the memory is set to 0 by default, you do not need to store a copy of it in ROM like with the .data section.  So your total RAM is data+bss while your FLASH usage is data+text.  In Nano-RK the stacks for applications are stored in static memory, so they appear in the bss section.  The kernel stack by default does not, so you should account for the RAM usage as data+bss+128bytes to be safe.   In the following example the RAM usage is 220+1021+128 = 1369 and the FLASH is 17258+220 = 17478.  A [[FireFly]] v2.2 node has 8192 bytes of RAM and 131072 bytes of FLASH.
30 16 Anthony Rowe
<pre>
31 13 Anthony Rowe
Size after:
32 14 Anthony Rowe
main.elf  :
33 13 Anthony Rowe
section     size      addr
34 13 Anthony Rowe
.data        220   8388864
35 13 Anthony Rowe
.text      17258         0
36 13 Anthony Rowe
.bss        1021   8389084
37 13 Anthony Rowe
.stab      41268         0
38 13 Anthony Rowe
.stabstr   16934         0
39 13 Anthony Rowe
Total      76701
40 16 Anthony Rowe
</pre>
41 13 Anthony Rowe
42 16 Anthony Rowe
*What variables are using up my memory?*
43 16 Anthony Rowe
* Use avr-nm to find a list of symbols and how much they consume.  Below is an example that prints the size of functions and static memory sorted as decimal:
44 16 Anthony Rowe
<pre>
45 15 Anthony Rowe
avr-nm -S --radix=d --size-sort main.elf
46 15 Anthony Rowe
...
47 15 Anthony Rowe
08388989 00000001 D NRK_UART1_TXD
48 15 Anthony Rowe
...
49 1 Anthony Rowe
08389446 00000116 B tx_buf
50 1 Anthony Rowe
00012074 00000118 T nrk_event_wait
51 16 Anthony Rowe
</pre>
52 16 Anthony Rowe
* "T" refers to the text section, "B" refers to the BSS section, and "D" refers to the data section.  Remember that strings don't show up in this list because they do not have compiler mapped labels.
53 1 Anthony Rowe
54 16 Anthony Rowe
*Avoid floating point*
55 16 Anthony Rowe
* There is no FPU on this processor, so all floating point is done through software emulation.  It is big and very slow.
56 1 Anthony Rowe
57 16 Anthony Rowe
*Stick with C99 variable types*
58 16 Anthony Rowe
* Use C99 types like (uint8_t, int8_t, uint16_t, int32_t etc) instead of int, short, long etc.