Bagaimana Arduino menangani buffer overflow serial? Apakah itu membuang data yang masuk terbaru atau yang tertua? Berapa banyak byte yang bisa ditampung oleh buffer?
Bagaimana Arduino menangani buffer overflow serial? Apakah itu membuang data yang masuk terbaru atau yang tertua? Berapa banyak byte yang bisa ditampung oleh buffer?
Jawaban:
Untuk port serial perangkat keras Anda dapat melihat di HardwareSerial.cpp bahwa ukuran buffer bervariasi tergantung pada jumlah RAM yang tersedia pada AVR tertentu:
#if (RAMEND < 1000)
#define SERIAL_BUFFER_SIZE 16
#else
#define SERIAL_BUFFER_SIZE 64
#endif
Untuk port serial perangkat lunak di SoftwareSerial.h ukuran buffer penerima _SS_MAX_RX_BUFF
didefinisikan sebagai 64 byte. Dalam kedua kasus itu berhenti mencoba untuk memasukkan data yang diterima ke dalam antrian ketika sudah penuh, sehingga Anda bisa mendapatkan campuran ke data lama dan baru tergantung pada bagaimana Anda mengambil data dari antrian.
Idealnya akan lebih baik untuk memastikan buffer selalu dikosongkan secara cepat untuk menghindari pengisian buffer. Mungkin lihat timer dan menerapkan mesin negara sederhana jika masalah Anda terkait dengan kode lain memblokir loop utama.
Anda dapat melihat dari sumber HardwareSerial bahwa jika byte yang masuk menemukan buffer cincin penuh, itu dibuang:
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;
}
}
Saya mendapat kesan bahwa jika saya mengirimkan data ke Arduino dan tidak memiliki "penarik" data aktif di sisi Arduino maka jika lebih banyak data yang masuk daripada yang bisa muat dalam buffer, itu akan dibuang. Bisakah Anda mengonfirmasi itu?
Ya itu akan dibuang. Tidak ada kontrol aliran perangkat lunak atau perangkat keras, kecuali jika Anda menerapkan sendiri.
Namun dengan buffer 64-byte, dan menerima data pada (katakanlah) 9600 baud, Anda mendapatkan satu byte setiap 1,04 ms, dan dengan demikian dibutuhkan 66,6 ms untuk mengisi buffer. Pada prosesor 16 MHz Anda harus dapat memeriksa buffer cukup sering sehingga tidak mengisi. Yang harus Anda lakukan adalah memindahkan data dari buffer HardwareSerial ke milik Anda sendiri, jika Anda tidak ingin memprosesnya sekarang.
Anda dapat melihat dari #if (RAMEND < 1000)
cek bahwa prosesor dengan 1000+ byte RAM mendapatkan buffer 64-byte, yang akan lebih sedikit RAM mendapatkan buffer 16-byte.
Data yang Anda tulis ditempatkan di buffer berukuran sama (16 atau 64 byte). Dalam hal pengiriman jika buffer mengisi kode "blok" menunggu interupsi untuk mengirim byte berikutnya keluar dari port serial.
Jika interupsi dimatikan, ini tidak akan pernah terjadi, jadi Anda tidak melakukan pencetakan Serial di dalam Rutin Layanan Interupsi.
1/960 = 0.001042 s
- yaitu satu byte setiap 1,04 ms.