Go Down

Topic: Skecth does't work if bigger than 8K (Read 702 times) previous topic - next topic

yanque

I'm working with Arduino Mini. I have a program that is 8K aprox (around 8300-8400 bytes). When I try to include more code (not much more code, just only some Serial.prints for debbuging, around 300 bytes) the code fails (compiling and uploading is correct, but the application does not work). If I comment the prints, then the application works. Any idea?  Is there any way in Arduino to obtain a map file to see if there is something strange? I know I can do it with WinAVR, but it would be nice if Arduino could give us that information. In fact, I think there is not check of RAM usage, I mean, if I use more than 1k of RAM with the Atmega168, for example, the compiler does not report any warning or error, Is that true?
Does anybody had  the same problems?

Thanks

mellis

Yea, I'm guessing that you're running out of RAM - we don't give an error for that.  Unfortunately, I don't know a good way to check this, but it's something we should improve on.  I'll add a note about it to the troubleshooting page.

mem

#2
Dec 26, 2007, 09:11 pm Last Edit: Dec 26, 2007, 09:17 pm by mem Reason: 1
There is a function for reporting the amount of free ram here: http://rob.faludi.com/ITP/arduino/Arduino_Available_RAM_Test.pde

Copy the MemoryTest() function into your sketch and send the returned value to the serial port.

p.s. mellis, it would be convenient to have a 'memoryFree() function available in the distribution libraries for optional use when required. The call to malloc() links in over 500 bytes so it may not be suitable for inclusion as part of the base runtime.

mellis

Ah, cool.  That would be nice to add.  I'll have to play with it a bit, but it definitely looks useful.  

atmh

I'm overall very pleased with the Arduino compiler, I like how it tells how many bits are used out of a maximum.  I was just wondering today if it counted up the number of bits used by variables (such as an int using a maximum number of bits, or a long using another number of bits).  And basically... Does it?  Is this the question you guys just answered?

I'm new to this and I'm more of a mechanical guy, so this isn't exactly my realm (but I am finding it quite fun and interesting).

kg4wsv

If we were talking about a dinosaur like FORTRAN your calculation would be correct, but with a dynamic language like C memory usage is a non-trivial calculation, becasue typical automatic variables are allocated when the function is called, and in the general case compiler has no way of knowing exactly how that will happen.

For a worst-case example, let's look at a recursive function, like factorial (this one is slightly contrived to illustrate the issue):
Code: [Select]
int fac(int n)
{
 int result;

 if (n == 1)
   result = 1;
 else
   result = n * fac(n - 1);

   return result;
}


This function will allocate an int (2 bytes on the arduino) each time it is called.  If my calling function calls fac(7) the function will be called 7 times (6 times it will call itself) requiring a total of 7x2=14 bytes of RAM for the various copies of the variable result, but the compiler has no way of knowing this at compile time.

-j


mem

For the reasons given by j in the previous post, the best way of knowing the amount of free ram is to use a runtime function that requests free memory (malloc) to determine how much is actually available.

The following function will return free memory as an integer. Post #2 above has a link to a sketch that has a worked example.
Code: [Select]
// this function will return the number of bytes currently free in RAM
// written by Rob Faludi http://www.faludi.com
int memoryTest() {
 int byteCounter = 0; // initialize a counter
 byte *byteArray; // create a pointer to a byte array
 // More on pointers here: http://en.wikipedia.org/wiki/Pointer#C_pointers

 // use the malloc function to repeatedly attempt allocating a certain number of bytes to memory
 // More on malloc here: http://en.wikipedia.org/wiki/Malloc
 while ( (byteArray = (byte*) malloc (byteCounter * sizeof(byte))) != NULL ) {
   byteCounter++; // if allocation was successful, then up the count for the next try
   free(byteArray); // free memory after allocating it
 }
 
 free(byteArray); // also free memory after the function finishes
 return byteCounter; // send back the highest number of bytes successfully allocated
}



follower

Quote
If I comment the prints, then the application works. Any idea?

Another possibility is that you have an uninitialised variable somewhere. That can cause behaviour like you describe.

--Phil.

yanque

Thanks for yor help. I'll try to use a function like memoryTest to check how much RAM I use.

In any case ¿would it be too complicated to allow the Arduino user to specify its own compiler flags? I mean, it would be nice if the user could specify in the preferences window, for example, or in the preferences file, or wherever, the compilation flags. That way, we could use -Map options to see the RAM already allocated. Althoug it is not enough to see if your program could get out of RAM, it would help (and perhaps for other cases). On the other hand, it would be something hidden for the non-experienced user, so the "easiness" of the environment wouldn´t change.

Thanks again

mem

That's a very good point, it would be convenient if the memory map was made a little more accessible, but as you say, still invisible by default. Why not plant that thought in the suggestions threads.

Go Up