Arduinoはシリアルバッファオーバーフローをどのように処理しますか?最新の受信データまたは最も古い受信データを破棄しますか?バッファーは何バイト保持できますか?
Arduinoはシリアルバッファオーバーフローをどのように処理しますか?最新の受信データまたは最も古い受信データを破棄しますか?バッファーは何バイト保持できますか?
回答:
ハードウェアシリアルポートの場合、HardwareSerial.cppで、特定のAVRで使用可能なRAMの量に応じてバッファーサイズが異なることがわかります。
#if (RAMEND < 1000)
#define SERIAL_BUFFER_SIZE 16
#else
#define SERIAL_BUFFER_SIZE 64
#endif
SoftwareSerial.hのソフトウェアシリアルポートの場合、受信バッファサイズ_SS_MAX_RX_BUFF
は64バイトとして定義されます。どちらの場合も、キューがいっぱいになると受信データをキューに挿入しようとするのを停止するため、キューからデータを取得する方法に応じて、古いデータと新しいデータを混在させることができます。
理想的には、バッファがいっぱいにならないように、バッファを常にプロンプト方式で空にすることをお勧めします。問題がメインループをブロックしている他のコードに関連している場合は、タイマーと単純なステートマシンの実装をご覧ください。
HardwareSerialのソースから、着信バイトでリングバッファがいっぱいであることが検出されると、破棄されることがわかります。
inline void store_char(unsigned char c, ring_buffer *buffer)
{
int i = (unsigned int)(buffer->head + 1) % SERIAL_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 != buffer->tail) {
buffer->buffer[buffer->head] = c;
buffer->head = i;
}
}
Arduinoにデータを送信し、Arduino側にアクティブな「プル」データがない場合、バッファに収まらないほど多くのデータが到着すると破棄されるという印象を受けます。確認できますか?
はい、破棄されます。独自に実装しない限り、ソフトウェアまたはハードウェアのフロー制御はありません。
ただし、64バイトのバッファーを使用し、(たとえば)9600ボーでデータを受信すると、1.04ミリ秒ごとに1バイトを取得するため、バッファーがいっぱいになるのに66.6ミリ秒かかります。16 MHzプロセッサでは、バッファがいっぱいにならないように十分な頻度でバッファをチェックできるはずです。あなたが本当にしなければならないのは、すぐに処理したくない場合、HardwareSerialバッファから自分のバッファにデータを移動することです。
#if (RAMEND < 1000)
1000バイト以上のRAMを搭載したプロセッサが64バイトのバッファを取得し、16バイトバッファを取得するRAMが少ないプロセッサを確認できます。
書き込むデータは、同じサイズのバッファ(16または64バイト)に配置されます。バッファが次のバイトをシリアルポートから送信するための割り込みを待機しているコード「ブロック」をいっぱいにする場合に送信する場合。
割り込みがオフになっている場合、これは決して起こりません。したがって、割り込みサービスルーチン内でシリアル印刷を行いません。
1/960 = 0.001042 s
-1.04ミリ秒ごとに1バイトです。