12.1. Waarom een protocolbibliotheek¶
Een paar kabels en een baudrate zijn genoeg om bytes van een cam naar een host-pc te verplaatsen. USB-CDC en UART geven het cam-programma allebei een stroom waarbij write aan de ene kant bytes erin stopt en read ze er aan de andere kant uithaalt. Wat voegt een protocolbibliotheek daar dan bovenop toe?
Drie dingen die je telkens zelf zou moeten schrijven als je probeerde een serieus kanaal tussen cam en host rechtstreeks op ruwe bytes te bouwen:
Framing. Een bytestroom heeft geen inherente structuur. De cam schrijft temp=42 en de host leest temp= plus een interrupt die later binnenkomt, dan 42 plus het volgende bericht dat begint met humid=... en er al tegenaan loopt. Bytes hebben geen grenzen. Elke niet-triviale host-verbinding eindigt ermee dat er een markering wordt verzonnen – \n tussen berichten, length-prefix-headers, escape-sequenties voor binaire payloads – zodat de ontvanger weet waar het ene bericht eindigt en het volgende begint. De protocolbibliotheek geeft je een uniform pakketformaat met een sync-woord en een lengteveld, zodat de ontvanger nooit hoeft te gokken.
Betrouwbaarheid. USB-CDC verliest in normaal bedrijf geen bytes in stilte, maar UART wel (wanneer de host de poort niet snel genoeg bedient), en een seriële kabel die wordt losgekoppeld en weer aangesloten kan één kant met een onvolledig pakket achterlaten. Het juiste is om de corruptie te detecteren, de andere kant om hertransmissie te vragen en applicatiecode alleen ooit berichten te overhandigen die intact zijn aangekomen. De protocolbibliotheek doet dat voor elk pakket met een CRC en bevestigingen per pakket – standaard ingeschakeld; de applicatie ziet de nieuwe pogingen niet.
Multiplexing. Er is precies één USB-CDC-poort tussen de cam en de host. Als de cam een afbeelding streamt en de host er configuratie naartoe stuurt en de IDE stdout leest voor print-uitvoer, dan moeten alle drie de uitwisselingen die ene bytestroom delen. De protocolbibliotheek geeft elke onafhankelijke stroom een kanaalnummer, laat de cam voor elk ervan een Python-klasse registreren, en zorgt ervoor dat de reads van de host op elk kanaal elkaar niet storen. Vanuit de applicatiecode ziet elk kanaal eruit als zijn eigen privéverbinding.
12.1.1. Waarom je dat niet zelf zou schrijven¶
Dat kan. Het kost een paar weken werk om alle drie correct te krijgen op een seriële lijn, en nog een paar weken om de framing netjes hot-plug-herstel te laten afhandelen, de hertransmissies te laten werken zonder energie te verspillen aan round-trips, en de multiplexer onvolledige reads te laten overleven zonder de bytes van het ene kanaal in die van het andere te verminken.
De protocolbibliotheek heeft dat werk al gedaan, is gevalideerd op elke ondersteunde cam, en heeft bijpassende bibliotheken aan de host-kant die hetzelfde wire-formaat spreken. Het gebruiken betekent dat de cam-kantcode één kleine klasse per kanaal is en de host-kantcode een Camera-object met channel_read- en channel_write-methoden. De vrijgekomen mentale ruimte gaat naar wat de applicatie daadwerkelijk doet.
Dit hoofdstuk leert het protocol vanaf de grond op: het wire-formaat, de framing-regels, het betrouwbaarheidsmechanisme, het kanaalmodel, en ten slotte de Python-klassen aan beide kanten. Aan het einde kan de lezer een host-GUI bouwen die met de cam praat, een script dat sensorgegevens van de cam naar een laptop streamt, en het soort interactieve kalibratietool dat wordt meegeleverd in openmv-projects/tools/.