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;
}