rpc — ספריית rpc

מודול ה-rpc ב-OpenMV Cam מאפשר לך לחבר את ה-OpenMV Cam שלך אל בקר זעיר או מחשב אחר ולבצע קריאות פייתון (או פרוצדורה) מרוחקות על ה-OpenMV Cam שלך. מודול ה-rpc מאפשר גם את הכיוון ההפוך, אם ברצונך שה-OpenMV Cam שלך יוכל לבצע קריאות פרוצדורה (או פייתון) מרוחקות על בקר זעיר או מחשב אחר.

כיצד להשתמש בספרייה

slave מינימלי שחושף פונקציית callback אחת מעל 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.

ה-master התואם המבקש מה-slave פריים JPEG:

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

החלף את rpc_uart_master / rpc_uart_slave בזוג can, i2c או spi התואם כדי להשתמש בתעבורה שונה.

באופן כללי, כדי שהתקן הבקרה ישתמש בספריית ה-rpc תיצור אובייקט ממשק באמצעות ספריית ה-rpc. לדוגמה:

interface = rpc.rpc_uart_master(baudrate=115200)

פעולה זו יוצרת ממשק UART לתקשורת עם rpc slave.

לאחר שהממשק נוצר עליך פשוט לבצע:

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

וספריית ה-rpc תנסה לבצע את ה-"remote_function_or_method_name" על ה-slave. הפונקציה או המתודה המרוחקת תקבל את ה-bytes_object_argument שיכול להיות בגודל של עד 2^32-1 בתים. לאחר שהמתודה המרוחקת מסיימת לרוץ היא תחזיר memory_view_object_result שגם הוא יכול להיות בגודל של עד 2^32-1 בתים. מכיוון שהארגומנט והתגובה הם שניהם מכלי בתים גנריים, ניתן להעביר כל דבר דרך ספריית ה-rpc ולקבל כל סוג של תגובה. דרך פשוטה להעברת ארגומנטים היא להשתמש ב-struct.pack() כדי ליצור את הארגומנט וב-struct.unpack() כדי לקבל את הארגומנט בצד השני. בנוגע לתגובה, הצד השני עשוי לשלוח אובייקט מחרוזת או מחרוזת json כתוצאה שאותה יכול ה-master לפרש.

באשר לשגיאות, אם תנסה לבצע שם של פונקציה או מתודה שאינו קיים, המתודה rpc_master.call() תחזיר אובייקט bytes() ריק. אם ספריית ה-rpc נכשלה בתקשורת עם ה-slave, ספריית ה-rpc תחזיר None.

כדי לשמור על פשטות, ספריית ה-rpc אינה מתחזקת חיבור בין התקני ה-master וה-slave. המתודה rpc_master.call() עוטפת את הניסיון להתחבר אל ה-slave, התחלת ביצוע הפונקציה או המתודה המרוחקת, וקבלת התוצאה.

כעת, בצד ה-slave של הדברים עליך ליצור ממשק rpc לתקשורת עם ה-master. זה נראה כך:

interface = rpc.rpc_uart_slave(baudrate=115200)

פעולה זו תיצור את שכבת ממשק ה-UART לתקשורת עם rpc master.

לאחר שאתה יוצר את ממשק ה-slave עליך לרשום פונקציות callback שה-master יכול לקרוא להן באמצעות אובייקט הממשק:

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

interface.register_callback(remote_function_or_method_name)

אתה רשאי לרשום כמה פונקציות callback שתרצה על ה-slave. לבסוף, לאחר שסיימת לרשום את פונקציות ה-callback עליך פשוט לבצע:

interface.loop()

על ה-slave כדי להפעיל את ספריית ה-rpc ולהתחיל להאזין ל-master. שים לב שהמתודה rpc_slave.loop() אינה חוזרת.

class rpc – מחלקת הבסיס rpc

מחלקת הבסיס rpc ממומשת מחדש על ידי המחלקות rpc_master ו-rpc_slave כדי ליצור את ממשקי ה-master וה-slave. היא אינה מיועדת לשימוש ישיר.

class rpc.rpc

יוצר אובייקט rpc. אינו מיועד לשימוש ישיר.

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

ממומש מחדש על ידי תת-מחלקות ייעודיות לתעבורה. ממלא את buff בבתים מהממשק הבסיסי בתוך timeout_ms אלפיות שנייה. מחזיר None בעת timeout.

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

ממומש מחדש על ידי תת-מחלקות ייעודיות לתעבורה. שולח את data מעל הממשק הבסיסי בתוך timeout_ms אלפיות שנייה.

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

