Pages: [1]   Go Down
Author Topic: Question about memory management.  (Read 619 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have a question or two about memory management.  For the past couple of months I have been learning C/C++ from what I could glean from the internet and the Arduino help and example code. I have a Arduino Mega and an Ethernet shield. I started writing a web server as practice at learning C. Everything was going well, the server has become a fairly full featured server and runs well, serves up files, controls IO Pins and returns data from attached sensors. Suddenly I began getting system lockups. The first was when I began parsing the GET request from the Network Configuration page. Anyway, long story short, I believe what I am experiencing are stack/heap collisions. After visiting the Atmel site and looking through the AVR Libc Reference Manual I am almost positive. So, another rewrite is coming. But before that I wanted to know how certain things are stored, and in what part of memory.

For example:  
Code:
client.println(“<html>\r\n<head><title>Something Meaningful</title></head>“);
Is the text stored in program memory as a string literal or stored in SRAM?

Also, is it better to declare global variables rather than have functions create and free up the memory to avoid fragmentation?

And finely, is there a way to use an array of chars rather than a String object with functions such as FileType.name(); from the SD library? Or should I just initialize a String as a global variable with a reserved size?

It was the String in the parsing function that was crashing the program. So any info would be helpful, and thanks in advance for any replies.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 617
Posts: 49463
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Is the text stored in program memory as a string literal or stored in SRAM?
Yes, it is. Both. Use the F() macro to keep the string out of SRAM.

client.println(F(“<html>\r\n<head><title>Something Meaningful</title></head>“));

Quote
Also, is it better to declare global variables rather than have functions create and free up the memory to avoid fragmentation?
Not generally. Functions create variables on the stack, which is cleaned up when the function ends. Dynamic allocation, like Strings, happens in the heap, and can cause fragmentation of the heap.

Quote
And finely, is there a way to use an array of chars rather than a String object with functions such as FileType.name(); from the SD library?
Of course. The name() function returns a pointer to an array of chars that is NULL terminated. Specifically, what do you want to do with the name?

Quote
Or should I just initialize a String as a global variable with a reserved size?
This is what you should do with String:
String

Logged

Offline Offline
Jr. Member
**
Karma: 1
Posts: 86
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Adafruit has a nice overview of Arduino memory usage at http://learn.adafruit.com/memories-of-an-arduino/you-know-you-have-a-memory-problem-when-dot-dot-dot

By your description of your project, you likely have a lot of strings/character arrays, and as PaulS noted, they all get copied from program memory to SRAM, taking up valuable resources. F("…") is a simple way to save memory. For other strings you can use PROGMEM. There's a nice tutorial on it here: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=38003
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Is the text stored in program memory as a string literal or stored in SRAM?
Yes, it is. Both. Use the F() macro to keep the string out of SRAM.

client.println(F(“<html>\r\n<head><title>Something Meaningful</title></head>“));

Quote
Also, is it better to declare global variables rather than have functions create and free up the memory to avoid fragmentation?
Not generally. Functions create variables on the stack, which is cleaned up when the function ends. Dynamic allocation, like Strings, happens in the heap, and can cause fragmentation of the heap.

Quote
And finely, is there a way to use an array of chars rather than a String object with functions such as FileType.name(); from the SD library?
Of course. The name() function returns a pointer to an array of chars that is NULL terminated. Specifically, what do you want to do with the name?

Quote
Or should I just initialize a String as a global variable with a reserved size?
This is what you should do with String:
String



Thank You, that answered all my questions. I had never seen the F() macro before. I did some quick research on the web and discovered that the 2000+ bytes of HTML that the create config page function was loading up memory horribly. Not to mention several other page creation functions. That will be remedied.  And the fact that (god help me, this is C so I should have known) the name function returned a pointer to a string not the string it's self. And the String response is exactly what I was trying to achieve. Armed with this new information I can get everything back on track without a complete rewrite.

One last question (for now), is there a complete reference to the Arduino programming language? Something a little more complete than the reference file that comes with the compiler download? If I had known about the F() macro I would not have had the problem in the first place. The last time I did any programming was back in the late 80's in the structured programming days running DOS 6 using a Pascal compiler.

Thanks again for the help....
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 617
Posts: 49463
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The F() macro is documented in the stuff that comes with the IDE. It is NOT documented in a place where people might actually look for it, though.

http://arduino.cc/en/Serial/Print
Quote
You can pass flash-memory based strings to Serial.print() by wrapping them with F(). For example :

    Serial.print(F(“Hello World”))

The benefits of using it are complete ignored, though.

And, of course, why the print() method is documented on a page called Print is a mystery, since case DOES matter.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The F() macro is documented in the stuff that comes with the IDE. It is NOT documented in a place where people might actually look for it, though.

http://arduino.cc/en/Serial/Print
Quote
You can pass flash-memory based strings to Serial.print() by wrapping them with F(). For example :

    Serial.print(F(“Hello World”))

The benefits of using it are complete ignored, though.

And, of course, why the print() method is documented on a page called Print is a mystery, since case DOES matter.

Hey your right. I never actually looked at that particular example as Serial.print() was so self explanatory.  But your right about it being just a passing remark, not an explanation of why it would be useful. But the question remains. Is there a more all inclusive resource for the Arduino's command set, memory management and eccentricities of C/C++ when used on a microcontroller? Attempting to learn this based on bits and pieces, clues and the occasional code snippet is slow going and results in a lot of code rewrite when a better way is discovered.

PS. the F() macro and eliminating the Strings has the web server back up and running. Thanks again.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 617
Posts: 49463
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
But the question remains. Is there a more all inclusive resource for the Arduino's command set, memory management and eccentricities of C/C++ when used on a microcontroller?
Not that I'm aware of. There are a number of books available, but I haven't read any of them, so I can't recommend one. I do know that at least three of them were written by forum members, so hopefully they'll chime in and say something about their book in relationship to your question.

Quote
Attempting to learn this based on bits and pieces, clues and the occasional code snippet is slow going and results in a lot of code rewrite when a better way is discovered.
I can sympathize with that. But, that's about all I can do.
Logged

Pages: [1]   Go Up
Jump to: