rpc — rpc könyvtár

Az OpenMV Cam rpc modulja lehetővé teszi, hogy az OpenMV Cam eszközt egy másik mikrovezérlőhöz vagy számítógéphez csatlakoztasd, és távoli python- (vagy eljárás-) hívásokat hajts végre az OpenMV Cam eszközön. Az rpc modul a fordított irányt is támogatja, ha azt szeretnéd, hogy az OpenMV Cam egy másik mikrovezérlőn vagy számítógépen tudjon távoli eljárás- (vagy python-) hívásokat végrehajtani.

A könyvtár használata

Egy minimális slave, amely egy visszahívást tesz elérhetővé UART-on keresztül:

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.

A hozzá tartozó master, amely egy JPEG képkockát kér a slave-től:

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")

Cseréld ki az rpc_uart_master / rpc_uart_slave párost a megfelelő can, i2c vagy spi párra, ha más átviteli közeget szeretnél használni.

Általában ahhoz, hogy a vezérlő eszköz használhassa az rpc könyvtárat, létrehozol egy interfész objektumot az rpc könyvtár segítségével. Például:

interface = rpc.rpc_uart_master(baudrate=115200)

Ez egy UART interfészt hoz létre az rpc slave-vel való kommunikációhoz.

Miután az interfész létrejött, csak ezt kell tenned:

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

Az rpc könyvtár pedig megpróbálja végrehajtani az adott "remote_function_or_method_name" hívást a slave-en. A távoli függvény vagy metódus megkapja a bytes_object_argument argumentumot, amely legfeljebb 2^32-1 bájt méretű lehet. Miután a távoli metódus befejezte a végrehajtást, egy memory_view_object_result eredményt ad vissza, amely szintén legfeljebb 2^32-1 bájt méretű lehet. Mivel az argumentum és a válasz egyaránt általános bájttároló, bármit átadhatsz az rpc könyvtáron keresztül, és bármilyen típusú választ fogadhatsz. Az argumentumok átadásának egyszerű módja, ha a struct.pack() segítségével hozod létre az argumentumot, és a struct.unpack() segítségével fogadod azt a másik oldalon. A válasznál a másik oldal eredményként küldhet egy sztring objektumot vagy json sztringet, amelyet aztán a master értelmezhet.

Ami a hibákat illeti, ha egy nem létező függvény- vagy metódusnevet próbálsz végrehajtani, az rpc_master.call() metódus egy üres bytes() objektumot ad vissza. Ha az rpc könyvtárnak nem sikerült kommunikálnia a slave-vel, az rpc könyvtár None értéket ad vissza.

Az egyszerűség kedvéért az rpc könyvtár nem tart fenn folyamatos kapcsolatot a master és a slave eszköz között. Az rpc_master.call() metódus magában foglalja a slave-hez való kapcsolódás megkísérlését, a távoli függvény vagy metódus végrehajtásának elindítását és az eredmény fogadását.

A slave oldalon pedig létre kell hoznod egy rpc interfészt a masterrel való kommunikációhoz. Ez így néz ki:

interface = rpc.rpc_uart_slave(baudrate=115200)

Ez létrehozza az UART interfész réteget az rpc masterrel való kommunikációhoz.

Miután létrehoztad a slave interfészt, regisztrálnod kell az interfész objektummal azokat a visszahívásokat, amelyeket a master hívhat:

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

interface.register_callback(remote_function_or_method_name)

Annyi visszahívást regisztrálhatsz a slave-en, amennyit csak szeretnél. Végül, miután befejezted a visszahívások regisztrálását, csak ezt kell végrehajtanod:

interface.loop()

A slave-en az rpc könyvtár elindításához és a master figyelésének megkezdéséhez. Megjegyzendő, hogy az rpc_slave.loop() metódus nem tér vissza.

class rpc – rpc alaposztály

Az rpc alaposztályt az rpc_master és rpc_slave osztályok újraimplementálják a master és slave interfészek létrehozásához. Nem közvetlen használatra szánták.

class rpc.rpc

Létrehoz egy rpc objektumot. Nem közvetlen használatra szánták.

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

Az átviteli közeghez igazodó alosztályok újraimplementálják. Feltölti a buff puffert az alapul szolgáló interfészről érkező bájtokkal timeout_ms ezredmásodpercen belül. Időtúllépés esetén None értéket ad vissza.

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

Az átviteli közeghez igazodó alosztályok újraimplementálják. Elküldi a data adatot az alapul szolgáló interfészen keresztül timeout_ms ezredmásodpercen belül.

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