מקבל זרם של מטענים מ-rpc.stream_writer מרוחק. יש לקרוא לו מתוך פונקציית callback של rpc_slave (או ישירות לאחר rpc_master.call מוצלח) לאחר ששני הצדדים סונכרנו.

  • call_back – קריאֶה (callable) המופעלת פעם אחת לכל מטען שמתקבל בצורה call_back(data) כאשר data הוא memoryview. ערך ההחזרה מתעלמים ממנו.

  • queue_depth – מספר הפריימים בתעופה שלכותב מותר לשלוח לפני המתנה לקורא. ערכים גבוהים יותר מגדילים את התפוקה במחיר של זיכרון.

  • read_timeout_ms – אלפיות שנייה להמתנה לכל מטען.

חוזר בכל שגיאה. כדי לבטל, זרוק חריגה בתוך call_back; הצד המרוחק יעבור timeout.

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

שולח זרם של מטענים אל rpc.stream_reader מרוחק. יש לקרוא לו מתוך פונקציית callback של rpc_slave (או ישירות לאחר rpc_master.call מוצלח) לאחר ששני הצדדים סונכרנו.

  • call_back – קריאֶה (callable) המופעלת ללא ארגומנטים והמחזירה את מטען ה-bytes או ה-memoryview הבא לשליחה.

  • write_timeout_ms – אלפיות שנייה להמתנה בעת שליחת כל מטען.

חוזר בכל שגיאה. כדי לבטל, זרוק חריגה בתוך call_back; הצד המרוחק יעבור timeout.

class rpc_master – מחלקת הבסיס rpc_master

ה-rpc_master היא מחלקת בסיס. השתמש באחת מתת-המחלקות הייעודיות לתעבורה (rpc_can_master, rpc_i2c_master, rpc_spi_master, rpc_uart_master).

class rpc.rpc_master

יוצר אובייקט rpc_master. אינו מיועד לשימוש ישיר.

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

מבצע קריאה מרוחקת על התקן ה-slave.

  • name – שם מחרוזת של הפונקציה או המתודה המרוחקת לביצוע.

  • data – אובייקט מסוג bytes המועבר כארגומנט לפונקציה המרוחקת.

  • send_timeout – אלפיות שנייה להמתנה במהלך ההתחברות אל ה-slave והתחלת ביצוע הפונקציה המרוחקת. ברגע שה-master מתחיל לשלוח את הארגומנט זה כבר לא חל; הספרייה מאפשרת עד 5 שניות להעברת הארגומנט.

  • recv_timeout – אלפיות שנייה להמתנה לכך שה-slave יתחיל להחזיר תגובה. ברגע שה-master מתחיל לקבל את התגובה זה כבר לא חל; הספרייה מאפשרת עד 5 שניות להעברת התגובה.

מחזיר memoryview של התגובה בהצלחה, bytes() ריק אם השם המרוחק אינו קיים על ה-slave, או None בעת כשל בתקשורת.

class rpc_slave – מחלקת הבסיס rpc_slave

ה-rpc_slave היא מחלקת בסיס. השתמש באחת מתת-המחלקות הייעודיות לתעבורה (rpc_can_slave, rpc_i2c_slave, rpc_spi_slave, rpc_uart_slave).

class rpc.rpc_slave

יוצר אובייקט rpc_slave. אינו מיועד לשימוש ישיר.

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

רושם פונקציית callback שה-master עשוי להפעיל לפי שם. cb היא קריאֶה (callable) המקבלת ארגומנט memoryview אחד ומחזירה אובייקט מסוג bytes. ה-__name__ של פונקציית ה-callback משמש כמפתח החיפוש.

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

מתזמן את cb (קריאֶה המקבלת ללא ארגומנטים) לביצוע פעם אחת, מיד לאחר שפונקציית ה-rpc callback הרצה כעת מחזירה בהצלחה את תגובתה ל-master. חובה לקרוא לו מתוך פונקציית rpc callback. מאפשר לעבודה ארוכת-טווח או להעברות cut-through מסוג rpc.get_bytes/rpc.put_bytes לרוץ בין טרנזקציות rpc. רשום מחדש בכל הפעלה אם נדרש ביצוע חוזר.

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

רושם את cb (קריאֶה המקבלת ללא ארגומנטים) להפעלה בכל איטרציה של rpc_slave.loop. בניגוד ל-rpc_slave.schedule_callback, פונקציית callback זו נשארת רשומה. חייבת להיות בלתי חוסמת; קצב הקריאה משתנה.

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

