Over 600 bytes of RAM for Serial on a Mega, Gasp!

I decided to look at Serial on the Mega after the post by fungus here http://arduino.cc/forum/index.php/topic,71833.0.html.

I was shocked to find that Serial uses over 600 bytes of RAM for a simple sketch that only prints to Serial port zero.

Am I doing something wrong?

I wrote a minimal serial library, MinSerial, and a test sketch for the test. I am using 0022.

Here is the test sketch:

#define MIN_SERIAL 0
int FreeRam() {
  extern int  __bss_end;
  extern int* __brkval;
  int free_memory;
  if (reinterpret_cast<int>(__brkval) == 0) {
    // if no heap use from end of bss section
    free_memory = reinterpret_cast<int>(&free_memory)
                  - reinterpret_cast<int>(&__bss_end);
  } else {
    // use from top of stack to heap
    free_memory = reinterpret_cast<int>(&free_memory)
                  - reinterpret_cast<int>(__brkval);
  }
  return free_memory;
}
#if MIN_SERIAL
#include <MinSerial.h>
MinSerial sout;
void setup() {
  sout.begin(9600);
  sout.println(FreeRam());
}
void loop() {}
#else
void setup() {
  Serial.begin(9600);
  Serial.println(FreeRam());
}
void loop() {}
#endif

With my MinSerial library the sketch prints 8159. With the standard Serial library the sketch prints 7549. Thats 610 bytes more for the standard Serial library.

I always assumed the buffers for Mega Serial ports were only allocated if you used the ports. That the loader would take care of it.

Here are the files for MinSerial:

MinSerial.h

#ifndef MinSerial_h
#define MinSerial_h
#include <WProgram.h>
class MinSerial : public Print {
 public:
   void begin(long baud);
   int read();
   void write(uint8_t b);
};
#endif  // MinSerial_h

MinSerial.cpp

#include <MinSerial.h>
//------------------------------------------------------------------------------
void MinSerial::begin(long baud) {
  uint16_t baud_setting;
  // don't worry, the compiler will squeeze out F_CPU != 16000000UL
  if (F_CPU != 16000000UL || baud != 57600) {
    // Double the USART Transmission Speed
    UCSR0A = 1 << U2X0;
    baud_setting = (F_CPU / 4 / baud - 1) / 2;
  } else {
    // hardcoded exception for compatibility with the bootloader shipped
    // with the Duemilanove and previous boards and the firmware on the 8U2
    // on the Uno and Mega 2560.
    UCSR0A = 0;
    baud_setting = (F_CPU / 8 / baud - 1) / 2;
  }
  // assign the baud_setting
  UBRR0H = baud_setting >> 8;
  UBRR0L = baud_setting;
  // enable transmit and receive
  UCSR0B |= (1 << TXEN0) | (1 << RXEN0) ;
}
//------------------------------------------------------------------------------
int MinSerial::read() {
  if (UCSR0A & (1 << RXC0)) return UDR0;
  return -1;
}
//------------------------------------------------------------------------------
void MinSerial::write(uint8_t b) {
  while (!(UCSR0A & (1 << UDRE0))) {}
  UDR0 = b;
}

Thanks for sharing, any idea what the RAM diff is on an UNO or 2009? - no test duino nearby :frowning: