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
Code Analysis
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- pburgess
- Posts: 4161
- Joined: Sun Oct 26, 2008 2:29 am
Re: Code Analysis
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.
If your program is using any canned tables or strings, you can stick these in flash program space using the PROGMEM directive.
- westfw
- Posts: 2008
- Joined: Fri Apr 27, 2007 1:01 pm
Re: Code Analysis
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:
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
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
- wdickenson
- Posts: 184
- Joined: Fri Nov 16, 2012 8:43 pm
Re: Code Analysis
wow. Thanks. I'll start there.. Thanks !
- wdickenson
- Posts: 184
- Joined: Fri Nov 16, 2012 8:43 pm
Re: Code Analysis
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
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
-
- Posts: 466
- Joined: Thu Aug 30, 2012 1:34 am
Re: Code Analysis
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.
- adafruit_support_bill
- Posts: 88093
- Joined: Sat Feb 07, 2009 10:11 am
Re: Code Analysis
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
Some good tips here on managing memory: http://itp.nyu.edu/~gpv206/2008/04/maki ... o_mem.html
- wdickenson
- Posts: 184
- Joined: Fri Nov 16, 2012 8:43 pm
Re: Code Analysis
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 !
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 !
- westfw
- Posts: 2008
- Joined: Fri Apr 27, 2007 1:01 pm
Re: Code Analysis
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:avr-nm -nS /tmp/applet/*.elf | grep " [BD] "
Code: Select all
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));
- wdickenson
- Posts: 184
- Joined: Fri Nov 16, 2012 8:43 pm
Re: Code Analysis
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.
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: 184
- Joined: Fri Nov 16, 2012 8:43 pm
Re: Code Analysis
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
Thanks
- westfw
- Posts: 2008
- Joined: Fri Apr 27, 2007 1:01 pm
Re: Code Analysis
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.
I've completely forgotten what the windows equivalent of "grep " [BD] "" would be, though.
Code: Select all
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:\>
- wdickenson
- Posts: 184
- Joined: Fri Nov 16, 2012 8:43 pm
Re: Code Analysis
Thank you ! I will run that tonight and start the memory reduction program again !
Thanks
Thanks
Please be positive and constructive with your questions and comments.