rpc — rpc-Bibliothek¶
Das rpc-Modul auf der OpenMV Cam ermöglicht es Ihnen, Ihre OpenMV Cam mit einem anderen Mikrocontroller oder Computer zu verbinden und entfernte Python- (oder Prozedur-)Aufrufe auf Ihrer OpenMV Cam auszuführen. Das rpc-Modul erlaubt auch den umgekehrten Weg, falls Sie möchten, dass Ihre OpenMV Cam entfernte Prozedur- (oder Python-)Aufrufe auf einem anderen Mikrocontroller oder Computer ausführen kann.
Verwendung der Bibliothek¶
Ein minimaler Slave, der einen Callback über UART bereitstellt:
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.
Der passende Master, der den Slave nach einem JPEG-Einzelbild fragt:
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")
Tauschen Sie rpc_uart_master / rpc_uart_slave gegen das passende can-, i2c- oder spi-Paar aus, um einen anderen Transportweg zu verwenden.
Im Allgemeinen erstellen Sie für das steuernde Gerät zur Nutzung der rpc-Bibliothek ein Schnittstellenobjekt mit der rpc-Bibliothek. Zum Beispiel:
interface = rpc.rpc_uart_master(baudrate=115200)
Dies erstellt eine UART-Schnittstelle, um mit einem rpc-Slave zu kommunizieren.
Sobald die Schnittstelle erstellt ist, müssen Sie nur Folgendes tun:
memory_view_object_result = interface.call("remote_function_or_method_name", bytes_object_argument)
Und die rpc-Bibliothek wird versuchen, diese "remote_function_or_method_name" auf dem Slave auszuführen. Die entfernte Funktion oder Methode erhält das bytes_object_argument, das bis zu 2^32-1 Byte groß sein kann. Sobald die entfernte Methode die Ausführung beendet hat, gibt sie ein memory_view_object_result zurück, das ebenfalls bis zu 2^32-1 Byte groß sein kann. Da Argument und Antwort beide generische Byte-Container sind, können Sie alles über die rpc-Bibliothek übergeben und jede Art von Antwort empfangen. Eine einfache Möglichkeit, Argumente zu übergeben, besteht darin, struct.pack() zu verwenden, um das Argument zu erstellen, und struct.unpack(), um das Argument auf der anderen Seite zu empfangen. Für die Antwort kann die andere Seite ein String-Objekt oder einen JSON-String als Ergebnis senden, das der Master dann interpretieren kann.
Was Fehler betrifft: Wenn Sie versuchen, einen nicht existierenden Funktions- oder Methodennamen auszuführen, gibt die rpc_master.call()-Methode ein leeres bytes()-Objekt zurück. Falls die rpc-Bibliothek nicht mit dem Slave kommunizieren konnte, gibt die rpc-Bibliothek None zurück.
Um die Dinge einfach zu halten, hält die rpc-Bibliothek keine Verbindung zwischen Master- und Slave-Geräten aufrecht. Die rpc_master.call()-Methode kapselt den Versuch, sich mit dem Slave zu verbinden, die Ausführung der entfernten Funktion oder Methode zu starten und das Ergebnis abzurufen.
Auf der Slave-Seite müssen Sie nun eine rpc-Schnittstelle erstellen, um mit dem Master zu kommunizieren. Das sieht so aus:
interface = rpc.rpc_uart_slave(baudrate=115200)
Dies erstellt die UART-Schnittstellenschicht, um mit einem rpc-Master zu kommunizieren.
Sobald Sie die Slave-Schnittstelle erstellt haben, müssen Sie Callbacks registrieren, die der Master mit dem Schnittstellenobjekt aufrufen kann:
def remote_function_or_method_name(memoryview_object_argument):
<lots of code>
return bytes_object_result
interface.register_callback(remote_function_or_method_name)
Sie können auf dem Slave so viele Callbacks registrieren, wie Sie möchten. Sobald Sie mit dem Registrieren der Callbacks fertig sind, müssen Sie schließlich nur noch Folgendes ausführen:
interface.loop()
Auf dem Slave, um die rpc-Bibliothek zu starten und auf den Master zu lauschen. Beachten Sie, dass die rpc_slave.loop()-Methode nicht zurückkehrt.
class rpc – rpc-Basisklasse¶
Die rpc-Basisklasse wird von den Klassen rpc_master und rpc_slave neu implementiert, um die Master- und Slave-Schnittstellen zu erstellen. Sie ist nicht zur direkten Verwendung gedacht.
- class rpc.rpc¶
Erstellt ein
rpc-Objekt. Nicht zur direkten Verwendung gedacht.- get_bytes(buff: bytearray | memoryview, timeout_ms: int) bytes | None¶
Von transportspezifischen Unterklassen neu implementiert. Füllt
buffinnerhalb vontimeout_msMillisekunden mit Bytes aus der zugrunde liegenden Schnittstelle. Gibt bei ZeitüberschreitungNonezurück.
- put_bytes(data: bytes | memoryview, timeout_ms: int) None¶
Von transportspezifischen Unterklassen neu implementiert. Sendet
datainnerhalb vontimeout_msMillisekunden über die zugrunde liegende Schnittstelle.
- stream_reader(call_back: Callable[[memoryview], None], queue_depth: int = 1, read_timeout_ms: int = 5000) None¶
Empfängt einen Strom von Nutzdaten von einem entfernten
rpc.stream_writer. Sollte innerhalb einesrpc_slave-Callbacks (oder direkt nach einem erfolgreichenrpc_master.call) aufgerufen werden, sobald sich beide Seiten synchronisiert haben.call_back– aufrufbares Objekt, das einmal pro empfangener Nutzlast alscall_back(data)aufgerufen wird, wobeidataeinmemoryviewist. Der Rückgabewert wird ignoriert.queue_depth– Anzahl der in Übertragung befindlichen Einzelbilder, die der Writer senden darf, bevor er auf den Reader wartet. Höhere Werte erhöhen den Durchsatz auf Kosten des Speichers.read_timeout_ms– Millisekunden, die pro Nutzlast gewartet werden soll.
Kehrt bei jedem Fehler zurück. Zum Abbrechen lösen Sie innerhalb von
call_backeine Ausnahme aus; die Gegenseite wird in eine Zeitüberschreitung laufen.
- stream_writer(call_back: Callable[[], bytes | memoryview], write_timeout_ms: int = 5000) None¶
Sendet einen Strom von Nutzdaten an einen entfernten
rpc.stream_reader. Sollte innerhalb einesrpc_slave-Callbacks (oder direkt nach einem erfolgreichenrpc_master.call) aufgerufen werden, sobald sich beide Seiten synchronisiert haben.call_back– aufrufbares Objekt, das ohne Argumente aufgerufen wird und die nächste zu sendendebytes- odermemoryview-Nutzlast zurückgibt.write_timeout_ms– Millisekunden, die beim Senden jeder Nutzlast gewartet werden soll.
Kehrt bei jedem Fehler zurück. Zum Abbrechen lösen Sie innerhalb von
call_backeine Ausnahme aus; die Gegenseite wird in eine Zeitüberschreitung laufen.
class rpc_master – rpc_master-Basisklasse¶
Der rpc_master ist eine Basisklasse. Verwenden Sie eine der transportspezifischen Unterklassen (rpc_can_master, rpc_i2c_master, rpc_spi_master, rpc_uart_master).
- class rpc.rpc_master¶
Erstellt ein
rpc_master-Objekt. Nicht zur direkten Verwendung gedacht.- call(name: str, data: bytes = bytes(), send_timeout: int = 1000, recv_timeout: int = 1000) memoryview | None¶
Führt einen entfernten Aufruf auf dem Slave-Gerät aus.
name– String-Name der auszuführenden entfernten Funktion oder Methode.data–bytes-ähnliches Objekt, das als Argument an die entfernte Funktion übergeben wird.send_timeout– Millisekunden, die beim Verbinden mit dem Slave und beim Starten der Ausführung der entfernten Funktion gewartet werden soll. Sobald der Master beginnt, das Argument zu senden, gilt dies nicht mehr; die Bibliothek erlaubt bis zu 5 Sekunden für die Argumentübertragung.recv_timeout– Millisekunden, die darauf gewartet werden soll, dass der Slave beginnt, eine Antwort zurückzugeben. Sobald der Master beginnt, die Antwort zu empfangen, gilt dies nicht mehr; die Bibliothek erlaubt bis zu 5 Sekunden für die Antwortübertragung.
Gibt bei Erfolg ein
memoryviewder Antwort zurück, ein leeresbytes(), falls der entfernte Name auf dem Slave nicht existiert, oderNonebei einem Kommunikationsfehler.
class rpc_slave – rpc_slave-Basisklasse¶
Der rpc_slave ist eine Basisklasse. Verwenden Sie eine der transportspezifischen Unterklassen (rpc_can_slave, rpc_i2c_slave, rpc_spi_slave, rpc_uart_slave).
- class rpc.rpc_slave¶
Erstellt ein
rpc_slave-Objekt. Nicht zur direkten Verwendung gedacht.- register_callback(cb: Callable[[memoryview], bytes | memoryview]) None¶
Registriert einen Callback, den der Master über seinen Namen aufrufen kann.
cbist ein aufrufbares Objekt, das einmemoryview-Argument annimmt und einbytes-ähnliches Objekt zurückgibt. Das__name__des Callbacks wird als Suchschlüssel verwendet.
- schedule_callback(cb: Callable[[], None]) None¶
Plant
cb(ein aufrufbares Objekt ohne Argumente) zur einmaligen Ausführung, unmittelbar nachdem der aktuell laufende rpc-Callback seine Antwort erfolgreich an den Master zurückgegeben hat. Muss innerhalb eines rpc-Callbacks aufgerufen werden. Ermöglicht es, dass langlaufende Arbeit oderrpc.get_bytes/rpc.put_bytes-Direktdurchleitungsübertragungen zwischen rpc-Transaktionen ausgeführt werden. Bei wiederholter Ausführung muss bei jedem Aufruf erneut registriert werden.
- setup_loop_callback(cb: Callable[[], None]) None¶
Registriert
cb(ein aufrufbares Objekt ohne Argumente), das bei jeder Iteration vonrpc_slave.loopaufgerufen wird. Anders alsrpc_slave.schedule_callbackbleibt dieser Callback registriert. Muss nicht blockierend sein; die Aufrufrate ist variabel.
- loop(recv_timeout: int = 1000, send_timeout: int = 1000) None¶
Führt die rpc-Slave-Dispatch-Schleife aus. Kehrt nur durch eine aus einem Callback ausgelöste Ausnahme zurück.
recv_timeout– Millisekunden, die auf einen Befehl vom Master gewartet werden soll, bevor erneut versucht wird.send_timeout– Millisekunden, die darauf gewartet werden soll, dass der Master die Antwort bestätigt, bevor zum Empfang zurückgekehrt wird.
class rpc_can_master – CAN-Master-Schnittstelle¶
Steuern Sie ein anderes rpc-Gerät über 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-Bit-CAN-Nachrichten-ID, die für den Datentransport verwendet wird.bit_rate– CAN-Bitrate in Bit pro Sekunde.sample_point– Tseg1/Tseg2-Abtastpunkt-Prozentsatz (z. B. 50.0, 62.5, 75, 87.5).can_bus– CAN-Peripheriegerätenummer.
message_idundbit_ratevon Master und Slave müssen übereinstimmen. Der Bus muss mit 120 Ohm terminiert werden.
class rpc_can_slave – CAN-Slave-Schnittstelle¶
Lassen Sie sich von einem anderen rpc-Gerät über CAN steuern.
class rpc_i2c_master – I2C-Master-Schnittstelle¶
Steuern Sie ein anderes rpc-Gerät über I2C.
- class rpc.rpc_i2c_master(slave_addr: int = 0x12, rate: int = 100000, i2c_bus: int = 2)¶
slave_addr– 7-Bit-I2C-Adresse des Slave-Geräts.rate– I2C-Bus-Taktfrequenz in Hz.i2c_bus– I2C-Peripheriegerätenummer.
Master- und Slave-Adressen müssen übereinstimmen. An SCL und SDA sind externe Pull-up-Widerstände erforderlich, und beide Geräte müssen eine gemeinsame Masse teilen.
class rpc_i2c_slave – I2C-Slave-Schnittstelle¶
Lassen Sie sich von einem anderen rpc-Gerät über I2C steuern.
class rpc_spi_master – SPI-Master-Schnittstelle¶
Steuern Sie ein anderes rpc-Gerät über 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– Name des Chip-Select-Pins.freq– SPI-Bus-Taktfrequenz in Hz.clk_polarity– Ruhepegel des Takts (0 oder 1).clk_phase– Daten an der ersten (0) oder zweiten (1) Taktflanke abtasten.spi_bus– SPI-Peripheriegerätenummer.
Master- und Slave-Einstellungen müssen übereinstimmen. Verbinden Sie CS, SCLK, MOSI, MISO direkt. Beide Geräte müssen eine gemeinsame Masse teilen.
class rpc_spi_slave – SPI-Slave-Schnittstelle¶
Lassen Sie sich von einem anderen rpc-Gerät über SPI steuern.
- class rpc.rpc_spi_slave(cs_pin: str = 'P3', clk_polarity: int = 1, clk_phase: int = 0, spi_bus: int = 2)¶
cs_pin– Name des Chip-Select-Eingangspins.clk_polarity– Ruhepegel des Takts (0 oder 1).clk_phase– Daten an der ersten (0) oder zweiten (1) Taktflanke abtasten.spi_bus– SPI-Peripheriegerätenummer.
class rpc_uart_master – UART-Master-Schnittstelle¶
Steuern Sie ein anderes rpc-Gerät über asynchrone serielle Schnittstelle (UART).
- class rpc.rpc_uart_master(baudrate: int = 9600, uart_port: int = 3)¶
baudrate– serielle Baudrate.uart_port– UART-Peripheriegerätenummer.
Die Baudraten von Master und Slave müssen übereinstimmen. Verbinden Sie Master-TX mit Slave-RX und Master-RX mit Slave-TX. Beide Geräte müssen eine gemeinsame Masse teilen.
class rpc_uart_slave – UART-Slave-Schnittstelle¶
Lassen Sie sich von einem anderen rpc-Gerät über asynchrone serielle Schnittstelle (UART) steuern.