12.6. Imenovani kanali¶
ID kanala u zaglavlju svakog paketa omogućuje da do 32 neovisna toka dijele isti fizički transport. Sloj kanala pretvara te numeričke ID-ove u imenovane, aplikaciji vidljive krajnje točke na koje se kod domaćina može pozivati nizom znakova.
12.6.1. Četiri ugrađena kanala¶
Kamera registrira četiri kanala pri pokretanju, prije nego što se izvrši bilo koji aplikacijski kod:
stdin– bajtovi skripte koje domaćin šalje kameri na izvršavanje. IDE koristi ovaj kanal za slanje skripte koja se uređuje;exec()na SDK-u domaćina ekvivalentan je poziv iz Python programa.stdout– bajtovi iz pozivaprint()na kameri i tragovi neuhvaćenih iznimaka. Serijska konzola IDE-a čita ovaj kanal.stream– kanal za prikaz uživo. IDE iz njega povlači JPEG sličice; bilo koja skripta domaćina može učiniti isto pomoćuread_frame().profile– događaji profilera, prisutni samo kada je kamera izgrađena s omogućenim profiliranjem. Većina izdanih verzija to izostavlja.
Aplikacijski kod rijetko treba dirati bilo koji od ugrađenih kanala; zanimljiv rad odvija se na kanalima koje aplikacija sama registrira.
12.6.2. Registriranje kanala¶
Skripta na strani kamere registrira novi kanal pozivanjem protocol.register() s imenom i Python pozadinskim objektom:
import json
import protocol
import time
trigger_count = 0
class StatusChannel:
def size(self):
# Refresh the snapshot on every host query.
self._buf = json.dumps({
'uptime_s': time.ticks_ms() // 1000,
'triggers': trigger_count,
}).encode()
return len(self._buf)
def read(self, offset, size):
return self._buf[offset:offset + size]
protocol.register(name='status', backend=StatusChannel())
Metode pozadinskog objekta određuju što kanal može raditi. Pozadinski objekt sa samo size i read je podatkovni kanal samo za čitanje; dodajte write i postaje dvosmjeran; dodajte poll i domaćin može upitati jesu li novi podaci spremni prije nego što plati za čitanje. Uzorkovanje podataka unutar size najjednostavniji je obrazac kada je korisni teret dovoljno malen da stane u jedan fragment – međuspremnik se generira na zahtjev, nikad se ne sprema u predmemoriju, nikad ne dolazi do utrke. Veći korisni tereti – slikovne sličice, senzorski tragovi – trebaju obrazac zasuna koji drži međuspremnik dok domaćin ne završi svoje višefragmentno čitanje, što je obrađeno uz kanal sličica.
Mala količina vođenja evidencije odvija se automatski:
Biblioteka dodjeljuje sljedeći slobodan ID kanala (između 0 i 31).
Zastavice mogućnosti izvode se iz prisutnih metoda:
CHANNEL_FLAG_READako je definiranaread,CHANNEL_FLAG_WRITEako je definiranawrite,CHANNEL_FLAG_LOCKako su definiranelock/unlock.Paket događaja
CHANNEL_REGISTEREDšalje se svakom povezanom domaćinu kako bi se njegov popis kanala ažurirao.
Povratna vrijednost je rukovatelj protocol.ProtocolChannel koji aplikacija može zadržati. Metoda rukovatelja send_event() predstavlja kuku na strani kamere za obavještavanje domaćina da se „nešto dogodilo na ovom kanalu bez promjene podataka za čitanje” – okidač je aktiviran, gumb je pritisnut, prijeđena je prekretnica u broju uzoraka.
12.6.3. Čitanje kanala s domaćina¶
SDK domaćina isporučuje se kao paket openmv na PyPI-ju (pip install openmv), izgrađen na pyserial za transport. Njegova klasa openmv.camera.Camera izlaže imenovane kanale kamere putem visokorazinskih metoda:
from openmv.camera import Camera
with Camera('/dev/ttyACM0', baudrate=921600) as cam:
cam.update_channels()
if cam.has_channel('status'):
size = cam.channel_size('status')
data = cam.channel_read('status', size)
Upozorenje
Paket openmv zahtijeva CPython 3.12 ili noviji. Raniji interpreteri nemaju značajke o kojima SDK ovisi; instalirajte verziju 3.12+ prije pip install openmv.
Nekoliko stvari koje treba primijetiti u vezi s postavljanjem:
Niz znakova serijskog priključka – ovdje
/dev/ttyACM0– u stilu jeCOM3na sustavu Windows,/dev/cu.usbmodemXXXXna macOS-u i/dev/ttyACM*na Linuxu. Stvarni broj ovisi o tome kao koji se priključak kamera nabrojala.Brzina prijenosa je magična vrijednost protokola
921600, koju USB-CDC stog kamere prepoznaje kao „ovaj klijent govori protokolom, a ne REPL-om”. Bilo koja druga brzina vraća se na običnu serijsku liniju.Upravitelj konteksta
with Camera(...) as cam:otvara transport, izvodiPROTO_SYNC, razmjenjuje mogućnosti i pri izlazu uredno zatvara priključak. Eksplicitan pozivupdate_channels()nakon ulaska osvježava lokalni popis kanala svim kanalima koje je aplikacija registrirala nakon pokretanja.
channel_size() i channel_read() su radne metode; channel_write() šalje međuspremnik kameri i natrag ako pozadinski objekt ima metodu write; has_channel() siguran je način provjere je li ime registrirano prije njegove uporabe. Ime kanala traži se jednom u ID kanala koji je kamera dodijelila tijekom register i koristi se u svakom paketu od tada nadalje.
Svaki par channel_size() / channel_read() košta dva povratna putovanja: jedan paket za upit o veličini, jedan za upit o bajtovima. Preko USB-CDC-a oba završavaju zajedno za otprilike jednu milisekundu; preko UART-a ista razmjena traje dulje razmjerno brzini prijenosa serijske linije. Aplikacijski kod koji čita u uskoj petlji trebao bi pozivati channel_size() samo kada se veličina zaista može promijeniti – za podatke fiksne veličine, veličina iz prvog poziva može se spremiti u predmemoriju.
12.6.4. Neovisnost među kanalima¶
Vrijedi znati tri stvari o tome kako kanali međusobno djeluju:
Neovisna kontrola toka. Svaki kanal ima vlastito stanje čitanja na čekanju, vlastite podatke i vlastite povratne pozive
size/read/write. Dugotrajno čitanje na kanalustreamne blokira čitanja na aplikacijskom kanaluconfig.Sekvencijalno po kanalu. Unutar jednog kanala paketi se isporučuju po redu. Sloj pouzdanosti to jamči čak i kada su uključeni ponovni prijenosi.
Dijeljeni transport, dijeljeni proračun za ponovni prijenos. Svi kanali dijele jednu fizičku vezu, pa bujica prometa na jednom kanalu usporava ostale zaposjedanjem žice. Mehanizam
CHANNEL_LOCKomogućuje jednom kanalu da rezervira žicu za atomarno čitanje višestrukih paketa; pozadinski objekt se uključuje implementiranjem povratnih pozivalock/unlock.
Kanal je minimalna površina na kojoj se program domaćina i program kamere dogovaraju o suradnji. Ime, smjer (čitanje ili pisanje ili oboje), metode povratnih poziva na strani kamere i odgovarajući pozivi metoda na strani domaćina čine cijeli ugovor.