מריץ את לולאת השיגור (dispatch) של ה-rpc slave. אינו חוזר אלא באמצעות חריגה הנזרקת מפונקציית callback.

  • recv_timeout – אלפיות שנייה להמתנה לפקודה מה-master לפני ניסיון חוזר.

  • send_timeout – אלפיות שנייה להמתנה לכך שה-master יאשר את התגובה לפני החזרה לקבלה.

class rpc_can_master – ממשק CAN Master

שולט בהתקן rpc אחר מעל CAN.

class rpc.rpc_can_master(message_id: int = 0x7FF, bit_rate: int = 250000, sample_point: float = 75, can_bus: int = 2)
  • message_id – מזהה הודעת CAN בן 11 ביט המשמש לתעבורת נתונים.

  • bit_rate – קצב הביטים של CAN בביטים לשנייה.

  • sample_point – אחוז נקודת הדגימה Tseg1/Tseg2 (למשל 50.0, 62.5, 75, 87.5).

  • can_bus – מספר ההתקן ההיקפי CAN.

ה-message_id וה-bit_rate של ה-master וה-slave חייבים להתאים. האפיק חייב להיות מסתיים ב-120 אוהם.

class rpc_can_slave – ממשק CAN Slave

להישלט על ידי התקן rpc אחר מעל CAN.

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

ראה rpc_can_master לתיאורי הארגומנטים.

class rpc_i2c_master – ממשק I2C Master

שולט בהתקן rpc אחר מעל I2C.

class rpc.rpc_i2c_master(slave_addr: int = 0x12, rate: int = 100000, i2c_bus: int = 2)
  • slave_addr – כתובת I2C בת 7 ביט של התקן ה-slave.

  • rate – תדר שעון אפיק ה-I2C ב-Hz.

  • i2c_bus – מספר ההתקן ההיקפי I2C.

כתובות ה-master וה-slave חייבות להתאים. נדרשים נוגדי משיכה (pull-ups) חיצוניים על SCL ו-SDA, ושני ההתקנים חייבים לחלוק הארקה משותפת.

class rpc_i2c_slave – ממשק I2C Slave

להישלט על ידי התקן rpc אחר מעל I2C.

class rpc.rpc_i2c_slave(slave_addr: int = 0x12, i2c_bus: int = 2)
  • slave_addr – כתובת I2C בת 7 ביט שאליה slave זה מגיב.

  • i2c_bus – מספר ההתקן ההיקפי I2C.

class rpc_spi_master – ממשק SPI Master

שולט בהתקן rpc אחר מעל 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 – שם פין בחירת השבב (chip-select).

  • freq – תדר שעון אפיק ה-SPI ב-Hz.

  • clk_polarity – רמת השעון במנוחה (0 או 1).

  • clk_phase – דגימת נתונים על קצה השעון הראשון (0) או השני (1).

  • spi_bus – מספר ההתקן ההיקפי SPI.

הגדרות ה-master וה-slave חייבות להתאים. חבר את CS, SCLK, MOSI, MISO ישירות. שני ההתקנים חייבים לחלוק הארקה משותפת.

class rpc_spi_slave – ממשק SPI Slave

להישלט על ידי התקן rpc אחר מעל SPI.

class rpc.rpc_spi_slave(cs_pin: str = 'P3', clk_polarity: int = 1, clk_phase: int = 0, spi_bus: int = 2)
  • cs_pin – שם פין הקלט של בחירת השבב (chip-select).

  • clk_polarity – רמת השעון במנוחה (0 או 1).

  • clk_phase – דגימת נתונים על קצה השעון הראשון (0) או השני (1).

  • spi_bus – מספר ההתקן ההיקפי SPI.

class rpc_uart_master – ממשק UART Master

שולט בהתקן rpc אחר מעל סריאלי אסינכרוני (UART).

class rpc.rpc_uart_master(baudrate: int = 9600, uart_port: int = 3)
  • baudrate – קצב הבָּאוּד הסריאלי.

  • uart_port – מספר ההתקן ההיקפי UART.

קצבי הבָּאוּד של ה-master וה-slave חייבים להתאים. חבר את TX של ה-master ל-RX של ה-slave ואת RX של ה-master ל-TX של ה-slave. שני ההתקנים חייבים לחלוק הארקה משותפת.

class rpc_uart_slave – ממשק UART Slave

להישלט על ידי התקן rpc אחר מעל סריאלי אסינכרוני (UART).

class rpc.rpc_uart_slave(baudrate: int = 9600, uart_port: int = 3)
  • baudrate – קצב הבָּאוּד הסריאלי.

  • uart_port – מספר ההתקן ההיקפי UART.