12.1. מדוע ספריית פרוטוקול¶
זוג כבלים וקצב בָּאוּד (baud rate) מספיקים כדי להעביר בייטים ממצלמה אל מחשב מארח. גם USB-CDC וגם UART מספקים לתוכנית של המצלמה זרם שבו write מכניס בייטים בקצה אחד ו-read מוציא אותם בקצה השני. אז מה ספריית פרוטוקול מוסיפה מעל לזה?
שלושה דברים שהיית צריך לכתוב בעצמך, בכל פעם מחדש, אילו ניסית לבנות ערוץ רציני בין מצלמה למארח ישירות על בייטים גולמיים:
מסגור (Framing). לזרם בייטים אין מבנה מובנה. המצלמה כותבת temp=42 והמארח קורא temp= ועוד פסיקה שמגיעה מאוחר יותר, ואז 42 ועוד ההודעה הבאה שמתחילה ב-humid=... שכבר נכנסת לתוכה. לבייטים אין גבולות. כל קישור מארח לא טריוויאלי מסתיים בהמצאת איזשהו סמן – \n בין הודעות, כותרות עם תחילית אורך, רצפי בריחה (escape) לעומסים בינאריים – כדי שהמקבל יידע היכן הודעה אחת מסתיימת והבאה מתחילה. ספריית הפרוטוקול נותנת לך פורמט מנה אחיד עם מילת סנכרון ושדה אורך, והמקבל לעולם אינו צריך לנחש.
אמינות. USB-CDC אינו מאבד בייטים בשקט בפעולה רגילה, אך UART כן (כאשר המארח אינו מטפל ביציאה במהירות מספקת), וכבל טורי שנותק והוחזר עלול להשאיר צד אחד עם מנה חלקית. הדבר הנכון לעשות הוא לזהות את ההשחתה, לבקש מהצד השני לשדר מחדש, ולמסור לקוד היישום רק הודעות שהגיעו שלמות. ספריית הפרוטוקול עושה זאת עבור כל מנה באמצעות CRC ואישורים (acknowledgements) לכל מנה – מופעל כברירת מחדל; היישום אינו רואה את השידורים החוזרים.
ריבוב (Multiplexing). קיימת בדיוק יציאת USB-CDC אחת בין המצלמה למארח. אם המצלמה מזרימה תמונה וגם המארח שולח לה תצורה וגם ה-IDE קורא את stdout עבור פלט print, כל שלוש החליפות חייבות לחלוק את אותו זרם בייטים יחיד. ספריית הפרוטוקול נותנת לכל זרם עצמאי מספר ערוץ, מאפשרת למצלמה לרשום מחלקת Python עבור כל אחד מהם, ומונעת מקריאות המארח בכל ערוץ להפריע זו לזו. מנקודת המבט של קוד היישום, כל ערוץ נראה כקישור פרטי משלו.
12.1.1. מדוע לא לכתוב זאת בעצמך¶
אתה יכול. דרושים כמה שבועות עבודה כדי שכל השלושה יעבדו נכון על קו טורי, ועוד כמה שבועות כדי שהמסגור יטפל בנקיות בהתאוששות מחיבור-חם (hot-plug), שהשידורים החוזרים יעבדו בלי לבזבז אנרגיה על הלוך-ושוב, ושהמרבב ישרוד קריאות חלקיות מבלי להשחית את הבייטים של ערוץ אחד אל תוך ערוץ אחר.
ספריית הפרוטוקול כבר ביצעה את העבודה הזו, אומתה על כל מצלמה נתמכת, ויש לה ספריות תואמות בצד המארח שמדברות באותו פורמט תיל. שימוש בה משמעו שקוד צד-המצלמה הוא מחלקה קטנה אחת לכל ערוץ, וקוד צד-המארח הוא אובייקט Camera עם המתודות channel_read ו-channel_write. המרחב המנטלי שנחסך מופנה לכל מה שהיישום באמת עושה.
פרק זה מלמד את הפרוטוקול מהיסוד: פורמט התיל, כללי המסגור, מנגנון האמינות, מודל הערוצים, ולבסוף מחלקות ה-Python בשני הקצוות. בסופו של דבר הקורא יוכל לבנות GUI מארח שמדבר עם המצלמה, סקריפט שמזרים נתוני חיישן מהמצלמה למחשב נייד, וכלי כיול אינטראקטיבי מהסוג שנשלח ב-openmv-projects/tools/.