Arduino จัดการกับบัฟเฟอร์ล้นแบบอนุกรมอย่างไร


27

Arduino จัดการกับบัฟเฟอร์ล้นแบบอนุกรมอย่างไร มันทิ้งข้อมูลที่เข้ามาใหม่ล่าสุดหรือเก่าที่สุดหรือไม่? บัฟเฟอร์สามารถเก็บได้กี่ไบต์?

serial 

คำตอบ:


13

สำหรับฮาร์ดแวร์พอร์ตอนุกรมคุณสามารถดูได้ใน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 ไบต์ ในทั้งสองกรณีมันจะหยุดความพยายามที่จะแทรกข้อมูลที่ได้รับลงในคิวเมื่อมันเต็มดังนั้นคุณสามารถรับข้อมูลมิกซ์กับข้อมูลเก่าและใหม่ขึ้นอยู่กับวิธีที่คุณดึงข้อมูลจากคิว

เป็นการดีที่สุดที่จะต้องแน่ใจว่าบัฟเฟอร์ได้รับการอบในลักษณะพร้อมท์เสมอเพื่อหลีกเลี่ยงการเติมบัฟเฟอร์ อาจดูตัวจับเวลาและการใช้งานเครื่องสถานะง่าย ๆ หากปัญหาของคุณเกี่ยวข้องกับโค้ดอื่น ๆ ที่บล็อกลูปหลัก


ฉันได้รับความประทับใจว่าถ้าฉันส่งข้อมูลไปยัง Arduino และไม่มี "puller" ของข้อมูลที่ใช้งานอยู่ในด้าน Arduino แล้วถ้ามีข้อมูลเข้ามามากกว่าที่จะใส่ลงไปในบัฟเฟอร์มันจะถูกทิ้ง คุณยืนยันได้ไหม ฉันสันนิษฐานอย่างไร้เดียงสาว่าตัวส่งสัญญาณจะบล็อกจนกว่าจะมีที่ว่างสำหรับเก็บข้อมูล
Kolban

ฉันเพิ่งดูรหัสทั้งหมดนั้น (ภายใต้ / usr / share / arduino / hardware / arduino / core / arduino / HardwareSer‌ ial.cpp) และสามารถยืนยันสิ่งที่คุณเขียนที่นี่ สิ่งเดียวที่ฉันจะเพิ่มคือเนื่องจาก SRAM คือ 2K (RAMEND> 1,000) ดังนั้นหากคำสั่งจะใช้ 64 แทนที่จะเป็น 16 บนนาโนหรือ Uno ดังนั้นหากใครต้องการที่จะขยายขนาดของบัฟเฟอร์แหวนที่จะเป็นสถานที่ที่จะเปลี่ยนมัน
SDsolar

5

การได้รับ

คุณสามารถดูได้จากแหล่งที่มาของ 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


ฉันเชื่อว่าคุณออกตามลำดับความสำคัญ: ที่ 9600 บอดคุณจะได้รับไบต์ทุก ๆ ~ 0.1 ms ดังนั้นใช้เวลาเพียง 6.6 ms ในการเติมบัฟเฟอร์
Eric Dand

1
ที่ 9600 baud คุณจะได้รับ 9600 บิตต่อวินาที เนื่องจากแต่ละไบต์คือ 10 บิต (8 data + 1 start bit + 1 stop bit) ดังนั้นคุณจะได้รับ 960 bytes ต่อวินาที 1/960 = 0.001042 s- นั่นคือหนึ่งไบต์ทุก 1.04 มิลลิวินาที
Nick Gammon

อ่าแน่นอนไม่ไบต์! ขอบคุณสำหรับการแก้ไข
Eric Dand

ดังนั้น Nick โปรดตอบคำถามนี้สำหรับฉัน: ถ้าฉันมี Pi ที่ใช้ Python นั่งอยู่ที่ ser.readline () รออินพุตเป็นตัวบันทึกข้อมูลและมันถูกป้อนผ่าน serial โดย Arduino โดยการอ่านจากนั้นส่งเป็นแบทช์พร้อมแท็บ delimeters จากนั้นใช้การหน่วงเวลา (120000) ดังนั้นแบทช์จะเข้ามาในทุก ๆ สองนาที Python อวัยวะภายในอาจจะอ่านได้ทันทีในตัวละครแต่ละตัวจนกว่าจะพบบรรทัดใหม่ ณ จุดที่มันปล่อยสายทั้งหมดเป็นค่าตอบแทน ดังนั้นฉันไม่ต้องกังวลเกี่ยวกับขนาดของบัฟเฟอร์ Arduino แม้ว่าฉันจะส่ง 80 ตัวอักษรทั้งหมดใช่มั้ย? นั่นจะเป็นข้อสันนิษฐานที่ดีหรือไม่?
SDsolar

ใช่ขนาดบัฟเฟอร์ส่งจะไม่สำคัญในสถานการณ์นี้ บัฟเฟอร์ขนาดเล็กจะชะลอการส่ง (เล็กน้อย) แต่ถ้าคุณใช้เวลานานเกินไปคุณจะไม่สนใจ
Nick Gammon
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.