openamp --- รองรับ Asymmetric Multiprocessing (AMP) มาตรฐาน

โมดูล openamp จัดเตรียมโครงสร้างพื้นฐานการสื่อสารระหว่างโปรเซสเซอร์มาตรฐานสำหรับ MicroPython โมดูลนี้จัดการรายละเอียดทั้งหมดของ OpenAMP เช่น การตั้งค่า shared resource table การเริ่มต้น vrings เป็นต้น โดยมี API สำหรับใช้งานโครงสร้างพื้นฐาน RPMsg bus ผ่านคลาส Endpoint และรองรับ processor Life Cycle Management (LCM) เช่น การโหลดเฟิร์มแวร์ การเริ่มและหยุด remote core ผ่านคลาส RemoteProc

ตัวอย่างการใช้งาน:

import openamp

def ept_recv_callback(src, data):
    print("Received message on endpoint", data)

# Create a new RPMsg endpoint to communicate with the remote core.
ept = openamp.Endpoint("vuart-channel", callback=ept_recv_callback)

# Create a RemoteProc object, load its firmware and start it.
rproc = openamp.RemoteProc("virtual_uart.elf") # Or entry point address (ex 0x081E0000)
rproc.start()

while True:
    if ept.is_ready():
        ept.send("data")

ฟังก์ชัน

openamp.new_service_callback(ns_callback: Callable[[str, int], Any]) None

ตั้งค่า callback สำหรับบริการใหม่

อาร์กิวเมนต์ ns_callback คือฟังก์ชันที่จะถูกเรียกเมื่อ remote processor ประกาศบริการใหม่ ณ จุดนั้น host processor สามารถเลือกสร้าง endpoint ที่ประกาศมาได้ หากบริการนั้นรองรับ หรือจะเพิกเฉยหากไม่รองรับ หากไม่ได้ตั้งค่าฟังก์ชันนี้ host processor ควรลงทะเบียน endpoint ในฝั่งตัวเองก่อน และระบบจะผูก endpoint โดยอัตโนมัติเมื่อ remote ประกาศบริการ

คลาส Endpoint

class openamp.Endpoint(name: str, callback: Callable[[int, bytes], Any], src: int = ENDPOINT_ADDR_ANY, dest: int = ENDPOINT_ADDR_ANY)

สร้าง RPMsg Endpoint ใหม่ endpoint คือช่องทางการสื่อสารแบบสองทิศทางระหว่างสองคอร์

อาร์กิวเมนต์ ได้แก่:

  • name คือชื่อของ endpoint

  • callback คือฟังก์ชันที่ถูกเรียกเมื่อ endpoint ได้รับข้อมูล โดยรับที่อยู่ต้นทางของ remote point และข้อมูลเป็น bytes ที่ส่งผ่านการอ้างอิง

  • src คือที่อยู่ต้นทางของ endpoint หากไม่ระบุ ไลบรารีจะกำหนดให้อัตโนมัติ

  • dest คือที่อยู่ปลายทางของ endpoint หาก endpoint ถูกสร้างจาก new_service_callback ต้องระบุค่านี้และต้องตรงกับที่อยู่ต้นทางของ remote endpoint หาก endpoint ลงทะเบียนในฝั่งตัวเองก่อนการประกาศ ที่อยู่ปลายทางจะถูกกำหนดโดยไลบรารีเมื่อ endpoint ถูกผูก

deinit() None

ทำลาย endpoint และปลดปล่อยทรัพยากรทั้งหมด

is_ready() bool

คืนค่า True หาก endpoint พร้อมส่งข้อมูล (กล่าวคือมีทั้งที่อยู่ต้นทางและปลายทาง)

send(buffer: bytes, *, src: int = -1, dest: int = -1, timeout: int = -1) int

ส่งข้อความไปยัง remote processor ผ่าน endpoint นี้

อาร์กิวเมนต์ ได้แก่:

  • buffer คือ payload ของข้อความ (ออบเจ็กต์ใดก็ได้ที่รองรับ buffer protocol เช่น bytes, bytearray หรือ str)

  • src คือที่อยู่ต้นทางของ endpoint สำหรับข้อความ หากไม่ระบุ จะใช้ที่อยู่ต้นทางที่ endpoint ผูกไว้

  • dest คือที่อยู่ปลายทางของ endpoint สำหรับข้อความ หากไม่ระบุ จะใช้ที่อยู่ปลายทางที่ endpoint ผูกไว้

  • timeout ระบุเวลาเป็นมิลลิวินาทีที่รอบัฟเฟอร์ว่าง ค่าเริ่มต้นคือฟังก์ชันจะบล็อก

คลาส RemoteProc

Warning

บน STM32H7 คอร์ AMP ที่สองเป็น Cortex-M4 ที่ไม่สามารถหยุดแล้วรีสตาร์ทในที่เดิมได้ การเรียก RemoteProc.stop() หรือ RemoteProc.shutdown() บนแพลตฟอร์มนั้นจึงทำการรีเซ็ตระบบทั้งหมดแทนที่จะเป็นการหยุดเฉพาะคอร์

class openamp.RemoteProc(entry: str | int)

ออบเจ็กต์ RemoteProc รองรับ processor Life Cycle Management (LCM) เช่น การโหลดเฟิร์มแวร์ การเริ่มและหยุด remote core

อาร์กิวเมนต์ entry อาจเป็น path ไปยังไฟล์ภาพเฟิร์มแวร์ ซึ่งในกรณีนี้เฟิร์มแวร์จะถูกโหลดจากไฟล์ไปยังหน่วยความจำเป้าหมาย หรืออาจเป็น entry point address ซึ่งในกรณีนี้เฟิร์มแวร์ต้องถูกโหลดไว้ที่ address นั้นแล้ว

start() None

เริ่มต้น remote processor

stop() None

หยุด remote processor พฤติกรรมที่แน่นอนขึ้นอยู่กับแพลตฟอร์ม

shutdown() None

Shutdown หยุด remote processor และปลดปล่อยทรัพยากรทั้งหมด พฤติกรรมที่แน่นอนขึ้นอยู่กับแพลตฟอร์ม แต่โดยทั่วไปจะปิด power และ clock ของ remote core ฟังก์ชันนี้ยังใช้เป็น finaliser ด้วย (กล่าวคือ ถูกเรียกเมื่อออบเจ็กต์ RemoteProc ถูก collect)