Adatcsomagok folyamát fogadja egy távoli rpc.stream_writer egységtől. Egy rpc_slave visszahíváson belülről (vagy közvetlenül egy sikeres rpc_master.call után) kell meghívni, miután mindkét oldal szinkronizálódott.

  • call_back – minden fogadott adatcsomagra egyszer meghívott hívható objektum call_back(data) formában, ahol a data egy memoryview. A visszatérési értékét figyelmen kívül hagyja.

  • queue_depth – azon folyamatban lévő képkockák száma, amelyeket az író elküldhet, mielőtt az olvasóra várna. A magasabb értékek növelik az átviteli teljesítményt a memória rovására.

  • read_timeout_ms – az adatcsomagonként várakozandó ezredmásodpercek száma.

Bármilyen hiba esetén visszatér. A megszakításhoz válts ki egy kivételt a call_back belsejében; a távoli oldal időtúllépést jelez.

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

Adatcsomagok folyamát küldi egy távoli rpc.stream_reader egységnek. Egy rpc_slave visszahíváson belülről (vagy közvetlenül egy sikeres rpc_master.call után) kell meghívni, miután mindkét oldal szinkronizálódott.

  • call_back – argumentum nélkül meghívott hívható objektum, amely a következő elküldendő bytes vagy memoryview adatcsomagot adja vissza.

  • write_timeout_ms – az egyes adatcsomagok küldésekor várakozandó ezredmásodpercek száma.

Bármilyen hiba esetén visszatér. A megszakításhoz válts ki egy kivételt a call_back belsejében; a távoli oldal időtúllépést jelez.

class rpc_master – rpc_master alaposztály

Az rpc_master egy alaposztály. Használd valamelyik átviteli közeghez igazodó alosztályt (rpc_can_master, rpc_i2c_master, rpc_spi_master, rpc_uart_master).

class rpc.rpc_master

Létrehoz egy rpc_master objektumot. Nem közvetlen használatra szánták.

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

Egy távoli hívást hajt végre a slave eszközön.

  • name – a végrehajtandó távoli függvény vagy metódus sztring neve.

  • data – a távoli függvénynek argumentumként átadott bytes típusú objektum.

  • send_timeout – a slave-hez való csatlakozás és a távoli függvény végrehajtásának elindítása közben várakozandó ezredmásodpercek száma. Miután a master megkezdi az argumentum küldését, ez már nem érvényes; a könyvtár legfeljebb 5 másodpercet enged az argumentum átvitelére.

  • recv_timeout – a slave válaszadásának megkezdésére várakozandó ezredmásodpercek száma. Miután a master megkezdi a válasz fogadását, ez már nem érvényes; a könyvtár legfeljebb 5 másodpercet enged a válasz átvitelére.

Sikeres esetben a válasz egy memoryview nézetét adja vissza, üres bytes() értéket, ha a távoli név nem létezik a slave-en, vagy None értéket kommunikációs hiba esetén.

class rpc_slave – rpc_slave alaposztály

Az rpc_slave egy alaposztály. Használd valamelyik átviteli közeghez igazodó alosztályt (rpc_can_slave, rpc_i2c_slave, rpc_spi_slave, rpc_uart_slave).

class rpc.rpc_slave

Létrehoz egy rpc_slave objektumot. Nem közvetlen használatra szánták.

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

Regisztrál egy visszahívást, amelyet a master név alapján meghívhat. A cb egy hívható objektum, amely egy memoryview argumentumot vesz át és egy bytes típusú objektumot ad vissza. A visszahívás __name__ attribútumát használja keresési kulcsként.

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

Ütemezi a cb (argumentum nélküli hívható objektum) egyszeri végrehajtását, közvetlenül azután, hogy az éppen futó rpc visszahívás sikeresen visszaadta a válaszát a masternek. Egy rpc visszahíváson belülről kell meghívni. Lehetővé teszi, hogy hosszan futó munka vagy rpc.get_bytes/rpc.put_bytes átmenő (cut-through) átvitelek fussanak az rpc tranzakciók között. Ismételt végrehajtás esetén minden meghíváskor újra kell regisztrálni.

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

Regisztrálja a cb (argumentum nélküli hívható objektum) meghívását az rpc_slave.loop minden iterációjában. Az rpc_slave.schedule_callback metódussal ellentétben ez a visszahívás regisztrálva marad. Nem blokkolhat; a hívási gyakoriság változó.

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

