rpc — knihovna rpc

Modul rpc na OpenMV Cam vám umožňuje připojit vaši OpenMV Cam k jinému mikrokontroléru nebo počítači a provádět na vaší OpenMV Cam vzdálená volání Pythonu (nebo procedur). Modul rpc umožňuje i opačný směr, pokud chcete, aby vaše OpenMV Cam mohla provádět vzdálená volání procedur (nebo Pythonu) na jiném mikrokontroléru nebo počítači.

Jak knihovnu používat

Minimální slave, který vystavuje jeden callback přes UART:

import rpc
import csi

csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.QVGA)

interface = rpc.rpc_uart_slave(baudrate=115200)

def snapshot(_):
    return csi0.snapshot().compress().bytearray()

interface.register_callback(snapshot)
interface.loop()  # Does not return.

Odpovídající master, který si od slave vyžádá JPEG snímek:

import rpc

interface = rpc.rpc_uart_master(baudrate=115200)

result = interface.call("snapshot")
if result is None:
    print("communication failed")
elif len(result) == 0:
    print("remote function not registered on the slave")
else:
    # result is a memoryview of the JPEG bytes returned by the slave.
    print("received", len(result), "bytes")

Pro použití jiného přenosu zaměňte rpc_uart_master / rpc_uart_slave za odpovídající dvojici can, i2c nebo spi.

Obecně platí, že aby řídicí zařízení mohlo používat knihovnu rpc, vytvoříte pomocí knihovny rpc objekt rozhraní. Například:

interface = rpc.rpc_uart_master(baudrate=115200)

Tím se vytvoří rozhraní UART pro komunikaci se slave zařízením rpc.

Jakmile je rozhraní vytvořeno, stačí provést:

memory_view_object_result = interface.call("remote_function_or_method_name", bytes_object_argument)

A knihovna rpc se pokusí spustit dané "remote_function_or_method_name" na slave zařízení. Vzdálená funkce nebo metoda obdrží bytes_object_argument, který může mít velikost až 2^32-1 bajtů. Jakmile vzdálená metoda dokončí provádění, vrátí memory_view_object_result, který může mít rovněž velikost až 2^32-1 bajtů. Protože argument i odpověď jsou oba obecné kontejnery bajtů, můžete přes knihovnu rpc předat cokoli a obdržet libovolný typ odpovědi. Jednoduchý způsob předávání argumentů je použít struct.pack() k vytvoření argumentu a struct.unpack() k přijetí argumentu na druhé straně. Pokud jde o odpověď, druhá strana může jako výsledek odeslat řetězcový objekt nebo json řetězec, který pak master může interpretovat.

Co se týče chyb, pokud se pokusíte spustit neexistující název funkce nebo metody, metoda rpc_master.call() vrátí prázdný objekt bytes(). Pokud se knihovně rpc nepodaří komunikovat se slave zařízením, knihovna rpc vrátí None.

Aby zůstala věc jednoduchá, knihovna rpc neudržuje spojení mezi master a slave zařízeními. Metoda rpc_master.call() zapouzdřuje pokus o připojení ke slave zařízení, spuštění vzdálené funkce nebo metody a získání výsledku.

Nyní na straně slave musíte vytvořit rozhraní rpc pro komunikaci s master zařízením. Vypadá to takto:

interface = rpc.rpc_uart_slave(baudrate=115200)

Tím se vytvoří vrstva rozhraní UART pro komunikaci s master zařízením rpc.

Jakmile vytvoříte rozhraní slave, je třeba pomocí objektu rozhraní zaregistrovat callbacky, které může master volat:

def remote_function_or_method_name(memoryview_object_argument):
    <lots of code>
    return bytes_object_result

interface.register_callback(remote_function_or_method_name)

Na slave zařízení můžete zaregistrovat libovolný počet callbacků. Nakonec, jakmile dokončíte registraci callbacků, stačí provést:

interface.loop()

Na slave zařízení tím spustíte knihovnu rpc a začnete naslouchat master zařízení. Pozor, metoda rpc_slave.loop() se nevrací.

třída rpc – základní třída rpc

Základní třída rpc je znovu implementována třídami rpc_master a rpc_slave k vytvoření rozhraní master a slave. Není určena k přímému použití.

class rpc.rpc

Vytvoří objekt rpc. Není určen k přímému použití.

get_bytes(buff: bytearray | memoryview, timeout_ms: int) bytes | None

Znovu implementováno podtřídami specifickými pro daný přenos. Naplní buff bajty z podkladového rozhraní během timeout_ms milisekund. Při vypršení časového limitu vrací None.

