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.

Svislý zásobník čtyř označených vrstev: přenos dole (USB nebo UART), rámcování nad ním (hlavička paketu s CRC), spolehlivost nad tím (sekvenční čísla, ACK / NAK, opětovné přenosy) a kanály nahoře (pojmenované logické streamy).

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ě.