Check if SRAM is damaged?

Hi there!

I just started with arduino and it's great fun - but actually my arduino shows a strange behavior which I can't explain.

As soon as I use a certain amount of SRAM the program goes crazy - debug output on the serial interface are random characters etc.

I have an Arduino-Ethernet with an ATmega328. This means 2k of SRAM should be available. As long as I use only 1730 all is fine. (add the data and bss section of the avr-size output):

>avr-size LedController.cpp.elf
   text    data     bss     dec     hex filename
  23256     854     876   24986    619a LedController.cpp.elf

But as soon as I use 1834 the problem occures:

>avr-size LedController.cpp.elf
   text    data     bss     dec     hex filename
  23352     958     876   25186    6262 LedController.cpp.elf

I am pretty sure that's not a programming error, because the only difference in the code are the following dummy lines anywhere in the program (it can't just be a single string because the compiler would optimise it away):

char test[100] = "dfddf"; 
  if(strcmp(test, "sdf") == 0) {
    test[0] = 33;
  }

Why is limit so low (between 1730 and 1834) and not at 2k? May my SRAM be broken? Is there a way to test the SRAM?

Why is limit so low (between 1730 and 1834) and not at 2k? May my SRAM be broken? Is there a way to test the SRAM?

Stack..
I doubt your RAM is damaged.
Try moving strings to PROGMEM.

And post code.

Hi AWOL, thanks for your reply. I think I can solve the problem for current project by using PROGMEM.

But: Does anyone know of a general way testing SRAM?

PS: If someone is interested; the code can be downloaded from http://www.flinks-journey.com/misc/LedController.zip. just uncomment the three lines in WebServer.cpp

But: Does anyone know of a general way testing SRAM?

Think you could do some tricks with AVRDUDE.EXE ? write and read back?

robtillaart:
Think you could do some tricks with AVRDUDE.EXE ? write and read back?

Thanks, I'll try that

But: Does anyone know of a general way testing SRAM?

Or define the largest array (within the given RAM), then write to and read values from it, like you would do it the eeprom.

...but be careful not to call any functions or do anything that would use RAM-based stack :wink:

I checked if the flash was correctly written with avrdude - seems ok.

>avrdude -p m328p -c stk500v1 -P COM2 -F -U flash:w:Led
oller.cpp.hex

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.05s

avrdude: Device signature = 0x000000
avrdude: Yikes!  Invalid device signature.
avrdude: Expected signature for ATMEGA328P is 1E 95 0F
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "LedController.cpp.hex"
avrdude: input file LedController.cpp.hex auto detected as Intel Hex
avrdude: writing flash (18920 bytes):

Writing | ################################################## | 100% 7.08s

avrdude: 18920 bytes of flash written
avrdude: verifying flash memory against LedController.cpp.hex:
avrdude: load data flash data from input file LedController.cpp.hex:
avrdude: input file LedController.cpp.hex auto detected as Intel Hex
avrdude: input file LedController.cpp.hex contains 18920 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 6.38s

avrdude: verifying ...
avrdude: 18920 bytes of flash verified

avrdude: safemode: Fuses OK

avrdude done.  Thank you.

Then I tried to validate the SRAM by reading values from an array as suggested by florinc.
Program:

void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  
  int errors = 0;
  
  Serial.println("init ok"); 
  
  char testa[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\0";
  int counta = strlen(testa);
  
  char testb[] = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\0";
  int countb = strlen(testb);
  
  Serial.println("start..."); 
  Serial.print("count a: "); 
  Serial.println(counta); 
  Serial.print("count b: "); 
  Serial.println(countb); 
  
  
  // test a
  for(int i=0; i<counta; i++) {
    if(testa[i] != 'a'){
        Serial.print("error in 'a' at ");
        Serial.println(i); 
        errors++;
    } else {
        Serial.print("ok in 'a' at ");
        Serial.println(i); 
    }
  }  
  Serial.println("'a' completed"); 
  
  // test b
  for(int i=0; i<countb; i++) {
    if(testb[i] != 'b'){
        Serial.print("error in 'b' at ");
        Serial.println(i); 
        errors++;
    } else {
        Serial.print("ok in 'b' at ");
        Serial.println(i); 
    }
  }  
  Serial.println("'b' completed"); 
  
  Serial.println(); 
  Serial.print(errors); 
  Serial.println(" errors"); 
  
}

void loop()
{
	// nothing happens after setup
}

Output:

Now I'm certain my SRAM is broken.
Unfortunately I got an SMD board :~ wonder if there's a change for replacement

Thanks for your help!

Check how much SRAM is remaining: Arduino Playground - AvailableMemory.

I found an ATMEL Application Note for testing RAM (http://www.atmel.com/Images/doc7715.pdf) and reconsidered the issue. Seems more like a collision with the Stack (...) :roll_eyes:

Code:

#define RAM_COUNT 1700 // bytes in RAM to be allocated an tested. If it's too high a problem with the stack pointer occures and 

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  } 

  PROGMEM int errors = 0; 
  PROGMEM char msg_error[] = " RAM errors";
  PROGMEM char currentByte;  
  PROGMEM int i;
  PROGMEM char pattern_55 = 0x55;
  PROGMEM char pattern_AA = 0xAA;
  
  // allocate heap
  volatile  char * test = (char*) malloc (RAM_COUNT);
  
  // test heap
  for(i=0; i<RAM_COUNT; i++) {
    currentByte = test[i];
    test[i] = pattern_55;
    if(test[i] != pattern_55) errors++;
    test[i] = pattern_AA;
    if(test[i] != pattern_AA) errors++;
    test[i] = currentByte;
  }
  
  Serial.print(errors);  
  Serial.println(msg_error);
  
  printRam();
}

void loop()
{
  // nothing happens after setup
}

void printIntHex(char *s, int v) { 
  Serial.print(s);
  Serial.print(": ");
  Serial.println(v);
}


void printRam() {
  extern int __heap_start, __bss_start, __data_start;
  int stack;
  int heapend = getHeapend();

  //printIntHex("End of RAM:   ", RAMEND);
  //printIntHex("Stack pointer:", SP);
  //printIntHex("Stack pointer:", (int) &stack);
  //printIntHex("Heap end:     ", heapend);
  //printIntHex("Heap start:   ", (int) &__heap_start);
  //printIntHex("BSS start     ", (int) & __bss_start);
  //printIntHex("Data start    ", (int) & __data_start);  
  printIntHex("Free RAM:     ", SP-heapend);
  printIntHex("BSS used:     ", (int) &__heap_start - (int) & __bss_start);
  printIntHex("Data used:    ", (int) & __bss_start - (int) & __data_start);
  printIntHex("Heap used:    ", heapend - (int) &__heap_start);
}

int getHeapend() {
  extern int __heap_start, *__brkval;
  
  if((int)__brkval == 0) {
    return (int)&__heap_start;
  } 
  else {
    return (int) __brkval;
  }
}

Output:

0 RAM errors
Free RAM: 41
BSS used: 180
Data used: 98
Heap used: 1702