rpc — rpc-bibliotheek

Met de rpc-module op de OpenMV Cam kun je je OpenMV Cam verbinden met een andere microcontroller of computer en remote python-aanroepen (of procedure-aanroepen) op je OpenMV Cam uitvoeren. De rpc-module maakt ook het omgekeerde mogelijk als je wilt dat je OpenMV Cam remote procedure-aanroepen (of python-aanroepen) op een andere microcontroller of computer kan uitvoeren.

De bibliotheek gebruiken

Een minimale slave die één callback over UART beschikbaar stelt:

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.

De bijbehorende master die de slave om een JPEG-frame vraagt:

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

Vervang rpc_uart_master / rpc_uart_slave door het bijbehorende can-, i2c- of spi-paar om een ander transport te gebruiken.

Over het algemeen maak je, om de rpc-bibliotheek op het besturende apparaat te gebruiken, een interface-object aan met de rpc-bibliotheek. Bijvoorbeeld:

interface = rpc.rpc_uart_master(baudrate=115200)

Dit maakt een UART-interface aan om met een rpc-slave te communiceren.

Zodra de interface is aangemaakt, hoef je alleen het volgende te doen:

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

En de rpc-bibliotheek zal proberen die "remote_function_or_method_name" op de slave uit te voeren. De remote-functie of -methode ontvangt het bytes_object_argument dat tot 2^32-1 bytes groot kan zijn. Zodra de remote-methode klaar is met uitvoeren, retourneert deze een memory_view_object_result dat eveneens tot 2^32-1 bytes groot kan zijn. Omdat zowel het argument als het antwoord generieke byte-containers zijn, kun je alles via de rpc-bibliotheek doorgeven en elk type antwoord ontvangen. Een eenvoudige manier om argumenten door te geven is struct.pack() gebruiken om het argument aan te maken en struct.unpack() om het argument aan de andere kant te ontvangen. Voor het antwoord kan de andere kant een string-object of json-string als resultaat sturen, dat de master vervolgens kan interpreteren.

Wat fouten betreft: als je probeert een niet-bestaande functie- of methodenaam uit te voeren, retourneert de rpc_master.call()-methode een leeg bytes()-object. Als de rpc-bibliotheek niet met de slave kon communiceren, retourneert de rpc-bibliotheek None.

Om het eenvoudig te houden onderhoudt de rpc-bibliotheek geen verbinding tussen de master- en slave-apparaten. De rpc_master.call()-methode omvat het verbinden met de slave, het starten van de uitvoering van de remote-functie of -methode, en het ophalen van het resultaat.

Aan de slave-kant moet je nu een rpc-interface aanmaken om met de master te communiceren. Dit ziet er als volgt uit:

interface = rpc.rpc_uart_slave(baudrate=115200)

Dit maakt de UART-interfacelaag aan om met een rpc-master te communiceren.

Zodra je de slave-interface hebt aangemaakt, moet je callbacks registreren die de master kan aanroepen met het interface-object:

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

interface.register_callback(remote_function_or_method_name)

Je mag zoveel callbacks op de slave registreren als je wilt. Tot slot hoef je, zodra je klaar bent met het registreren van callbacks, alleen het volgende uit te voeren:

interface.loop()

Op de slave om de rpc-bibliotheek op te starten en te beginnen met luisteren naar de master. Merk op dat de rpc_slave.loop()-methode niet terugkeert.

class rpc – rpc-basisklasse

De rpc-basisklasse wordt opnieuw geïmplementeerd door de rpc_master- en rpc_slave-klassen om de master- en slave-interfaces aan te maken. Het is niet bedoeld om rechtstreeks gebruikt te worden.

class rpc.rpc

Maakt een rpc-object aan. Niet bedoeld om rechtstreeks gebruikt te worden.

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

Opnieuw geïmplementeerd door transport-specifieke subklassen. Vult buff met bytes uit de onderliggende interface binnen timeout_ms milliseconden. Retourneert None bij time-out.

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

Opnieuw geïmplementeerd door transport-specifieke subklassen. Verstuurt data over de onderliggende interface binnen timeout_ms milliseconden.

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

