Go Down

Topic: SRAM and storing strings (Read 4775 times) previous topic - next topic

baum

But I never got an error. I got a warning.

BigMan73

I have exactly the same compilation warnings.
Tone.cpp indeed has the same warning.
It is due to the usage of F() strings (PROGMEM).

Is there a way to workaround this? Ideally I prefer to get Zero warnings.
Why is the the usage of F() strings recommended if the compiler warns against it??

PaulS

Quote
Tone.cpp indeed has the same warning.

The necessary changes to the Tone file have been documented. You could search for the fix, and implement it.

Quote
Is there a way to workaround this? Ideally I prefer to get Zero warnings.

See above. There are plenty of other warnings that are not shown to you, so zero warnings is pretty difficult to achieve.

Quote
Why is the the usage of F() strings recommended if the compiler warns against it??

The F() macro moves strings into program memory, removing them from SRAM, making SRAM available for other things. The compiler isn't warning against using F() in general, only in what Tone specifically is doing that causes the issue.

Marek080

The warning is really just a warning in IDE 1.0. It is triggered in tone.cpp, too. If you search the web it is not unique to arduino. I modified arduino.h by adding the following at line ~58.

Code: [Select]
// Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734
#ifdef PROGMEM
#undef PROGMEM
#define PROGMEM __attribute__((section(".progmem.data")))
#endif


loved the 68000 assembler back then and now I have to deal with THIS 8 bit thingy

BigMan73


The warning is really just a warning in IDE 1.0. It is triggered in tone.cpp, too. If you search the web it is not unique to arduino. I modified arduino.h by adding the following at line ~58.

Code: [Select]
// Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734
#ifdef PROGMEM
#undef PROGMEM
#define PROGMEM __attribute__((section(".progmem.data")))
#endif



Great, exactly what I was looking for!  :)
I have zero tolerance to compilation warnings, once you get used to them the quality of the code quickly deteriorates.
I don't know why Arduino team is releasing code that has warnings (like tone.cpp). It should not be allowed - period.

As for F() usage, I find it problematic:
A simple usage of:
String test = F("hello");
does not compile: "error: conversion from '__FlashStringHelper*' to non-scalar type 'String' requested"

The String constructors do not support this data type, which is very unfortunate. Sure, I can go to that class and start making it work but it should be working out of the box;

PaulS

Quote
The String constructors do not support this data type, which is very unfortunate. Sure, I can go to that class and start making it work but it should be working out of the box;

Why? The String class is for dynamic string creation. The progmem stuff is for static data. I think you're whining too much.

BigMan73


Quote
The String constructors do not support this data type, which is very unfortunate. Sure, I can go to that class and start making it work but it should be working out of the box;

Why? The String class is for dynamic string creation. The progmem stuff is for static data. I think you're whining too much.


So you're saying I cannot concatenate or use Flash strings using String class .. I'll guess I can just do it for my own private and modified version of String class.
I think you're not being very helpful. See post above by Marek080 - that was very helpful and actually resolved my original problem.

Zero warnings are not difficult to achieve - unless you're a mediocre or sloppy programmer

dxw00d

Code: [Select]
String test = F("hello");

Can you explain to me what you think this should do? I'm genuinely curious.

baum

Without the F() syntax, "hello" would be stored in your SRAM. But you don't have a lot of SRAM, so using the F() stores the string in the flash (program) memory, of which you have a lot. Projects that need a lot of strings will benefit from storing strings in flash, as it will free up ram for things like variables. But a flash string cannot be modified.

baum

dxw00d

I know what the F() macro does. I don't understand how you think it should apply when you create a variable that must, by definition, be stored in SRAM.

baum

Why must strings be stored in sram? You can put variables in the flash with PROGMEM... F() is sort of doing the same thing.

PaulS

Quote
So you're saying I cannot concatenate or use Flash strings using String class .. I'll guess I can just do it for my own private and modified version of String class.
I think you're not being very helpful. See post above by Marek080 - that was very helpful and actually resolved my original problem.

Sorry. I'm not feeling good today. The String class was developed to make string processing easy - constructing a string from data read from the serial port, for instance. I would guess that no one thought that adding a Flash-compatible constructor or concatenation operator was necessary. Of course, if you want to clutter up your SRAM with Strings made from Flash data, you are free to do so.

I know how to do all the stuff that the String class does, using string functions, so I've never felt the need to use the String class, especially after looking at how the concatenation operator works.

Your mileage may vary.

BigMan73


Without the F() syntax, "hello" would be stored in your SRAM. But you don't have a lot of SRAM, so using the F() stores the string in the flash (program) memory, of which you have a lot. Projects that need a lot of strings will benefit from storing strings in flash, as it will free up ram for things like variables. But a flash string cannot be modified.

baum


+1 -> Exactly!
I actually ran out of SRAM space before moving to Flash strings.
But I didn't want to rewrite my entire Firmware because of that, as I am already using the String class heavily.
When you build strings on the fly, which are composed of constant/literal parts and dynamic values, the String class is very handy.
But moving to F() macro, broke the existing code.
Yes, I can re-write the whole code, but I would prefer to use the same Facade (String interface) instead of changing the implementation.

GoForSmoke

The String Object class makes it easier (for some, not me) to write string manipulation code without knowing what is going on in memory.
What do you think happens when you concatenate two strings? Not caring is for people who have excess RAM. How can that concatenation be done in read-only flash? Are you going to write a function for "you can't get there from here"?

I'm not the least bit surprised when String users have memory problems. They don't C so well.

Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

Nick Gammon

Here's the problem with the String library: It makes it easy to write a program that doesn't work.

What I mean by that is, the nice simple String handling initially simplifies things (eg. concatenation). So you use it all over the place. And then you get into full-scale testing. Like, running your program for more than 5 minutes. Then it crashes. Then you go onto the forum. Then people tell you to stop using the String class.

So basically it has just wasted your time. Because now you have to throw it away. You would have saved more time in the long run by not using it in the first place.

It's not a bug per se in the library. It's just that all that concatenation tends to fragment the rather small amount of memory you have on the chip.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Go Up