rpc — rpc-bibliotek¶
Modulen rpc på OpenMV Cam låter dig ansluta din OpenMV Cam till en annan mikrokontroller eller dator och köra fjärranrop av python (eller procedurer) på din OpenMV Cam. Modulen rpc möjliggör även det omvända om du vill att din OpenMV Cam ska kunna köra fjärranrop av procedurer (eller python) på en annan mikrokontroller eller dator.
Hur du använder biblioteket¶
En minimal slav som exponerar ett återanrop över 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.
Den matchande mastern som ber slaven om en JPEG-bildruta:
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")
Byt ut rpc_uart_master / rpc_uart_slave mot motsvarande par can, i2c eller spi för att använda en annan transport.
I allmänhet skapar du, för att styrenheten ska kunna använda biblioteket rpc, ett gränssnittsobjekt med hjälp av biblioteket rpc. Till exempel:
interface = rpc.rpc_uart_master(baudrate=115200)
Detta skapar ett UART-gränssnitt för att kommunicera med en rpc-slav.
När gränssnittet har skapats behöver du bara göra:
memory_view_object_result = interface.call("remote_function_or_method_name", bytes_object_argument)
Och biblioteket rpc kommer att försöka köra "remote_function_or_method_name" på slaven. Fjärrfunktionen eller -metoden tar emot bytes_object_argument som kan vara upp till 2^32-1 byte stort. När fjärrmetoden har kört klart returnerar den ett memory_view_object_result som också kan vara upp till 2^32-1 byte stort. Eftersom både argumentet och svaret är generiska byte-behållare kan du skicka vad som helst genom biblioteket rpc och ta emot vilken typ av svar som helst. Ett enkelt sätt att skicka argument är att använda struct.pack() för att skapa argumentet och struct.unpack() för att ta emot argumentet på den andra sidan. För svaret kan den andra sidan skicka ett strängobjekt eller en json-sträng som resultat, vilket mastern sedan kan tolka.
När det gäller fel, om du försöker köra ett funktions- eller metodnamn som inte finns kommer metoden rpc_master.call() att returnera ett tomt bytes()-objekt. Om biblioteket rpc misslyckas med att kommunicera med slaven kommer biblioteket rpc att returnera None.
För att hålla saker enkelt upprätthåller biblioteket rpc inte någon anslutning mellan master- och slavenheterna. Metoden rpc_master.call() kapslar in att försöka ansluta till slaven, starta körningen av fjärrfunktionen eller -metoden och hämta resultatet.
På slavsidan måste du nu skapa ett rpc-gränssnitt för att kommunicera med mastern. Det ser ut så här:
interface = rpc.rpc_uart_slave(baudrate=115200)
Detta skapar UART-gränssnittslagret för att kommunicera med en rpc-master.
När du har skapat slavgränssnittet behöver du sedan registrera återanrop som mastern kan anropa med gränssnittsobjektet:
def remote_function_or_method_name(memoryview_object_argument):
<lots of code>
return bytes_object_result
interface.register_callback(remote_function_or_method_name)
Du kan registrera så många återanrop du vill på slaven. Slutligen, när du är klar med att registrera återanrop behöver du bara köra:
interface.loop()
På slaven för att starta upp biblioteket rpc och börja lyssna efter mastern. Observera att metoden rpc_slave.loop() inte returnerar.
class rpc – basklass för rpc¶
Basklassen rpc återimplementeras av klasserna rpc_master och rpc_slave för att skapa master- och slavgränssnitten. Den är inte avsedd att användas direkt.
- class rpc.rpc¶
Skapar ett
rpc-objekt. Inte avsett att användas direkt.- get_bytes(buff: bytearray | memoryview, timeout_ms: int) bytes | None¶
Återimplementeras av transportspecifika underklasser. Fyller
buffmed byte från det underliggande gränssnittet inomtimeout_msmillisekunder. ReturnerarNonevid tidsgräns.
- put_bytes(data: bytes | memoryview, timeout_ms: int) None¶
Återimplementeras av transportspecifika underklasser. Skickar
dataöver det underliggande gränssnittet inomtimeout_msmillisekunder.
- stream_reader(call_back: Callable[[memoryview], None], queue_depth: int = 1, read_timeout_ms: int = 5000) None¶
Tar emot en ström av nyttolaster från en fjärransluten
rpc.stream_writer. Bör anropas inifrån ettrpc_slave-återanrop (eller direkt efter ett lyckatrpc_master.call) när båda sidor har synkroniserats.call_back– anropbar funktion som anropas en gång per mottagen nyttolast somcall_back(data)därdataär enmemoryview. Returvärdet ignoreras.queue_depth– antal bildrutor under överföring som skrivaren tillåts skicka innan den väntar på läsaren. Högre värden ökar genomströmningen på bekostnad av minne.read_timeout_ms– millisekunder att vänta per nyttolast.
Returnerar vid alla fel. För att avbryta, kasta ett undantag inuti
call_back; den fjärranslutna sidan kommer att nå tidsgränsen.
- stream_writer(call_back: Callable[[], bytes | memoryview], write_timeout_ms: int = 5000) None¶
Skickar en ström av nyttolaster till en fjärransluten
rpc.stream_reader. Bör anropas inifrån ettrpc_slave-återanrop (eller direkt efter ett lyckatrpc_master.call) när båda sidor har synkroniserats.call_back– anropbar funktion som anropas utan argument och returnerar nästabytes- ellermemoryview-nyttolast att skicka.write_timeout_ms– millisekunder att vänta vid sändning av varje nyttolast.
Returnerar vid alla fel. För att avbryta, kasta ett undantag inuti
call_back; den fjärranslutna sidan kommer att nå tidsgränsen.
class rpc_master – basklass för rpc_master¶
rpc_master är en basklass. Använd en av de transportspecifika underklasserna (rpc_can_master, rpc_i2c_master, rpc_spi_master, rpc_uart_master).
- class rpc.rpc_master¶
Skapar ett
rpc_master-objekt. Inte avsett att användas direkt.- call(name: str, data: bytes = bytes(), send_timeout: int = 1000, recv_timeout: int = 1000) memoryview | None¶
Kör ett fjärranrop på slavenheten.
name– strängnamn på fjärrfunktionen eller -metoden som ska köras.data–bytes-liknande objekt som skickas som argument till fjärrfunktionen.send_timeout– millisekunder att vänta vid anslutning till slaven och vid start av körningen av fjärrfunktionen. När mastern börjar skicka argumentet gäller detta inte längre; biblioteket tillåter upp till 5 sekunder för argumentöverföringen.recv_timeout– millisekunder att vänta på att slaven ska börja returnera ett svar. När mastern börjar ta emot svaret gäller detta inte längre; biblioteket tillåter upp till 5 sekunder för svarsöverföringen.
Returnerar en
memoryviewav svaret vid lyckat anrop, ett tomtbytes()om fjärrnamnet inte finns på slaven, ellerNonevid kommunikationsfel.
class rpc_slave – basklass för rpc_slave¶
rpc_slave är en basklass. Använd en av de transportspecifika underklasserna (rpc_can_slave, rpc_i2c_slave, rpc_spi_slave, rpc_uart_slave).
- class rpc.rpc_slave¶
Skapar ett
rpc_slave-objekt. Inte avsett att användas direkt.- register_callback(cb: Callable[[memoryview], bytes | memoryview]) None¶
Registrerar ett återanrop som mastern kan anropa med namn.
cbär en anropbar funktion som tar ettmemoryview-argument och returnerar ettbytes-liknande objekt. Återanropets__name__används som uppslagsnyckel.
- schedule_callback(cb: Callable[[], None]) None¶
Schemalägger
cb(en anropbar funktion som inte tar några argument) för att köras en gång, omedelbart efter att det för närvarande körande rpc-återanropet har returnerat sitt svar till mastern. Måste anropas inifrån ett rpc-återanrop. Tillåter långvarigt arbete eller cut-through-överföringar medrpc.get_bytes/rpc.put_bytesatt köras mellan rpc-transaktioner. Registrera om vid varje anrop om upprepad körning krävs.
- setup_loop_callback(cb: Callable[[], None]) None¶
Registrerar
cb(en anropbar funktion som inte tar några argument) för att anropas vid varje iteration avrpc_slave.loop. Till skillnad frånrpc_slave.schedule_callbackförblir detta återanrop registrerat. Måste vara icke-blockerande; anropsfrekvensen är variabel.
- loop(recv_timeout: int = 1000, send_timeout: int = 1000) None¶
Kör rpc-slavens dispatch-loop. Returnerar inte annat än genom ett undantag som kastas från ett återanrop.
recv_timeout– millisekunder att vänta på ett kommando från mastern innan nytt försök görs.send_timeout– millisekunder att vänta på att mastern ska bekräfta svaret innan den återgår till att ta emot.
class rpc_can_master – CAN-mastergränssnitt¶
Styr en annan rpc-enhet över 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-bitars CAN-meddelande-id som används för datatransport.bit_rate– CAN-bithastighet i bitar per sekund.sample_point– Tseg1/Tseg2-samplingspunktsprocent (t.ex. 50.0, 62.5, 75, 87.5).can_bus– CAN-kringutrustningens nummer.
Masterns och slavens
message_idochbit_ratemåste matcha. Bussen måste termineras med 120 ohm.
class rpc_can_slave – CAN-slavgränssnitt¶
Styras av en annan rpc-enhet över CAN.
class rpc_i2c_master – I2C-mastergränssnitt¶
Styr en annan rpc-enhet över I2C.
- class rpc.rpc_i2c_master(slave_addr: int = 0x12, rate: int = 100000, i2c_bus: int = 2)¶
slave_addr– 7-bitars I2C-adress för slavenheten.rate– I2C-bussens klockfrekvens i Hz.i2c_bus– I2C-kringutrustningens nummer.
Master- och slavadresserna måste matcha. Externa pull-up-motstånd krävs på SCL och SDA, och båda enheterna måste dela en gemensam jord.
class rpc_i2c_slave – I2C-slavgränssnitt¶
Styras av en annan rpc-enhet över I2C.
class rpc_spi_master – SPI-mastergränssnitt¶
Styr en annan rpc-enhet över 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– namn på chip-select-stiftet.freq– SPI-bussens klockfrekvens i Hz.clk_polarity– klocknivå i viloläge (0 eller 1).clk_phase– sampla data på den första (0) eller andra (1) klockflanken.spi_bus– SPI-kringutrustningens nummer.
Master- och slavinställningarna måste matcha. Anslut CS, SCLK, MOSI, MISO direkt. Båda enheterna måste dela en gemensam jord.
class rpc_spi_slave – SPI-slavgränssnitt¶
Styras av en annan rpc-enhet över SPI.
- class rpc.rpc_spi_slave(cs_pin: str = 'P3', clk_polarity: int = 1, clk_phase: int = 0, spi_bus: int = 2)¶
cs_pin– namn på chip-select-ingångsstiftet.clk_polarity– klocknivå i viloläge (0 eller 1).clk_phase– sampla data på den första (0) eller andra (1) klockflanken.spi_bus– SPI-kringutrustningens nummer.
class rpc_uart_master – UART-mastergränssnitt¶
Styr en annan rpc-enhet över asynkron seriell kommunikation (UART).
- class rpc.rpc_uart_master(baudrate: int = 9600, uart_port: int = 3)¶
baudrate– seriell baudhastighet.uart_port– UART-kringutrustningens nummer.
Master- och slavbaudhastigheterna måste matcha. Anslut masterns TX till slavens RX och masterns RX till slavens TX. Båda enheterna måste dela en gemensam jord.
class rpc_uart_slave – UART-slavgränssnitt¶
Styras av en annan rpc-enhet över asynkron seriell kommunikation (UART).