Ontvangt een stroom payloads van een remote rpc.stream_writer. Moet worden aangeroepen vanuit een rpc_slave-callback (of direct na een geslaagde rpc_master.call) zodra beide kanten gesynchroniseerd zijn.

  • call_back – aanroepbaar object dat eenmaal per ontvangen payload wordt aangeroepen als call_back(data) waarbij data een memoryview is. De retourwaarde wordt genegeerd.

  • queue_depth – aantal in-flight frames dat de writer mag versturen voordat hij op de reader wacht. Hogere waarden verhogen de doorvoer ten koste van geheugen.

  • read_timeout_ms – milliseconden om per payload te wachten.

Keert terug bij elke fout. Om te annuleren, gooi je een uitzondering op binnen call_back; de andere kant zal een time-out krijgen.

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

Verstuurt een stroom payloads naar een remote rpc.stream_reader. Moet worden aangeroepen vanuit een rpc_slave-callback (of direct na een geslaagde rpc_master.call) zodra beide kanten gesynchroniseerd zijn.

  • call_back – aanroepbaar object dat zonder argumenten wordt aangeroepen en de volgende te versturen bytes- of memoryview-payload retourneert.

  • write_timeout_ms – milliseconden om te wachten bij het versturen van elke payload.

Keert terug bij elke fout. Om te annuleren, gooi je een uitzondering op binnen call_back; de andere kant zal een time-out krijgen.

class rpc_master – rpc_master-basisklasse

De rpc_master is een basisklasse. Gebruik een van de transport-specifieke subklassen (rpc_can_master, rpc_i2c_master, rpc_spi_master, rpc_uart_master).

class rpc.rpc_master

Maakt een rpc_master-object aan. Niet bedoeld om rechtstreeks gebruikt te worden.

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

Voert een remote-aanroep uit op het slave-apparaat.

  • name – string-naam van de remote-functie of -methode die uitgevoerd moet worden.

  • databytes-achtig object dat als argument aan de remote-functie wordt doorgegeven.

  • send_timeout – milliseconden om te wachten tijdens het verbinden met de slave en het starten van de uitvoering van de remote-functie. Zodra de master begint met het versturen van het argument geldt dit niet meer; de bibliotheek staat tot 5 seconden toe voor de overdracht van het argument.

  • recv_timeout – milliseconden om te wachten totdat de slave begint met het retourneren van een antwoord. Zodra de master begint met het ontvangen van het antwoord geldt dit niet meer; de bibliotheek staat tot 5 seconden toe voor de overdracht van het antwoord.

Retourneert bij succes een memoryview van het antwoord, een lege bytes() als de remote-naam niet bestaat op de slave, of None bij een communicatiefout.

class rpc_slave – rpc_slave-basisklasse

De rpc_slave is een basisklasse. Gebruik een van de transport-specifieke subklassen (rpc_can_slave, rpc_i2c_slave, rpc_spi_slave, rpc_uart_slave).

class rpc.rpc_slave

Maakt een rpc_slave-object aan. Niet bedoeld om rechtstreeks gebruikt te worden.

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

Registreert een callback die de master op naam kan aanroepen. cb is een aanroepbaar object dat één memoryview-argument neemt en een bytes-achtig object retourneert. De __name__ van de callback wordt gebruikt als opzoeksleutel.

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

Plant cb (een aanroepbaar object zonder argumenten) om eenmalig uitgevoerd te worden, direct nadat de momenteel actieve rpc-callback zijn antwoord met succes aan de master heeft geretourneerd. Moet worden aangeroepen vanuit een rpc-callback. Maakt het mogelijk om langlopend werk of rpc.get_bytes/rpc.put_bytes cut-through-overdrachten tussen rpc-transacties uit te voeren. Herregistreer bij elke aanroep als herhaalde uitvoering vereist is.

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

Registreert cb (een aanroepbaar object zonder argumenten) om bij elke iteratie van rpc_slave.loop aangeroepen te worden. Anders dan rpc_slave.schedule_callback blijft deze callback geregistreerd. Moet non-blocking zijn; de aanroepfrequentie is variabel.

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

