12.6. Channel bernama¶
ID channel dalam header setiap paket memungkinkan hingga 32 stream independen berbagi transport fisik yang sama. Lapisan channel mengubah ID numerik tersebut menjadi endpoint bernama yang terlihat oleh aplikasi yang dapat dirujuk oleh kode host dengan string.
12.6.1. Empat channel bawaan¶
Cam mendaftarkan empat channel saat boot, sebelum kode aplikasi apa pun dijalankan:
stdin-- byte skrip yang didorong host ke cam untuk dieksekusi. IDE menggunakan channel ini untuk mengirim skrip yang sedang diedit;exec()pada SDK host adalah panggilan setara dari program Python.stdout-- byte dari panggilanprint()cam dan traceback pengecualian yang tidak tertangkap. Konsol serial IDE membaca channel ini.stream-- channel pratinjau langsung. IDE mengambil bingkai JPEG darinya; skrip host mana pun dapat melakukan hal yang sama denganread_frame().profile-- event profiler, hanya ada ketika cam dibangun dengan profiling diaktifkan. Sebagian besar build rilis menghilangkannya.
Kode aplikasi jarang perlu menyentuh channel bawaan mana pun; pekerjaan menarik terjadi pada channel yang didaftarkan aplikasi itu sendiri.
12.6.2. Mendaftarkan channel¶
Skrip sisi cam mendaftarkan channel baru dengan memanggil protocol.register() dengan nama dan objek backend Python:
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 objek backend menentukan apa yang dapat dilakukan channel. Backend dengan hanya size dan read adalah channel data hanya-baca; tambahkan write dan itu menjadi dua arah; tambahkan poll dan host dapat bertanya apakah data baru siap sebelum membayar biaya pembacaan. Mengambil sampel data di dalam size adalah pola paling sederhana ketika payload cukup kecil untuk dimuat dalam satu fragmen -- buffer dibuat sesuai permintaan, tidak pernah di-cache, tidak pernah dalam kondisi balapan. Payload yang lebih besar -- bingkai citra, jejak sensor -- memerlukan pola penguncian yang menahan buffer sampai host selesai membaca multi-fragmennya, dibahas bersama channel bingkai.
Sejumlah kecil pembukuan terjadi secara otomatis:
Pustaka menetapkan ID channel berikutnya yang tersedia (antara 0 dan 31).
Flag kemampuan diturunkan dari metode yang ada:
CHANNEL_FLAG_READjikareaddidefinisikan,CHANNEL_FLAG_WRITEjikawritedidefinisikan,CHANNEL_FLAG_LOCKjikalock/unlockdidefinisikan.Paket event
CHANNEL_REGISTEREDdikirim ke host yang terhubung sehingga daftar channel-nya diperbarui.
Nilai kembalian adalah handle protocol.ProtocolChannel yang dapat dipegang aplikasi. Metode send_event() handle adalah hook sisi cam untuk memberi tahu host "sesuatu terjadi pada channel ini tanpa mengubah data yang dapat dibaca" -- trigger aktif, tombol ditekan, tonggak jumlah sampel tercapai.
12.6.3. Membaca channel dari host¶
SDK host dikirimkan sebagai paket openmv di PyPI (pip install openmv), dibangun di atas pyserial untuk transport. Kelas openmv.camera.Camera-nya mengekspos channel bernama cam melalui metode tingkat tinggi:
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)
Peringatan
Paket openmv memerlukan CPython 3.12 atau lebih baru. Interpreter yang lebih lama tidak memiliki fitur yang bergantung pada SDK; instal build 3.12+ sebelum pip install openmv.
Beberapa hal yang perlu diperhatikan tentang pengaturan:
String port serial --
/dev/ttyACM0di sini -- adalah gayaCOM3di Windows,/dev/cu.usbmodemXXXXdi macOS, dan/dev/ttyACM*di Linux. Nomor sebenarnya tergantung pada port mana yang dienumerasi cam.Laju baud adalah nilai ajaib protokol
921600, yang dikenali oleh stack USB-CDC cam sebagai "klien ini berbicara protokol, bukan REPL." Laju lainnya kembali ke saluran serial biasa.Pengelola konteks
with Camera(...) as cam:membuka transport, menjalankanPROTO_SYNC, bertukar kemampuan, dan saat keluar menutup port dengan bersih. Panggilanupdate_channels()eksplisit setelah masuk memperbarui daftar channel lokal dengan channel yang didaftarkan aplikasi setelah boot.
channel_size() dan channel_read() adalah metode utama; channel_write() melakukan round-trip buffer ke cam jika backend memiliki metode write; has_channel() adalah cara aman untuk memeriksa bahwa nama terdaftar sebelum digunakan. Nama channel dicari sekali menjadi ID channel yang ditetapkan cam selama register dan digunakan dalam setiap paket setelahnya.
Setiap pasangan channel_size() / channel_read() membutuhkan dua round-trip: satu paket untuk menanyakan ukurannya, satu untuk menanyakan byte-nya. Melalui USB-CDC keduanya selesai dalam sekitar satu milidetik gabungan; melalui UART pertukaran yang sama memakan waktu lebih lama sebanding dengan laju baud saluran serial. Kode aplikasi yang membaca dalam loop ketat harus memanggil channel_size() hanya ketika ukurannya benar-benar dapat berubah -- untuk data berukuran tetap, ukuran dari panggilan pertama dapat di-cache.
12.6.4. Independensi antar channel¶
Tiga hal yang perlu diketahui tentang cara channel berinteraksi:
Kontrol alur independen. Setiap channel memiliki status pembacaan tertunda sendiri, data sendiri, dan callback
size/read/writesendiri. Pembacaan yang berjalan lama pada channelstreamtidak memblokir pembacaan pada channelconfigaplikasi.Berurutan per channel. Dalam satu channel, paket dikirimkan secara berurutan. Lapisan keandalan menjamin ini bahkan ketika retransmit terlibat.
Transport bersama, anggaran retransmit bersama. Semua channel berbagi satu tautan fisik, sehingga lonjakan lalu lintas pada satu channel memperlambat yang lain dengan memonopoli kabel. Mekanisme
CHANNEL_LOCKmemungkinkan satu channel memesan kabel untuk pembacaan multi-paket atomik; backend memilih masuk dengan mengimplementasikan callbacklock/unlock.
Channel adalah luas permukaan minimum di mana program host dan program cam setuju untuk bekerja sama. Nama, arah (baca atau tulis atau keduanya), metode callback di sisi cam, dan panggilan metode yang sesuai di sisi host adalah keseluruhan kontrak.