Arduino จัดการกับบัฟเฟอร์ล้นแบบอนุกรมอย่างไร มันทิ้งข้อมูลที่เข้ามาใหม่ล่าสุดหรือเก่าที่สุดหรือไม่? บัฟเฟอร์สามารถเก็บได้กี่ไบต์?
Arduino จัดการกับบัฟเฟอร์ล้นแบบอนุกรมอย่างไร มันทิ้งข้อมูลที่เข้ามาใหม่ล่าสุดหรือเก่าที่สุดหรือไม่? บัฟเฟอร์สามารถเก็บได้กี่ไบต์?
คำตอบ:
สำหรับฮาร์ดแวร์พอร์ตอนุกรมคุณสามารถดูได้ในHardwareSerial.cppว่าขนาดบัฟเฟอร์แตกต่างกันไปขึ้นอยู่กับจำนวน RAM ที่มีอยู่ใน AVR เฉพาะ:
#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 และไม่มี "puller" ของข้อมูลที่ใช้งานอยู่ทางด้าน Arduino แล้วถ้ามีข้อมูลมามากกว่าที่จะใส่ลงไปในบัฟเฟอร์มันจะถูกทิ้ง คุณยืนยันได้ไหม
ใช่มันจะถูกทิ้ง ไม่มีการควบคุมการไหลของซอฟต์แวร์หรือฮาร์ดแวร์เว้นแต่ว่าคุณจะใช้งานของคุณเอง
อย่างไรก็ตามด้วยบัฟเฟอร์ 64- บิตและรับข้อมูลที่ (พูด) 9600 baud คุณจะได้รับหนึ่งไบต์ทุก ๆ 1.04 ms และใช้เวลา 66.6 ms ในการเติมบัฟเฟอร์ สำหรับโปรเซสเซอร์ 16 MHz คุณควรจะสามารถตรวจสอบบัฟเฟอร์ได้บ่อยครั้งพอที่จะไม่เต็ม สิ่งที่คุณต้องทำคือย้ายข้อมูลจากบัฟเฟอร์ HardwareSerial ไปยังของคุณเองหากคุณไม่ต้องการประมวลผลทันที
คุณสามารถดูได้จากการ#if (RAMEND < 1000)
ตรวจสอบว่าตัวประมวลผลที่มีหน่วยความจำ 1,000+ ไบต์ได้รับบัฟเฟอร์ 64- ไบต์ตัวใดตัวหนึ่งจะน้อยกว่า RAM ที่ได้รับบัฟเฟอร์ขนาด 16 ไบต์
ข้อมูลที่คุณเขียนจะถูกวางในบัฟเฟอร์ขนาดเดียวกัน (16 หรือ 64 ไบต์) ในกรณีของการส่งถ้าบัฟเฟอร์เติมรหัส "บล็อก" ที่รอให้อินเตอร์รัปต์ส่งไบต์ถัดไปออกจากพอร์ตอนุกรม
หากมีการปิดอินเทอร์รัปต์สิ่งนี้จะไม่เกิดขึ้นดังนั้นคุณไม่ต้องพิมพ์เอกสารอนุกรมภายใน Interrupt Service Routine
1/960 = 0.001042 s
- นั่นคือหนึ่งไบต์ทุก 1.04 มิลลิวินาที