12.1. De ce o bibliotecă de protocol¶
O pereche de cabluri și o rată baud sunt suficiente pentru a transfera octeți de la o cameră către un PC gazdă. Atât USB-CDC, cât și UART oferă programului camerei un flux în care write introduce octeți la un capăt, iar read îi extrage de la celălalt. Deci ce adaugă o bibliotecă de protocol peste asta?
Trei lucruri pe care ar trebui să le scrii singur, de fiecare dată, dacă ai încerca să construiești un canal serios cameră-gazdă direct pe octeți bruți:
Încadrarea în pachete (framing). Un flux de octeți nu are nicio structură inerentă. Camera scrie temp=42, iar gazda citește temp= plus o întrerupere care sosește mai târziu, apoi 42 plus următorul mesaj care începe cu humid=... deja amestecat în el. Octeții nu au limite. Orice legătură de gazdă cât de cât complexă ajunge să inventeze un marcaj – \n între mesaje, anteturi cu prefix de lungime, secvențe de eludare (escape) pentru sarcini utile binare – astfel încât receptorul să știe unde se termină un mesaj și unde începe următorul. Biblioteca de protocol îți oferă un format de pachet uniform cu un cuvânt de sincronizare și un câmp de lungime, iar receptorul nu trebuie niciodată să ghicească.
Fiabilitatea. USB-CDC nu pierde octeți în mod silențios în funcționarea normală, dar UART o face (când gazda nu deservește portul suficient de rapid), iar un cablu serial deconectat și reconectat poate lăsa o parte cu un pachet parțial. Lucrul corect de făcut este să detectezi coruperea, să ceri celeilalte părți să retransmită și să predai codului aplicației doar mesajele care au ajuns intacte. Biblioteca de protocol face asta pentru fiecare pachet cu un CRC și confirmări (ACK) per pachet – activate în mod implicit; aplicația nu vede retransmisiile.
Multiplexarea. Există exact un singur port USB-CDC între cameră și gazdă. Dacă camera transmite o imagine în flux și gazda îi trimite configurație și IDE-ul citește stdout pentru ieșirea print, toate cele trei schimburi trebuie să partajeze acel flux unic de octeți. Biblioteca de protocol oferă fiecărui flux independent un număr de canal, permite camerei să înregistreze o clasă Python pentru fiecare și împiedică citirile gazdei de pe fiecare canal să interfereze cu celelalte. Din punctul de vedere al codului aplicației, fiecare canal arată ca propria sa legătură privată.
12.1.1. De ce să nu o scrii singur¶
Poți. Sunt câteva săptămâni de muncă pentru a face toate cele trei lucruri corecte pe o linie serială și încă alte câteva săptămâni pentru a face ca încadrarea în pachete să gestioneze curat recuperarea la conectare la cald (hot-plug), ca retransmisiile să funcționeze fără a irosi energie pe schimburi dus-întors și ca multiplexorul să supraviețuiască citirilor parțiale fără a corupe octeții unui canal în ai altuia.
Biblioteca de protocol a făcut deja acea muncă, a fost validată pe fiecare cameră acceptată și are biblioteci corespondente pe partea gazdei care vorbesc același format de transmisie. Folosirea ei înseamnă că pe partea camerei codul este o singură clasă mică per canal, iar pe partea gazdei codul este un obiect Camera cu metodele channel_read și channel_write. Spațiul mental economisit se îndreaptă către ceea ce face efectiv aplicația.
Acest capitol predă protocolul de la zero: formatul de transmisie, regulile de încadrare în pachete, mecanismul de fiabilitate, modelul de canale și, în final, clasele Python de la ambele capete. Până la final, cititorul poate construi o interfață grafică de gazdă care comunică cu camera, un script care transmite în flux date de senzor de la cameră la laptop și genul de instrument interactiv de calibrare care este inclus în openmv-projects/tools/.