12.2. Čtyři vrstvy¶
Knihovna protokolu je postavena jako zásobník čtyř vrstev, z nichž každá řeší jediný problém a staví na vrstvě pod sebou. Zbytek kapitoly prochází zásobník zdola nahoru.
12.2.1. Přenos¶
Úplně dole je bajtové potrubí mezi kamerou a hostitelem. Knihovně protokolu je jedno, který z nich bajty přenáší:
USB-CDC přes USB port, do něhož je kamera zapojena. Výchozí možnost s nejvyšší šířkou pásma pro každou kameru.
UART přes dvojici GPIO pinů na kameře připojených k sériovému adaptéru na hostiteli. Užitečné pro bezhlavá (headless) nasazení, kde je USB port obsazen nebo není fyzicky přístupný.
Jediným úkolem přenosu je „bajty jdou dovnitř, bajty vyjdou ven, v pořadí“. Vše nad touto vrstvou předpokládá, že přenos doručuje bajty v pořadí, v jakém byly zapsány, ale připouští, že samotné bajty mohou být poškozeny nebo že spoj může zcela vypadnout. Ztrátové dávky (chybí pár bajtů) i čisté výpadky (celý spoj na chvíli zmizí a pak se vrátí) se obě řeší výše.
12.2.2. Rámcování¶
Další vrstva nahoře vnucuje proudu bajtů strukturu. Každá zpráva se stává paketem – 10bajtová hlavička následovaná užitečnou zátěží a 4bajtovým zakončením. Hlavička nese:
2bajtové synchronizační slovo (
0xD5AA), které příjemci umožní znovu najít začátek paketu po ztrátě synchronizace.1bajtové sekvenční číslo používané vrstvou spolehlivosti.
1bajtové ID kanálu, které říká, kterému logickému streamu paket patří.
1bajtové pole příznaků pro bity ACK / NAK / fragment / event.
1bajtový operační kód, který rozlišuje příkazy protokolu, systémové příkazy a příkazy kanálu.
2bajtovou délku užitečné zátěže.
2bajtové CRC přes předchozích osm bajtů hlavičky.
Pak následuje užitečná zátěž a poté 4bajtové CRC přes samotnou užitečnou zátěž. Obě CRC zachycují poškození nezávisle: převrácený bit v hlavičce zneplatní CRC hlavičky a příjemce může paket zahodit, aniž by kdy potřeboval číst užitečnou zátěž.
12.2.3. Spolehlivost¶
Vrstva spolehlivosti mění „pakety, které možná dorazí“ na „pakety, které dorazily“. Sleduje sekvenční čísla v hlavičce, žádá druhou stranu o odeslání potvrzení pro každý paket, který je vyžaduje, a provádí opětovný přenos, pokud potvrzení nedorazí v rámci časového limitu. Ve výchozím nastavení začíná časový limit opětovného přenosu na 500 ms a při každém pokusu se zdvojnásobuje, se třemi opakováními, než to vzdá.
Každé z těchto chování je konfigurovatelné ve volání protocol.init(): ACK lze pro jednosměrné streamy vypnout, ověřování CRC lze na dokonale čistých přenosových kanálech přeskočit a parametry opětovného přenosu lze vyladit pro pomalé spoje nebo spoje s vysokou latencí.
12.2.4. Kanály¶
Nejvyšší vrstva je to, co vidí aplikační kód. Kanál je pojmenovaný logický stream identifikovaný ID kanálu od 0 do 31. Na jednom přenosovém kanálu může koexistovat až 32 kanálů; každý z nich je nezávislý na ostatních a je adresován svým ID v hlavičce každého paketu. Kamera startuje se čtyřmi vestavěnými kanály – stdin, stdout, stream a profile – a aplikační kód jich nad nimi registruje další voláním protocol.register() s třídou v Pythonu.
Čtyři vrstvy nemíchají odpovědnosti. Rámcování neví nic o kanálech; spolehlivost neví nic o obsahu paketů; vrstva kanálů neví, jak bajty dorazí. Právě tato separace je důvodem, proč se výměna přenosového kanálu (například z USB na UART) nepropíše nahoru do kódu kanálů, a právě ona umožňuje procházet zbytek kapitoly po jedné vrstvě.