12.2. สี่ชั้น¶
ไลบรารีโปรโตคอลถูกสร้างเป็น stack สี่ชั้น แต่ละชั้นแก้ปัญหาเดียวและสร้างบนชั้นที่อยู่ด้านล่าง บทที่เหลือจะเดิน stack จากล่างขึ้นบน
12.2.1. Transport¶
ที่ด้านล่างคือ pipe ไบต์ระหว่าง cam และ host ไลบรารีโปรโตคอลไม่สนใจว่าอันไหนรับส่งไบต์:
USB-CDC ผ่าน USB port ที่ cam เสียบอยู่ ตัวเลือกเริ่มต้นและมีแบนด์วิดท์สูงสุดสำหรับทุก cam
UART ผ่านคู่ GPIO pin บน cam ที่เชื่อมต่อกับ serial adapter บน host มีประโยชน์สำหรับการใช้งานแบบ headless ที่ USB port ยุ่งอยู่หรือเข้าถึงไม่ได้
หน้าที่เดียวของ transport คือ "ไบต์เข้า ไบต์ออก ตามลำดับ" ทุกอย่างเหนือชั้นนี้สมมติว่า transport ส่งไบต์ตามลำดับที่เขียน แต่อนุญาตให้ไบต์เองเสียหายหรือ link ขาดหายโดยสิ้นเชิง การสูญหายแบบ burst (ไบต์หายไปไม่กี่ตัว) และการขาดหายอย่างสะอาด (link หายไปทั้งหมดชั่วขณะแล้วกลับมา) ถูกจัดการในชั้นที่สูงขึ้น
12.2.2. Framing¶
ชั้นถัดไปขึ้นไปกำหนดโครงสร้างบน byte stream ทุกข้อความกลายเป็นแพ็กเก็ต -- ส่วนหัว 10 ไบต์ตามด้วย payload ตามด้วย trailer 4 ไบต์ ส่วนหัวบรรจุ:
sync word ขนาด 2 ไบต์ (
0xD5AA) ที่ให้ receiver หาจุดเริ่มต้นของแพ็กเก็ตได้ใหม่หลัง desyncหมายเลขลำดับ 1 ไบต์ ใช้โดยชั้น reliability
channel ID 1 ไบต์ ที่บอกว่าแพ็กเก็ตเป็นของ stream ลอจิกใด
ฟิลด์ flags 1 ไบต์ สำหรับบิต ACK / NAK / fragment / event
opcode 1 ไบต์ ที่แยกแยะคำสั่งโปรโตคอล คำสั่งระบบ และคำสั่งแชนเนล
ความยาว payload 2 ไบต์
CRC 2 ไบต์ ครอบคลุมแปดไบต์ส่วนหัวก่อนหน้า
payload ตามมา จากนั้น CRC 4 ไบต์ครอบคลุม payload เอง CRC สองตัวจับการเสียหายอย่างอิสระ: บิตที่พลิกในส่วนหัวจะทำให้ CRC ของส่วนหัวไม่ถูกต้อง และ receiver สามารถทิ้งแพ็กเก็ตได้โดยไม่ต้องอ่าน payload เลย
12.2.3. Reliability¶
ชั้น reliability แปลง "แพ็กเก็ตที่ อาจ มาถึง" เป็น "แพ็กเก็ตที่ มาถึงแล้ว" มันติดตามหมายเลขลำดับในส่วนหัว ขอให้อีกฝ่ายส่ง acknowledgement สำหรับทุกแพ็กเก็ตที่ต้องการ และส่งใหม่เมื่อ acknowledgement ไม่มาภายใน timeout โดยค่าเริ่มต้น retransmit timeout เริ่มที่ 500 ms และเพิ่มเป็นสองเท่าในแต่ละการลองใหม่ โดยลองสามครั้งก่อนยอมแพ้
พฤติกรรมเหล่านั้นแต่ละอย่างสามารถกำหนดค่าได้ในการเรียก protocol.init(): ACK สามารถปิดได้สำหรับ stream ทางเดียว การตรวจสอบ CRC สามารถข้ามได้บน transport ที่สะอาดสมบูรณ์ และพารามิเตอร์การส่งใหม่สามารถปรับแต่งสำหรับ link ที่ช้าหรือมีเวลาแฝงสูง
12.2.4. แชนเนล¶
ชั้นบนสุดคือสิ่งที่โค้ดแอปพลิเคชันเห็น แชนเนล คือ stream ลอจิกที่มีชื่อ ระบุด้วย channel ID ตั้งแต่ 0 ถึง 31 สูงสุด 32 แชนเนลสามารถอยู่ร่วมกันบน transport เดียว แต่ละอันเป็นอิสระจากอีกอัน ระบุด้วย ID ในส่วนหัวของทุกแพ็กเก็ต cam บูตพร้อมแชนเนล built-in สี่ตัว -- stdin, stdout, stream และ profile -- และโค้ดแอปพลิเคชันลงทะเบียนเพิ่มเติมโดยเรียก protocol.register() พร้อมคลาส Python
สี่ชั้นไม่ปะปนความกังวล Framing ไม่รู้เรื่องแชนเนล reliability ไม่รู้เรื่องเนื้อหาแพ็กเก็ต ชั้นแชนเนลไม่รู้ว่าไบต์มาอย่างไร การแยกส่วนนั้นคือเหตุผลที่การสลับ transport (USB เป็น UART เช่น) ไม่กระเพื่อมขึ้นสู่โค้ดแชนเนล และทำให้สามารถอธิบายบทที่เหลือทีละชั้นได้