put_bytes(data: bytes | memoryview, timeout_ms: int) None

Znovu implementováno podtřídami specifickými pro daný přenos. Odešle data přes podkladové rozhraní během timeout_ms milisekund.

stream_reader(call_back: Callable[[memoryview], None], queue_depth: int = 1, read_timeout_ms: int = 5000) None

Přijímá proud datových paketů ze vzdáleného rpc.stream_writer. Měl by být volán zevnitř callbacku rpc_slave (nebo přímo po úspěšném rpc_master.call), jakmile se obě strany synchronizovaly.

  • call_back – volatelný objekt vyvolaný jednou pro každý přijatý datový paket jako call_back(data), kde data je memoryview. Návratová hodnota je ignorována.

  • queue_depth – počet snímků v přenosu, které writer smí odeslat, než počká na readera. Vyšší hodnoty zvyšují propustnost za cenu paměti.

  • read_timeout_ms – počet milisekund čekání na jeden datový paket.

Vrací se při jakékoli chybě. Pro zrušení vyvolejte výjimku uvnitř call_back; vzdálené straně vyprší časový limit.

stream_writer(call_back: Callable[[], bytes | memoryview], write_timeout_ms: int = 5000) None

Odesílá proud datových paketů vzdálenému rpc.stream_reader. Měl by být volán zevnitř callbacku rpc_slave (nebo přímo po úspěšném rpc_master.call), jakmile se obě strany synchronizovaly.

  • call_back – volatelný objekt vyvolaný bez argumentů, který vrací další datový paket bytes nebo memoryview k odeslání.

  • write_timeout_ms – počet milisekund čekání při odesílání každého datového paketu.

Vrací se při jakékoli chybě. Pro zrušení vyvolejte výjimku uvnitř call_back; vzdálené straně vyprší časový limit.

třída rpc_master – základní třída rpc_master

rpc_master je základní třída. Použijte jednu z podtříd specifických pro daný přenos (rpc_can_master, rpc_i2c_master, rpc_spi_master, rpc_uart_master).

class rpc.rpc_master

Vytvoří objekt rpc_master. Není určen k přímému použití.

call(name: str, data: bytes = bytes(), send_timeout: int = 1000, recv_timeout: int = 1000) memoryview | None

Provede vzdálené volání na slave zařízení.

  • name – řetězcový název vzdálené funkce nebo metody, která se má spustit.

  • data – objekt typu bytes předaný jako argument vzdálené funkci.

  • send_timeout – počet milisekund čekání během připojování ke slave zařízení a spouštění vzdálené funkce. Jakmile master začne odesílat argument, toto se již neuplatňuje; knihovna povoluje na přenos argumentu až 5 sekund.

  • recv_timeout – počet milisekund čekání, než slave začne vracet odpověď. Jakmile master začne přijímat odpověď, toto se již neuplatňuje; knihovna povoluje na přenos odpovědi až 5 sekund.

Při úspěchu vrací memoryview odpovědi, prázdný bytes(), pokud vzdálený název na slave zařízení neexistuje, nebo None při selhání komunikace.

třída rpc_slave – základní třída rpc_slave

rpc_slave je základní třída. Použijte jednu z podtříd specifických pro daný přenos (rpc_can_slave, rpc_i2c_slave, rpc_spi_slave, rpc_uart_slave).

class rpc.rpc_slave

Vytvoří objekt rpc_slave. Není určen k přímému použití.

register_callback(cb: Callable[[memoryview], bytes | memoryview]) None

Zaregistruje callback, který může master vyvolat podle názvu. cb je volatelný objekt přijímající jeden argument memoryview a vracející objekt typu bytes. Jako vyhledávací klíč se používá __name__ callbacku.

schedule_callback(cb: Callable[[], None]) None

Naplánuje jednorázové provedení cb (volatelného objektu bez argumentů) ihned poté, co aktuálně běžící rpc callback úspěšně vrátí svou odpověď master zařízení. Musí být voláno zevnitř rpc callbacku. Umožňuje, aby mezi rpc transakcemi běžela dlouhotrvající práce nebo průchozí přenosy rpc.get_bytes/rpc.put_bytes. Pokud je vyžadováno opakované provádění, zaregistrujte znovu při každém vyvolání.

setup_loop_callback(cb: Callable[[], None]) None

Zaregistruje cb (volatelný objekt bez argumentů) tak, aby byl vyvolán při každé iteraci rpc_slave.loop. Na rozdíl od rpc_slave.schedule_callback zůstává tento callback zaregistrován. Musí být neblokující; rychlost volání je proměnlivá.