Voert de rpc-slave dispatch-lus uit. Keert niet terug behalve via een uitzondering die door een callback wordt opgegooid.

  • recv_timeout – milliseconden om te wachten op een commando van de master voordat opnieuw geprobeerd wordt.

  • send_timeout – milliseconden om te wachten totdat de master het antwoord bevestigt voordat teruggekeerd wordt naar ontvangen.

class rpc_can_master – CAN Master-interface

Bestuur een ander rpc-apparaat via CAN.

class rpc.rpc_can_master(message_id: int = 0x7FF, bit_rate: int = 250000, sample_point: float = 75, can_bus: int = 2)
  • message_id – 11-bits CAN message-id dat gebruikt wordt voor datatransport.

  • bit_rate – CAN-bitrate in bits per seconde.

  • sample_point – Tseg1/Tseg2 sample-point-percentage (bijv. 50.0, 62.5, 75, 87.5).

  • can_bus – CAN-randapparaatnummer.

De message_id en bit_rate van master en slave moeten overeenkomen. De bus moet afgesloten worden met 120 ohm.

class rpc_can_slave – CAN Slave-interface

Word bestuurd door een ander rpc-apparaat via CAN.

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

Zie rpc_can_master voor argumentbeschrijvingen.

class rpc_i2c_master – I2C Master-interface

Bestuur een ander rpc-apparaat via I2C.

class rpc.rpc_i2c_master(slave_addr: int = 0x12, rate: int = 100000, i2c_bus: int = 2)
  • slave_addr – 7-bits I2C-adres van het slave-apparaat.

  • rate – I2C-busklokfrequentie in Hz.

  • i2c_bus – I2C-randapparaatnummer.

De master- en slave-adressen moeten overeenkomen. Externe pull-ups zijn vereist op SCL en SDA, en beide apparaten moeten een gemeenschappelijke massa delen.

class rpc_i2c_slave – I2C Slave-interface

Word bestuurd door een ander rpc-apparaat via I2C.

class rpc.rpc_i2c_slave(slave_addr: int = 0x12, i2c_bus: int = 2)
  • slave_addr – 7-bits I2C-adres waarop deze slave reageert.

  • i2c_bus – I2C-randapparaatnummer.

class rpc_spi_master – SPI Master-interface

Bestuur een ander rpc-apparaat via 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 – naam van de chip-select-pin.

  • freq – SPI-busklokfrequentie in Hz.

  • clk_polarity – klokniveau in rust (0 of 1).

  • clk_phase – data bemonsteren op de eerste (0) of tweede (1) klokflank.

  • spi_bus – SPI-randapparaatnummer.

De master- en slave-instellingen moeten overeenkomen. Verbind CS, SCLK, MOSI, MISO rechtstreeks. Beide apparaten moeten een gemeenschappelijke massa delen.

class rpc_spi_slave – SPI Slave-interface

Word bestuurd door een ander rpc-apparaat via SPI.

class rpc.rpc_spi_slave(cs_pin: str = 'P3', clk_polarity: int = 1, clk_phase: int = 0, spi_bus: int = 2)
  • cs_pin – naam van de chip-select-ingangspin.

  • clk_polarity – klokniveau in rust (0 of 1).

  • clk_phase – data bemonsteren op de eerste (0) of tweede (1) klokflank.

  • spi_bus – SPI-randapparaatnummer.

class rpc_uart_master – UART Master-interface

Bestuur een ander rpc-apparaat via asynchrone seriële communicatie (UART).

class rpc.rpc_uart_master(baudrate: int = 9600, uart_port: int = 3)
  • baudrate – seriële baudrate.

  • uart_port – UART-randapparaatnummer.

De baudrates van master en slave moeten overeenkomen. Verbind master TX met slave RX en master RX met slave TX. Beide apparaten moeten een gemeenschappelijke massa delen.

class rpc_uart_slave – UART Slave-interface

Word bestuurd door een ander rpc-apparaat via asynchrone seriële communicatie (UART).

class rpc.rpc_uart_slave(baudrate: int = 9600, uart_port: int = 3)
  • baudrate – seriële baudrate.

  • uart_port – UART-randapparaatnummer.