Futtatja az rpc slave diszpécser ciklusát. Csak egy visszahívásból kiváltott kivétel esetén tér vissza.

  • recv_timeout – a master parancsára várakozandó ezredmásodpercek száma az újrapróbálkozás előtt.

  • send_timeout – a master válasz-nyugtázására várakozandó ezredmásodpercek száma, mielőtt visszatérne a fogadáshoz.

class rpc_can_master – CAN Master interfész

Egy másik rpc eszköz vezérlése CAN-en keresztül.

class rpc.rpc_can_master(message_id: int = 0x7FF, bit_rate: int = 250000, sample_point: float = 75, can_bus: int = 2)
  • message_id – az adatátvitelhez használt 11 bites CAN üzenetazonosító.

  • bit_rate – CAN bitsebesség bit/másodpercben.

  • sample_point – a Tseg1/Tseg2 mintavételi pont százalékos értéke (pl. 50.0, 62.5, 75, 87.5).

  • can_bus – a CAN periféria száma.

A master és a slave message_id és bit_rate értékének egyeznie kell. A buszt 120 ohmmal le kell zárni.

class rpc_can_slave – CAN Slave interfész

Vezérelhető egy másik rpc eszköz által CAN-en keresztül.

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

Az argumentumok leírását lásd az rpc_can_master osztálynál.

class rpc_i2c_master – I2C Master interfész

Egy másik rpc eszköz vezérlése I2C-n keresztül.

class rpc.rpc_i2c_master(slave_addr: int = 0x12, rate: int = 100000, i2c_bus: int = 2)
  • slave_addr – a slave eszköz 7 bites I2C címe.

  • rate – az I2C busz órajel-frekvenciája Hz-ben.

  • i2c_bus – az I2C periféria száma.

A master és a slave címének egyeznie kell. Az SCL és SDA vonalakon külső felhúzó ellenállásokra van szükség, és mindkét eszköznek közös földet kell megosztania.

class rpc_i2c_slave – I2C Slave interfész

Vezérelhető egy másik rpc eszköz által I2C-n keresztül.

class rpc.rpc_i2c_slave(slave_addr: int = 0x12, i2c_bus: int = 2)
  • slave_addr – az a 7 bites I2C cím, amelyre ez a slave válaszol.

  • i2c_bus – az I2C periféria száma.

class rpc_spi_master – SPI Master interfész

Egy másik rpc eszköz vezérlése SPI-n keresztül.

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 – a chip-select láb neve.

  • freq – az SPI busz órajel-frekvenciája Hz-ben.

  • clk_polarity – a tétlen órajelszint (0 vagy 1).

  • clk_phase – az adat mintavételezése az első (0) vagy a második (1) órajelélre.

  • spi_bus – az SPI periféria száma.

A master és a slave beállításainak egyeznie kell. A CS, SCLK, MOSI, MISO vonalakat közvetlenül kösd össze. Mindkét eszköznek közös földet kell megosztania.

class rpc_spi_slave – SPI Slave interfész

Vezérelhető egy másik rpc eszköz által SPI-n keresztül.

class rpc.rpc_spi_slave(cs_pin: str = 'P3', clk_polarity: int = 1, clk_phase: int = 0, spi_bus: int = 2)
  • cs_pin – a chip-select bemeneti láb neve.

  • clk_polarity – a tétlen órajelszint (0 vagy 1).

  • clk_phase – az adat mintavételezése az első (0) vagy a második (1) órajelélre.

  • spi_bus – az SPI periféria száma.

class rpc_uart_master – UART Master interfész

Egy másik rpc eszköz vezérlése aszinkron soros (UART) kapcsolaton keresztül.

class rpc.rpc_uart_master(baudrate: int = 9600, uart_port: int = 3)
  • baudrate – a soros átviteli sebesség (baud).

  • uart_port – az UART periféria száma.

A master és a slave átviteli sebességének (baud) egyeznie kell. Kösd a master TX vonalát a slave RX vonalához, a master RX vonalát pedig a slave TX vonalához. Mindkét eszköznek közös földet kell megosztania.

class rpc_uart_slave – UART Slave interfész

Vezérelhető egy másik rpc eszköz által aszinkron soros (UART) kapcsolaton keresztül.

class rpc.rpc_uart_slave(baudrate: int = 9600, uart_port: int = 3)
  • baudrate – a soros átviteli sebesség (baud).

  • uart_port – az UART periféria száma.