HardwareSerial::_rx_complete_irq()

概要

_rx_complete_irq()は、シリアル通信でデータを受信したときに起動される割り込みハンドラの、USART_RX_vectから呼び出され、ATmega328Pの受信バッファからArduinoの受信バッファにデータを移動します。

ソースコード

_rx_complete_irq()は、hardware/arduino/avr/cores/arduino/HardwareSerial_private.hに定義されています。以下に全ソースコードを示します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
void HardwareSerial::_rx_complete_irq(void)
{
  if (bit_is_clear(*_ucsra, UPE0)) {
    // No Parity error, read byte and store it in the buffer if there is
    // room
    unsigned char c = *_udr;
    rx_buffer_index_t i = (unsigned int)(_rx_buffer_head + 1) % SERIAL_RX_BUFFER_SIZE;
 
    // if we should be storing the received character into the location
    // just before the tail (meaning that the head would advance to the
    // current location of the tail), we're about to overflow the buffer
    // and so we don't write the character or advance the head.
    if (i != _rx_buffer_tail) {
      _rx_buffer[_rx_buffer_head] = c;
      _rx_buffer_head = i;
    }
  } else {
    // Parity error, read byte but discard it
    *_udr;
  };
}

入力はありません。戻り値もありません。

1
2
void HardwareSerial::_rx_complete_irq(void)
{

bit_is_clear()で、_ucsra(UCSR0A)レジスタのUPE0が0かどうかを判定します。0のときはパリティエラーがない状態なので、データを読み込みます。

 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
if (bit_is_clear(*_ucsra, UPE0)) {
  // No Parity error, read byte and store it in the buffer if there is
  // room
  unsigned char c = *_udr;
  rx_buffer_index_t i = (unsigned int)(_rx_buffer_head + 1) % SERIAL_RX_BUFFER_SIZE;
 
  // if we should be storing the received character into the location
  // just before the tail (meaning that the head would advance to the
  // current location of the tail), we're about to overflow the buffer
  // and so we don't write the character or advance the head.
  if (i != _rx_buffer_tail) {
    _rx_buffer[_rx_buffer_head] = c;
    _rx_buffer_head = i;
  }

_udr(UDR0)は、受信したデータが入っているレジスタです。

_rx_buffer_headは、今受信したデータを格納する予定の位置を示す変数です。この次に受信するデータを格納する位置を求めて(+1する)、その位置が、バッファの一番古いデータを格納する_rx_buffer_tailと同じであれば、今受信したデータはバッファに格納せずに破棄されます。つまり、最低1バイトは、利用せずに開けておきます。バッファに余裕がある場合は、バッファにデータを格納し、_rx_buffer_headを更新します。

17
18
19
20
21
  } else {
    // Parity error, read byte but discard it
    *_udr;
  };
}

パリティエラーが発生したときは、_udrを読み出し、何もせずに破棄します。

バージョン

Arduino AVR Boards 1.8.6

最終更新日

March 21, 2023

inserted by FC2 system