概要
_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