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

Abstract

The Serial.flush()/HardwareSerial::flush() sends all data in the serial transmit buffer.

Souce Code

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
void HardwareSerial::flush()
{
  // If we have never written a byte, no need to flush. This special
  // case is needed since there is no way to force the TXC (transmit
  // complete) bit to 1 during initialization
  if (!_written)
    return;
 
  while (bit_is_set(*_ucsrb, UDRIE0) || bit_is_clear(*_ucsra, TXC0)) {
    if (bit_is_clear(SREG, SREG_I) && bit_is_set(*_ucsrb, UDRIE0))
    // Interrupts are globally disabled, but the DR empty
    // interrupt should be enabled, so poll the DR empty flag to
    // prevent deadlock
    if (bit_is_set(*_ucsra, UDRE0))
      _tx_udr_empty_irq();
  }
  // If we get here, nothing is queued anymore (DRIE is disabled) and
  // the hardware finished tranmission (TXC is set).
}

No inputs, no outputs.

1
2
void HardwareSerial::flush()
{

If the _written is 0, it means no HardwareSerial::write() is used, does nothing and returns.

3
4
5
6
7
// If we have never written a byte, no need to flush. This special
// case is needed since there is no way to force the TXC (transmit
// complete) bit to 1 during initialization
if (!_written)
  return;

If UDRIE0 bit of _ucsrb(UCSR0B) is 1 or TXC0 bit of _ucsra(UCSR0A) is 0, the transmit buffer is not empty. Wait for the buffer to become empty.

The bit_is_set() and bit_is_clear() are macros to check the specified bit.

 9
10
11
12
13
14
15
16
17
18
19
  while (bit_is_set(*_ucsrb, UDRIE0) || bit_is_clear(*_ucsra, TXC0)) {
    if (bit_is_clear(SREG, SREG_I) && bit_is_set(*_ucsrb, UDRIE0))
    // Interrupts are globally disabled, but the DR empty
    // interrupt should be enabled, so poll the DR empty flag to
    // prevent deadlock
    if (bit_is_set(*_ucsra, UDRE0))
      _tx_udr_empty_irq();
  }
  // If we get here, nothing is queued anymore (DRIE is disabled) and
  // the hardware finished tranmission (TXC is set).
}

If the SREG_I bit of SREG is 0 and the UDRIE0 bit of _ucsrb(UCSR0B) is 1, it means interrupts are globally disabled. In case of UDRE0 bit of _ucsra(UCSR0A) is 1, the transmit buffer is not full, calls HardwareSerial::_tx_udr_empty_irq() to send data.

After the while loop, all data has been sent.

Version

Arduino 1.8.13

Last Update

June 19, 2020

inserted by FC2 system