Globals and SRAM use


I'm working on a fairly complex project and have a lot of nested function calls, passing around a fairly large graphics structure of about 86 bytes. Suddenly, after a small addition to the source file, the program died in a dazzling display of junk on the TFT display. So, I threw caution to the wind and moved the graphics structure so it was now defined with global scope. Alas, no joy. I though the optimizing compiler, seeing the graphics structure was now global would automatically change the function argument to a pointer or maybe even ignore the parameter as part of the call. Evidently not. This program shows what's happening:

struct grafix {                                               // Graph structure declaration
  int x;                // upper left coordinate horizontal
  int y;                // upper left coordinate vertical
  int w;                // width of graph
  int h;                // height of graph
  float minX;           // minimum X graph value, can be negative
  float maxX;           // maximum X graph value
  float minY;           // minimum Y
  float maxY;           // maximum Y
  float xInc;           // scale division between lo and hi
  float yInc;           // y increment
  float currentValue;   // Current value
  int digitTotal;       // total digits displayed, not counting decimal point
  int decimals;         // digits after decimal point
  int barColor;         // Color for bar
  int voidColor;        // Background color in bar chart
  int backBar;          // Background bar color
  int border;           // Border color
  int textColor;        // Color for text
  int backFill;         // Background color for entire graph
  char label[30];       // Label text
} myG;

void setup() {

  Serial.print("in Setup(), Free ram = ");


void dummy(struct grafix my)
  Serial.print("in dummy(), Free ram = ");

void loop() {

int freeRam() {
  extern int __heap_start, *__brkval;

  //Calculate the free RAM between the top of the heap and top of the stack
  //This new variable is on the top of the stack
  int l_total = 0;
  if (__brkval == 0)
    l_total = (int) &l_total - (int) &__heap_start;
    l_total = (int) &l_total - (int) __brkval;
  l_total -= sizeof(l_total); //Because free RAM starts after this local variable
  return l_total;

Clearly, the compiler is doing exactly what I asked it to, but not what I thought it would. I'm just passing this info along in case someone else faces a similar issue down the road.

Why not pass a pointer to the structure, instead? Why pass the structure itself, by value?

My company produced and marketed an MSDOS C compiler back in the 80's and 90's. We had a parameter optimization flag that did that very thing as part of the optimizer, but you could turn it off. The dangerous part of that was that we had to adjust the called code, too. By default, we left that optimizer turned off. Now that I know what's going on, I probably will change everything to a pointer. I just did the global change to see if it might fix my problem, which it didn't.