rpc — bibliothèque rpc¶
Le module rpc de l’OpenMV Cam vous permet de connecter votre OpenMV Cam à un autre microcontrôleur ou ordinateur et d’exécuter des appels python (ou de procédure) distants sur votre OpenMV Cam. Le module rpc permet également l’inverse si vous souhaitez que votre OpenMV Cam puisse exécuter des appels de procédure (ou python) distants sur un autre microcontrôleur ou ordinateur.
Comment utiliser la bibliothèque¶
Un esclave minimal qui expose une fonction de rappel via 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.
Le maître correspondant qui demande une trame JPEG à l’esclave
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")
Remplacez rpc_uart_master / rpc_uart_slave par la paire can, i2c ou spi correspondante pour utiliser un transport différent.
En général, pour que le dispositif contrôleur utilise la bibliothèque rpc, vous allez créer un objet interface à l’aide de la bibliothèque rpc. Par exemple
interface = rpc.rpc_uart_master(baudrate=115200)
Cela crée une interface UART pour communiquer avec un esclave rpc.
Une fois l’interface créée, il vous suffit de faire
memory_view_object_result = interface.call("remote_function_or_method_name", bytes_object_argument)
Et la bibliothèque rpc essaiera d’exécuter ce "remote_function_or_method_name" sur l’esclave. La fonction ou méthode distante recevra le bytes_object_argument qui peut atteindre une taille de 2^32-1 octets. Une fois que la méthode distante a terminé son exécution, elle retournera un memory_view_object_result qui peut également atteindre 2^32-1 octets. Comme l’argument et la réponse sont tous deux des conteneurs d’octets génériques, vous pouvez faire passer n’importe quoi à travers la bibliothèque rpc et recevoir n’importe quel type de réponse. Une manière simple de transmettre des arguments consiste à utiliser struct.pack() pour créer l’argument et struct.unpack() pour le recevoir de l’autre côté. Pour la réponse, l’autre côté peut envoyer un objet chaîne ou une chaîne json comme résultat, que le maître peut ensuite interpréter.
Quant aux erreurs, si vous essayez d’exécuter un nom de fonction ou de méthode inexistant, la méthode rpc_master.call() retournera un objet bytes() vide. Si la bibliothèque rpc n’a pas réussi à communiquer avec l’esclave, la bibliothèque rpc retournera None.
Pour rester simple, la bibliothèque rpc ne maintient pas de connexion entre les dispositifs maître et esclave. La méthode rpc_master.call() encapsule la tentative de connexion à l’esclave, le démarrage de l’exécution de la fonction ou méthode distante, et la récupération du résultat.
Maintenant, du côté de l’esclave, vous devez créer une interface rpc pour communiquer avec le maître. Cela ressemble à ceci
interface = rpc.rpc_uart_slave(baudrate=115200)
Cela créera la couche d’interface UART pour communiquer avec un maître rpc.
Une fois l’interface esclave créée, vous devez ensuite enregistrer les fonctions de rappel que le maître peut appeler avec l’objet interface
def remote_function_or_method_name(memoryview_object_argument):
<lots of code>
return bytes_object_result
interface.register_callback(remote_function_or_method_name)
Vous pouvez enregistrer autant de fonctions de rappel que vous le souhaitez sur l’esclave. Enfin, une fois que vous avez terminé l’enregistrement des fonctions de rappel, il vous suffit d’exécuter
interface.loop()
sur l’esclave pour démarrer la bibliothèque rpc et commencer à écouter le maître. Notez que la méthode rpc_slave.loop() ne retourne pas.
classe rpc – classe de base rpc¶
La classe de base rpc est réimplémentée par les classes rpc_master et rpc_slave pour créer les interfaces maître et esclave. Elle n’est pas destinée à être utilisée directement.
- class rpc.rpc¶
Crée un objet
rpc. N’est pas destiné à être utilisé directement.- get_bytes(buff: bytearray | memoryview, timeout_ms: int) bytes | None¶
Réimplémentée par les sous-classes spécifiques au transport. Remplit
buffavec des octets provenant de l’interface sous-jacente dans un délai detimeout_msmillisecondes. RetourneNoneen cas de dépassement de délai.
- put_bytes(data: bytes | memoryview, timeout_ms: int) None¶
Réimplémentée par les sous-classes spécifiques au transport. Envoie
datavia l’interface sous-jacente dans un délai detimeout_msmillisecondes.
- stream_reader(call_back: Callable[[memoryview], None], queue_depth: int = 1, read_timeout_ms: int = 5000) None¶
Reçoit un flux de charges utiles depuis un
rpc.stream_writerdistant. Doit être appelée depuis l’intérieur d’une fonction de rappelrpc_slave(ou directement après unrpc_master.callréussi) une fois que les deux côtés se sont synchronisés.call_back– objet appelable invoqué une fois par charge utile reçue sous la formecall_back(data)oùdataest unmemoryview. La valeur de retour est ignorée.queue_depth– nombre de trames en transit que l’émetteur est autorisé à envoyer avant d’attendre le lecteur. Des valeurs plus élevées augmentent le débit au prix de la mémoire.read_timeout_ms– millisecondes à attendre par charge utile.
Retourne en cas d’erreur. Pour annuler, levez une exception à l’intérieur de
call_back; le côté distant arrivera à expiration.
- stream_writer(call_back: Callable[[], bytes | memoryview], write_timeout_ms: int = 5000) None¶
Envoie un flux de charges utiles vers un
rpc.stream_readerdistant. Doit être appelée depuis l’intérieur d’une fonction de rappelrpc_slave(ou directement après unrpc_master.callréussi) une fois que les deux côtés se sont synchronisés.call_back– objet appelable invoqué sans argument qui retourne la prochaine charge utilebytesoumemoryviewà envoyer.write_timeout_ms– millisecondes à attendre lors de l’envoi de chaque charge utile.
Retourne en cas d’erreur. Pour annuler, levez une exception à l’intérieur de
call_back; le côté distant arrivera à expiration.
classe rpc_master – classe de base rpc_master¶
Le rpc_master est une classe de base. Utilisez l’une des sous-classes spécifiques au transport (rpc_can_master, rpc_i2c_master, rpc_spi_master, rpc_uart_master).
- class rpc.rpc_master¶
Crée un objet
rpc_master. N’est pas destiné à être utilisé directement.- call(name: str, data: bytes = bytes(), send_timeout: int = 1000, recv_timeout: int = 1000) memoryview | None¶
Exécute un appel distant sur le dispositif esclave.
name– nom sous forme de chaîne de la fonction ou méthode distante à exécuter.data– objet de typebytespassé comme argument à la fonction distante.send_timeout– millisecondes à attendre lors de la connexion à l’esclave et du démarrage de l’exécution de la fonction distante. Une fois que le maître commence à envoyer l’argument, cela ne s’applique plus ; la bibliothèque autorise jusqu’à 5 secondes pour le transfert de l’argument.recv_timeout– millisecondes à attendre que l’esclave commence à renvoyer une réponse. Une fois que le maître commence à recevoir la réponse, cela ne s’applique plus ; la bibliothèque autorise jusqu’à 5 secondes pour le transfert de la réponse.
Retourne un
memoryviewde la réponse en cas de succès, unbytes()vide si le nom distant n’existe pas sur l’esclave, ouNoneen cas d’échec de communication.
classe rpc_slave – classe de base rpc_slave¶
Le rpc_slave est une classe de base. Utilisez l’une des sous-classes spécifiques au transport (rpc_can_slave, rpc_i2c_slave, rpc_spi_slave, rpc_uart_slave).
- class rpc.rpc_slave¶
Crée un objet
rpc_slave. N’est pas destiné à être utilisé directement.- register_callback(cb: Callable[[memoryview], bytes | memoryview]) None¶
Enregistre une fonction de rappel que le maître peut invoquer par son nom.
cbest un objet appelable prenant un argumentmemoryviewet retournant un objet de typebytes. Le__name__de la fonction de rappel est utilisé comme clé de recherche.
- schedule_callback(cb: Callable[[], None]) None¶
Planifie l’exécution de
cb(un objet appelable sans argument) une seule fois, immédiatement après que la fonction de rappel rpc en cours d’exécution a renvoyé sa réponse avec succès au maître. Doit être appelée depuis l’intérieur d’une fonction de rappel rpc. Permet d’exécuter des travaux de longue durée ou des transferts directsrpc.get_bytes/rpc.put_bytesentre les transactions rpc. Réenregistrez à chaque invocation si une exécution répétée est requise.
- setup_loop_callback(cb: Callable[[], None]) None¶
Enregistre
cb(un objet appelable sans argument) pour qu’il soit invoqué à chaque itération derpc_slave.loop. Contrairement àrpc_slave.schedule_callback, cette fonction de rappel reste enregistrée. Doit être non bloquante ; la fréquence d’appel est variable.
- loop(recv_timeout: int = 1000, send_timeout: int = 1000) None¶
Exécute la boucle de répartition de l’esclave rpc. Ne retourne pas, sauf par une exception levée depuis une fonction de rappel.
recv_timeout– millisecondes à attendre une commande du maître avant de réessayer.send_timeout– millisecondes à attendre que le maître accuse réception de la réponse avant de revenir à la réception.
classe rpc_can_master – Interface maître CAN¶
Contrôle un autre dispositif rpc 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– identifiant de message CAN sur 11 bits utilisé pour le transport des données.bit_rate– débit binaire CAN en bits par seconde.sample_point– pourcentage du point d’échantillonnage Tseg1/Tseg2 (par ex. 50.0, 62.5, 75, 87.5).can_bus– numéro du périphérique CAN.
Les
message_idetbit_ratedu maître et de l’esclave doivent correspondre. Le bus doit être terminé par 120 ohms.
classe rpc_can_slave – Interface esclave CAN¶
Être contrôlé par un autre dispositif rpc via CAN.
classe rpc_i2c_master – Interface maître I2C¶
Contrôle un autre dispositif rpc via I2C.
- class rpc.rpc_i2c_master(slave_addr: int = 0x12, rate: int = 100000, i2c_bus: int = 2)¶
slave_addr– adresse I2C sur 7 bits du dispositif esclave.rate– fréquence d’horloge du bus I2C en Hz.i2c_bus– numéro du périphérique I2C.
Les adresses du maître et de l’esclave doivent correspondre. Des résistances de tirage externes sont requises sur SCL et SDA, et les deux dispositifs doivent partager une masse commune.
classe rpc_i2c_slave – Interface esclave I2C¶
Être contrôlé par un autre dispositif rpc via I2C.
classe rpc_spi_master – Interface maître SPI¶
Contrôle un autre dispositif rpc 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– nom de la broche de sélection de puce (chip-select).freq– fréquence d’horloge du bus SPI en Hz.clk_polarity– niveau d’horloge au repos (0 ou 1).clk_phase– échantillonnage des données sur le premier (0) ou le second (1) front d’horloge.spi_bus– numéro du périphérique SPI.
Les réglages du maître et de l’esclave doivent correspondre. Connectez CS, SCLK, MOSI, MISO directement. Les deux dispositifs doivent partager une masse commune.
classe rpc_spi_slave – Interface esclave SPI¶
Être contrôlé par un autre dispositif rpc 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– nom de la broche d’entrée de sélection de puce (chip-select).clk_polarity– niveau d’horloge au repos (0 ou 1).clk_phase– échantillonnage des données sur le premier (0) ou le second (1) front d’horloge.spi_bus– numéro du périphérique SPI.
classe rpc_uart_master – Interface maître UART¶
Contrôle un autre dispositif rpc via série asynchrone (UART).
- class rpc.rpc_uart_master(baudrate: int = 9600, uart_port: int = 3)¶
baudrate– débit en bauds de la liaison série.uart_port– numéro du périphérique UART.
Les débits en bauds du maître et de l’esclave doivent correspondre. Connectez le TX du maître au RX de l’esclave et le RX du maître au TX de l’esclave. Les deux dispositifs doivent partager une masse commune.
classe rpc_uart_slave – Interface esclave UART¶
Être contrôlé par un autre dispositif rpc via série asynchrone (UART).