Code:
// CPU: ATMega2560 (RN-Board) @ 16 MHz
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "header/glob_type.h"
#include "header/glob_errors.h"
#include "header/glob_defs.h"

// defines
#define BUFSIZE2_IN   16
#define BUFSIZE2_OUT  16


// types
typedef struct
{
  ui8_t volatile count;       // # Zeichen im Puffer
  ui8_t size;                 // Puffer-Größe
  ui8_t *pread;               // Lesezeiger
  ui8_t *pwrite;              // Schreibzeiger
  ui8_t read2end, write2end;  // # Zeichen bis zum Überlauf Lese-/Schreibzeiger
} fifo_t;


// Function Prototypes:
void     USART_Init(ui8_t chan, ui32_t baud);
void     USART_PutS(ui8_t channel, const char *s);
ui8_t    USART_PutC (ui8_t channel, const ui8_t c);
void     FIFO_Init (fifo_t *f, ui8_t *buffer, const ui8_t size);
e_errors FIFO_Put (fifo_t *f, const ui8_t data);


// Global variables
ui8_t  inbuf2[BUFSIZE2_IN];
ui8_t  outbuf2[BUFSIZE2_OUT];
fifo_t infifo2;
fifo_t outfifo2;

int volatile received;


// Inline Functions
static inline e_errors
_inline_fifo_put (fifo_t *f, const ui8_t data)
{
  if (f->count >= f->size)
  {
    return ERR_BUFFER_FULL;
  }

  ui8_t * pwrite = f->pwrite;

  *(pwrite++) = data;

  ui8_t write2end = f->write2end;

  if (--write2end == 0)
  {
    write2end = f->size;
    pwrite -= write2end;
  }

  f->write2end = write2end;
  f->pwrite = pwrite;

  ui8_t sreg = SREG;
  cli();
  f->count++;
  SREG = sreg;

  return ERR_OK;
}


static inline ui8_t
_inline_fifo_get (fifo_t *f)
{
  ui8_t *pread = f->pread;
  ui8_t data = *(pread++);
  ui8_t read2end = f->read2end;

  if (--read2end == 0)
  {
    read2end = f->size;
    pread -= read2end;
  }

  f->pread = pread;
  f->read2end = read2end;

  ui8_t sreg = SREG;
  cli();
  f->count--;
  SREG = sreg;

  return data;
}



// Main
int main (void)
{
  received=0;
  int i;
  char buffer [33];
      USART_Init(2, 9600L);             // USART Channel 2 (Onboard/TTL)
  sei();

  while(1)
  {
    i=itoa (received,buffer,10);
    USART_PutS(2, buffer);
    USART_PutS(2, "Test\r\n");
    _delay_ms(250);
  }
  return 0;
}



// Functions
void USART_Init(ui8_t chan, ui32_t baud)
{
  ui8_t sreg = SREG;
  ui16_t ubrr;
  switch(chan)
  {
    case 2:
      ubrr = (ui16_t) ((ui32_t) F_CPU / (16 * baud) - 1);
      UBRR2H = (ui8_t) (ubrr>>8);
      UBRR2L = (ui8_t) (ubrr);
      cli();
      UCSR2B = (1 << RXEN2) | (1 << TXEN2) | (1 << RXCIE2);
      UCSR2C = (1 << UMSEL21) | (1 << UCSZ21) | (1 << UCSZ20);
      do
      {
        UDR2;
      } while (UCSR2A & (1 << RXC2));

      UCSR2A = (1 << RXC2) | (1 << TXC2);
      SREG = sreg;
      FIFO_Init (&infifo2,  inbuf2,  BUFSIZE2_IN);
      FIFO_Init (&outfifo2, outbuf2, BUFSIZE2_OUT);
      break;
  } // END:switch(chan)
}

void USART_PutS(ui8_t channel, const char *s)
{
  do
  {
    USART_PutC(channel, *s);
  } while (*s++);
}

ui8_t USART_PutC (ui8_t channel, const ui8_t c)
{
  ui8_t ret = 0;
  switch(channel)
  {
    case 2:
      ret = FIFO_Put(&outfifo2,c);
      UCSR2B |= (1 << UDRIE2);
      break;
  }
  return ret;
}


void FIFO_Init (fifo_t *f, ui8_t *buffer, const ui8_t size)
{
  f->count = 0;
  f->pread = f->pwrite = buffer;
  f->read2end = f->write2end = f->size = size;
}


e_errors FIFO_Put (fifo_t *f, const ui8_t data)
{
  return _inline_fifo_put (f, data);
}


// Interrupts:
ISR(USART2_RX_vect)
{
  _inline_fifo_put (&infifo2,UDR2);
  received++;
}

SIGNAL(SIG_USART2_DATA)
{
  if (outfifo2.count > 0)
  {
    UDR2 = _inline_fifo_get (&outfifo2);
  } else {
    UCSR2B &= ~(1 << UDRIE2);
  }
}
und ich verwende die header-Dateien von jaecko