Playing with Arduino
A page to record my playing with Arduino
HardwareSerial::read()

Abstract

The Serial.read()/HardwareSerial::read() reads data from receive buffer.

Source Code

The HardwareSerial::read() is defined in hardware/arduino/avr/cores/arduino/HardwareSerial.cpp as below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
int HardwareSerial::read(void)
{
  // if the head isn't ahead of the tail, we don't have any characters
  if (_rx_buffer_head == _rx_buffer_tail) {
    return -1;
  } else {
    unsigned char c = _rx_buffer[_rx_buffer_tail];
    _rx_buffer_tail = (rx_buffer_index_t)(_rx_buffer_tail + 1) % SERIAL_RX_BUFFER_SIZE;
    return c;
  }
}

No inputs, output is int.

1
2
int HardwareSerial::read(void)
{

If the head and tail of the buffer is same, there is no data in the buffer, returns -1.

3
4
5
6
// if the head isn't ahead of the tail, we don't have any characters
if (_rx_buffer_head == _rx_buffer_tail) {
  return -1;
} else {

If the head and tail of the buffer is not same, reads the oldest data which is stored in buffer[tail], advance _rx_buffer_tail one byte, then return the data.

 6
 7
 8
 9
10
11
} else {
    unsigned char c = _rx_buffer[_rx_buffer_tail];
    _rx_buffer_tail = (rx_buffer_index_t)(_rx_buffer_tail + 1) % SERIAL_RX_BUFFER_SIZE;
    return c;
  }
}

Because the receive buffer is a ring buffer, if the tail gets to the last of the buffer, it should go back to the head of the buffer. To do that, add 1 to tail then get reminder of division by buffer size(SERIAL_RX_BUFFER_SIZE).

To put the received data to the buffer, an interrupt handler named USART_RX_vect is used.

Version

Arduino 1.8.13

Last Update

June 19, 2020

inserted by FC2 system