2

A few days ago I encountered memory problems (SRAM shortage) on my Arduino. I've read a lot and fixed the problem, now I have around 900 bytes free in SRAM. However, I still have difficulties understanding and using progmem.

The user is allowed to create up to 10 programs (a program in my case is just some object storing the user's preferences). As I don't want to run out of SRAM, I planned to store them in PROGMEM.

Consider the following class:

#define MAX_PROGRAMS 10
#define MAX_PREFS 10 

class Program
{ 
  public:
    Program(String name, Preference* prefs[]); // ctor

    String getName();
    static byte getNoOfPrograms();
    static Program* getProgram(byte idx);

  private:
    const String _name;
    static int _programCtr;

    Preference* _preferences[MAX_PREFS];
    static Program* _programs[MAX_PROGRAMS];
};

One notices that a program can store up to 10 preferences, hence, if the user decides to make 10 programs, each with 10 different preferences, we will definitely run out of SRAM.

Therefore, can I store instances of the above Program class in PROGMEM if I define them as below?

const Program* const pgm PROGMEM = new Program(F("Test"), ...);
// ...
delete pgm;

I presume this is possible since the whole object is const and could never be changed. I actually tried this and had no compiler errors, however, I was stumbled by the fact that the above two lines of code use 22 bytes of SRAM, when I expected it not to use any.

In my case, would it be better not to store the whole object in progmem but only its constant fields, and do the same for all constants in Preference ? (i.e. change const String _name to const char name[] PROGMEM; etc.)

VE7JRO
  • 2,554
  • 18
  • 25
  • 29
Kevin
  • 121
  • 1
  • 1
    Are you aware that everything you store in progmem is going to be fixed at compile time? I ask because you wish to use progmem to store user defined programs, so that makes sense only if the user defines that programs before compilation occurs... which to me makes the whole thing a nonsense... but I believe it all comes down to what is a program for you... – Roberto Lo Giacco Sep 23 '16 at 12:08
  • @RobertoLoGiacco Wow, thanks! This indeed does not make sense if it is to be fixed at compile time, since, the user will make those programs at runtime. Does this imply that i can not avoid to run out of SRAM, apart from limiting the user to less programs and preferences? – Kevin Sep 23 '16 at 12:19
  • Your example only puts the object pointer in program memory. "new" allocates the object from the heap. Please see this example that I put together a few years back. https://github.com/mikaelpatel/Sketchbook/tree/master/ProgramMemory – Mikael Patel Sep 23 '16 at 12:22
  • A more advanced example can be found in Cosa LCD Menu handler. The menu data structure is put in program memory; https://github.com/mikaelpatel/Cosa/blob/master/libraries/Menu/Menu.hh and example sketch, https://github.com/mikaelpatel/Cosa/blob/master/examples/LCD/CosaLCDmenu/CosaLCDmenu.ino – Mikael Patel Sep 23 '16 at 12:24
  • 1
    @MikaelPatel Right, i was not sure about dynamically allocating the object or not. Thanks for the examples, they are quiet useful, however, my program instances will be created at runtime. Hence, i think i will have no other option than limiting the user to a few programs.. – Kevin Sep 23 '16 at 12:28
  • @HyperZ Or cleaning up your system to a) not use String, and b) tokenize your program and store it as binary code. – Majenko Sep 23 '16 at 13:02
  • 1
    It is possible for software running on the ATmega to write to program memory at runtime, and even to erase it in large blocks. See bootloader sources for an example. – Chris Stratton Sep 23 '16 at 22:31
  • 1
    @Majenko Thanks, i cleaned up the whole system such that i don't use the String class anymore in order not to fragment the heap. Now, what do you mean by tokenizing my program and storing it as binary code? :) – Kevin Sep 29 '16 at 09:16
  • I've marked this as a duplicate of Using PROGMEM to store array of structs. The question isn't the same, but the solution is. – Pharap Aug 24 '17 at 18:40

0 Answers0