Trivial change, big problems.

Hi,

I've got a medium sized project (about 20 libraries) on a mega that has been working undisturbed for about a year, but I've just made what appears to be a trivial change to one of the libraries and suddenly it's crashed. Here's the function I added...

/**************************************************************************
  Set the GPS module to the given baud rate.
**************************************************************************/
void MiniGPS::setGpsBaud(unsigned long baud)               
{

  Serial.println("setGpsBaud() A");

  Serial.print("Setting GPS module to <");Serial.print(baud);Serial.println(">");

  Serial.println("setGpsBaud() B");

  switch (baud) 
  {
    case 9600UL:
      // Set baud rate to 9600
      //"$PMTK251,9600*27"
      strcpy_P(_messBuff, GPS_CONF_05);
      break;
    case 38400UL:
      // Set baud rate to 38400
      //"$PMTK251,9600*27"
      strcpy_P(_messBuff, GPS_CONF_06);
      break;
    case 57600UL:
      // Set baud rate to 57600
      //"$PMTK251,9600*27"
      strcpy_P(_messBuff, GPS_CONF_07);
      break;
    default: 
      // if nothing else matches, do the default
      // default is optional
      break;
  }

  Serial.println("setGpsBaud() D");

  // Write the command to the GPS module
  Serial2.println(_messBuff);

  Serial.println("setGpsBaud() E");
}

The NMEA commands that set the baud rate are defined as shown...

const prog_char GPS_CONF_05[]   PROGMEM = "$PMTK251,9600*17";
const prog_char GPS_CONF_06[]   PROGMEM = "$PMTK251,38400*27";
const prog_char GPS_CONF_07[]   PROGMEM = "$PMTK251,57600*2C";

And the string they're stored in defined like this.char _messBuff[100+1];  // Global medium-sized buffer.
Without the function, the whole project compiles, uploads and runs without problem. When I add the function. It still compiles and uploads, but when I call the function the arduino will crash and re-boot half way through the line Serial.println("setGpsBaud() B");

The project compiles to a size of 72996 bytes (of a 258048 byte maximum). And I've used the code herehttp://playground.arduino.cc/Code/AvailableMemory To tell me I have over 2000 bytes free at run time.

The function itself is designed for use once only (once the baud rate is set, it should stay set), so I can get the project to work simply by removing it.

The function will actually work fine as a stand-alone piece of code, it's only when I add it to an existing library that the whole project experiences problems.

If someone on this forum can spot what's wrong then I'd really appreciate it, but what I'm really after is
some advice on a general approach to this sort of problem. Since the function itself is so simple and appears to be correct, my assumption is that the error must actually be on one of my other twenty plus libraries - despite they fact I've used them happily for several years. So how do I go about re-testing my old libraries? how do I know where to start? My guess is that some code in an existing library happens to be corrupting some memory space allocated to the new function - is that a sensible guess? What approach should I adopt to hunt down the source of error, I can't really post all 20+ libraries here and expect others to trawl through the whole lot for me.

First your comment is out of sync with the code - better have no comments
other comments are trivial better remove them too

You must add an action when the baud rate is incorrect/default e.g. add the default baud rate of 9600 ,
this prevents that _messBuff becomes a mess :wink: because it is not initialized.

  switch (baud) 
  {

    case 57600UL:
      // "$PMTK251,57600*2C"
      strcpy_P(_messBuff, GPS_CONF_07);
      break;

    case 38400UL:
      // $PMTK251,38400*27"
      strcpy_P(_messBuff, GPS_CONF_06);
      break;

    default: 
    case 9600UL:
      //"$PMTK251,9600*27"
      strcpy_P(_messBuff, GPS_CONF_05);
      break;
  }

Thanks Rob,

Those are good programming and style tips, but don't actually stop the crash and re-boot!

The function will actually work fine as a stand-alone piece of code, it's only when I add it to an existing library that the whole project experiences problems.

Have you tried writing a short test program that uses the library with the new method but only calls the method?

Is your new code the straw that breaks the camel's back - by running out of SRAM

...R

Robin2:
Is your new code the straw that breaks the camel's back - by running out of SRAM

...R

And why are you NOT using the F() macro to save SRAM for important stuff?

Is your new code the straw that breaks the camel's back - by running out of SRAM

Maybe it is, but I've done my best check as mentioned in the original post. I think I have 2k of free memory available at runtime, is there a better way of checking that's not already covered in the link I mentioned?

And why are you NOT using the F() macro to save SRAM for important stuff?

Doesn't the F() macro just move stuff to PROGMEM? isn't it the same as....

Code: [Select]
const prog_char GPS_CONF_05[] PROGMEM = "$PMTK251,960017";
const prog_char GPS_CONF_06[] PROGMEM = "$PMTK251,38400
27";
const prog_char GPS_CONF_07[] PROGMEM = "$PMTK251,57600*2C";
Code: [Select]

Fulliautomatix:
Thanks Rob,

Those are good programming and style tips, but don't actually stop the crash and re-boot!

How large is the message buffer ?

Doesn't the F() macro just move stuff to PROGMEM? isn't it the same as....

No and no. What the F() macro does is keep stuff (string literals) from being copied, at run time, from flash memory (PROGMEM) to SRAM.

Your code has a LOT of string literals that do not need to be copied to SRAM.

Serial.println(F("setGpsBaud() A"));

How large is the message buffer ?

Code: [Select]
char _messBuff[100+1]; // Global medium-sized buffer.

Your code has a LOT of string literals that do not need to be copied to SRAM.

True, but most of them I just put in to try to work out at what point it crashes at - they're not in the live code, and I get the same problems with and without them.