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
buffmet bytes uit de onderliggende interface binnentimeout_msmilliseconden. RetourneertNonebij time-out.
- put_bytes(data: bytes | memoryview, timeout_ms: int) None¶
Opnieuw geïmplementeerd door transport-specifieke subklassen. Verstuurt
dataover de onderliggende interface binnentimeout_msmilliseconden.
- 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 eenrpc_slave-callback (of direct na een geslaagderpc_master.call) zodra beide kanten gesynchroniseerd zijn.call_back– aanroepbaar object dat eenmaal per ontvangen payload wordt aangeroepen alscall_back(data)waarbijdataeenmemoryviewis. 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 eenrpc_slave-callback (of direct na een geslaagderpc_master.call) zodra beide kanten gesynchroniseerd zijn.call_back– aanroepbaar object dat zonder argumenten wordt aangeroepen en de volgende te versturenbytes- ofmemoryview-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.data–bytes-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
memoryviewvan het antwoord, een legebytes()als de remote-naam niet bestaat op de slave, ofNonebij 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.
cbis een aanroepbaar object dat éénmemoryview-argument neemt en eenbytes-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 ofrpc.get_bytes/rpc.put_bytescut-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 vanrpc_slave.loopaangeroepen te worden. Anders danrpc_slave.schedule_callbackblijft 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_idenbit_ratevan 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_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_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_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).