Code Analysis
Moderators: adafruit_support_bill, adafruit

Code Analysis

by wdickenson on Sat Dec 01, 2012 6:56 pm

I need to put a program on a memory reduction plan !

I've built a program that controls a set of the RGB Leds like super christmas lights. It includes IR control, PIR sensor to act as a night light, RTC, and finally a microphone connected to the FFT programs to make a really wild display when the music plays. All good.

Good news - I think I am close to having it all work.

Bad news - I think I am out of ram. I had to comment out some functions to get this to run.

Now I am ok with stripping out some functions, but before I do, is there some code analysis tools to find unused variables, unused routines etc ?

Is there a book or article on reducing memory footprint ?

Thanks

wdickenson
 
Posts: 96
Joined: Fri Nov 16, 2012 7:43 pm

Re: Code Analysis

by pburgess on Sat Dec 01, 2012 7:03 pm

In the Arduino preferences window, enable verbose output during compilation. This will usually report unused variables.

If your program is using any canned tables or strings, you can stick these in flash program space using the PROGMEM directive.
User avatar
pburgess
 
Posts: 2535
Joined: Sun Oct 26, 2008 1:29 am

Re: Code Analysis

by westfw on Sat Dec 01, 2012 7:22 pm

The easiest improvement comes from moving strings into flash.

Other than that, the most basic tool is "nm" (avr-nm for avr.) This dumps the symbol table for a .elf file, allowing you to see what is in RAM and how much space each element is taking:
Code: Select all | TOGGLE FULL SIZE
 avr-nm -nS /tmp/applet/*.elf | grep " [BD] "
00800100 D __data_start
00800100 00000002 D x
00800102 00000002 D y
00800104 00000001 D analog_reference
00800126 B __bss_start
00800126 D __data_end
00800126 D _edata
00800126 00000080 B pixels
008001a6 00000004 B timer0_overflow_count
008001aa 00000004 B timer0_millis
008001af B __bss_end
User avatar
westfw
 
Posts: 1373
Joined: Fri Apr 27, 2007 12:01 pm
Location: SF Bay area

Re: Code Analysis

by wdickenson on Sat Dec 01, 2012 10:31 pm

wow. Thanks. I'll start there.. Thanks !

wdickenson
 
Posts: 96
Joined: Fri Nov 16, 2012 7:43 pm

Re: Code Analysis

by wdickenson on Sun Dec 02, 2012 10:35 am

I may be fixing the wrong problem.

Before I go code crazy - I have a basic question.

The compiler tells me that I have a 27K program to a max of 32K. 5K left.
When I run the program, the very first call is to the memory function which returns 105.
Then the program either a) stops dead b) loops through setup at high speed.

So while I originally thought my issue was too much program, I am now wondering which memory.

Any thoughts ? I dont want to post 1500 lines of my learning code. While I have tested each piece, this is the first integration test !

This is an UNO.

Thanks

wdickenson
 
Posts: 96
Joined: Fri Nov 16, 2012 7:43 pm

Re: Code Analysis

by tldr on Sun Dec 02, 2012 10:52 am

that's 5k of flash and 105 bytes of sram. the sram will probably be depleted with a couple of nested function calls. local memory in functions is going to have to fit in there.
"If I had known it was harmless, I would have killed it myself." - Phillip K. Dick, A Scanner Darkly
User avatar
tldr
 
Posts: 466
Joined: Thu Aug 30, 2012 12:34 am

Re: Code Analysis

by adafruit_support_bill on Sun Dec 02, 2012 11:02 am

RAM is typically the limiting factor in the UNO. Worst-case, you can upgrade to a Mega which has 4x the RAM. But you can probably claw back some space with a careful review of the code. Strings are the low-hanging fruit. Also look for variables (especially arrays) that are bigger than they need to be (e.g. using float when an int will do, or using an int where a byte is sufficient).
Some good tips here on managing memory: http://itp.nyu.edu/~gpv206/2008/04/maki ... o_mem.html
User avatar
adafruit_support_bill
 
Posts: 29216
Joined: Sat Feb 07, 2009 9:11 am

Re: Code Analysis

by wdickenson on Sun Dec 02, 2012 4:20 pm

Thank you ! All working !

I moved a few arrays into progmem
I replaced all my debugging strings with numerical codes
I reduced my LCD strings (that should have been a "duh". Should have thought of that sooner
I eliminated some code

And it's running. I have a fair amount of memory free.

But again, thank you all !

wdickenson
 
Posts: 96
Joined: Fri Nov 16, 2012 7:43 pm

Re: Code Analysis

by westfw on Sun Dec 02, 2012 9:28 pm

avr-nm -nS /tmp/applet/*.elf | grep " [BD] "

I should point out, since many beginners read here, that "nm" ONLY gives you information about the statically allocated data structures, things that are declared at the top level of your program, or "static" inside a function. In this example:
Code: Select all | TOGGLE FULL SIZE
int foo[10];
int bar[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}'

void loop()
{
   static int samples[10], lastsample;
   int index, i, j, k;

   String s = String(lastsample) + " = " + String(samples[lastsample]));
   char *p = malloc(10*sizeof(long));

foo, bar, samples, and lastsample will show up in "nm" output, but the memory used by i, j, k, s, and p is not "visible" until the program actually runs, and would NOT show up.
User avatar
westfw
 
Posts: 1373
Joined: Fri Apr 27, 2007 12:01 pm
Location: SF Bay area

Re: Code Analysis

by wdickenson on Tue Dec 11, 2012 11:28 am

Thats interesting.

I thought I had it solved but as the usual scope creep occurred, I now need to go back on the code version of weight watchers.

Thanks for that tip though.

wdickenson
 
Posts: 96
Joined: Fri Nov 16, 2012 7:43 pm

Re: Code Analysis

by wdickenson on Tue Dec 11, 2012 11:53 am

Hi - probably should asked this the first time around but in the Windows environment, how do I get the IDE to kick off the avr-nm program so I know whats loaded in where ?

Thanks

wdickenson
 
Posts: 96
Joined: Fri Nov 16, 2012 7:43 pm

Re: Code Analysis

by westfw on Tue Dec 18, 2012 8:47 pm

On windows, you would need to start a "Command Prompt" window and type out the path of the utility and file. This looks awful, but after you've done it once you can recall it via the history mechanism, and the .elf filename can be copy/pasted from the Arduino "verbose" compiler output.
Code: Select all | TOGGLE FULL SIZE
C:\>f:\bin\arduino-1.0.1\hardware\tools\avr\bin\avr-nm.exe C:\DOCUME~1\Bill\LOCALS~1\Temp\build5838287699423490265.tmp\Blink.cpp.elf | grep " [BD] "
0080010b B __bss_end
00800102 B __bss_start
00800102 D __data_end
00800100 D __data_start
00800102 D _edata
00800100 D led
00800106 B timer0_millis
00800102 B timer0_overflow_count
C:\>

I've completely forgotten what the windows equivalent of "grep " [BD] "" would be, though.
User avatar
westfw
 
Posts: 1373
Joined: Fri Apr 27, 2007 12:01 pm
Location: SF Bay area

Re: Code Analysis

by wdickenson on Tue Dec 25, 2012 1:10 pm

Thank you ! I will run that tonight and start the memory reduction program again !

Thanks

wdickenson
 
Posts: 96
Joined: Fri Nov 16, 2012 7:43 pm