loop(recv_timeout: int = 1000, send_timeout: int = 1000) None

Spustí dispečerskou smyčku rpc slave. Nevrací se s výjimkou výjimky vyvolané z callbacku.

  • recv_timeout – počet milisekund čekání na příkaz od master zařízení před opakovaným pokusem.

  • send_timeout – počet milisekund čekání, než master potvrdí odpověď, před návratem k příjmu.

třída rpc_can_master – rozhraní CAN Master

Řízení jiného zařízení rpc přes CAN.

class rpc.rpc_can_master(message_id: int = 0x7FF, bit_rate: int = 250000, sample_point: float = 75, can_bus: int = 2)
  • message_id – 11bitové CAN message id používané pro přenos dat.

  • bit_rate – bitová rychlost CAN v bitech za sekundu.

  • sample_point – procento Tseg1/Tseg2 vzorkovacího bodu (např. 50.0, 62.5, 75, 87.5).

  • can_bus – číslo periferie CAN.

message_id a bit_rate master a slave se musí shodovat. Sběrnice musí být zakončena 120 ohmy.

třída rpc_can_slave – rozhraní CAN Slave

Být řízen jiným zařízením rpc přes CAN.

class rpc.rpc_can_slave(message_id: int = 0x7FF, bit_rate: int = 250000, sample_point: float = 75, can_bus: int = 2)

Popisy argumentů viz rpc_can_master.

třída rpc_i2c_master – rozhraní I2C Master

Řízení jiného zařízení rpc přes I2C.

class rpc.rpc_i2c_master(slave_addr: int = 0x12, rate: int = 100000, i2c_bus: int = 2)
  • slave_addr – 7bitová I2C adresa slave zařízení.

  • rate – frekvence hodin sběrnice I2C v Hz.

  • i2c_bus – číslo periferie I2C.

Adresy master a slave se musí shodovat. Na SCL a SDA jsou vyžadovány externí pull-up rezistory a obě zařízení musí sdílet společnou zem.

třída rpc_i2c_slave – rozhraní I2C Slave

Být řízen jiným zařízením rpc přes I2C.

class rpc.rpc_i2c_slave(slave_addr: int = 0x12, i2c_bus: int = 2)
  • slave_addr – 7bitová I2C adresa, na kterou tento slave reaguje.

  • i2c_bus – číslo periferie I2C.

třída rpc_spi_master – rozhraní SPI Master

Řízení jiného zařízení rpc přes SPI.

class rpc.rpc_spi_master(cs_pin: str = 'P3', freq: int = 1000000, clk_polarity: int = 1, clk_phase: int = 0, spi_bus: int = 2)
  • cs_pin – název pinu chip-select.

  • freq – frekvence hodin sběrnice SPI v Hz.

  • clk_polarity – klidová úroveň hodin (0 nebo 1).

  • clk_phase – vzorkování dat na první (0) nebo druhé (1) hraně hodin.

  • spi_bus – číslo periferie SPI.

Nastavení master a slave se musí shodovat. Připojte CS, SCLK, MOSI, MISO přímo. Obě zařízení musí sdílet společnou zem.

třída rpc_spi_slave – rozhraní SPI Slave

Být řízen jiným zařízením rpc přes SPI.

class rpc.rpc_spi_slave(cs_pin: str = 'P3', clk_polarity: int = 1, clk_phase: int = 0, spi_bus: int = 2)
  • cs_pin – název vstupního pinu chip-select.

  • clk_polarity – klidová úroveň hodin (0 nebo 1).

  • clk_phase – vzorkování dat na první (0) nebo druhé (1) hraně hodin.

  • spi_bus – číslo periferie SPI.

třída rpc_uart_master – rozhraní UART Master

Řízení jiného zařízení rpc přes asynchronní sériovou linku (UART).

class rpc.rpc_uart_master(baudrate: int = 9600, uart_port: int = 3)
  • baudrate – sériová přenosová rychlost (baud rate).

  • uart_port – číslo periferie UART.

Přenosové rychlosti master a slave se musí shodovat. Připojte TX master k RX slave a RX master k TX slave. Obě zařízení musí sdílet společnou zem.

třída rpc_uart_slave – rozhraní UART Slave

Být řízen jiným zařízením rpc přes asynchronní sériovou linku (UART).

class rpc.rpc_uart_slave(baudrate: int = 9600, uart_port: int = 3)
  • baudrate – sériová přenosová rychlost (baud rate).

  • uart_port – číslo periferie UART.