Pages: [1]   Go Down
Author Topic: Over 600 bytes of RAM for Serial on a Mega, Gasp!  (Read 1225 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Edison Member
*
Karma: 63
Posts: 1598
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
Code:
#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
Code:
#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
Code:
#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;
}
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 211
Posts: 13471
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Pages: [1]   Go Up
Jump to: