|
| 1 | +:mod:`openamp` -- provides standard Asymmetric Multiprocessing (AMP) support |
| 2 | +============================================================================ |
| 3 | + |
| 4 | +.. module:: openamp |
| 5 | + :synopsis: provides standard Asymmetric Multiprocessing (AMP) support |
| 6 | + |
| 7 | +The ``openamp`` module provides a standard inter-processor communications infrastructure |
| 8 | +for MicroPython. The module handles all of the details of OpenAMP, such as setting up |
| 9 | +the shared resource table, initializing vrings, etc. It provides an API for using the |
| 10 | +RPMsg bus infrastructure with the `Endpoint` class, and provides processor Life Cycle |
| 11 | +Management (LCM) support, such as loading firmware and starting and stopping a remote |
| 12 | +core, via the `RemoteProc` class. |
| 13 | + |
| 14 | +Example usage:: |
| 15 | + |
| 16 | + import openamp |
| 17 | + |
| 18 | + def ept_recv_callback(src, data): |
| 19 | + print("Received message on endpoint", data) |
| 20 | + |
| 21 | + # Create a new RPMsg endpoint to communicate with the remote core. |
| 22 | + ept = openamp.Endpoint("vuart-channel", callback=ept_recv_callback) |
| 23 | + |
| 24 | + # Create a RemoteProc object, load its firmware and start it. |
| 25 | + rproc = openamp.RemoteProc("virtual_uart.elf") # Or entry point address (ex 0x081E0000) |
| 26 | + rproc.start() |
| 27 | + |
| 28 | + while True: |
| 29 | + if ept.is_ready(): |
| 30 | + ept.send("data") |
| 31 | + |
| 32 | +Functions |
| 33 | +--------- |
| 34 | + |
| 35 | +.. function:: new_service_callback(ns_callback) |
| 36 | + |
| 37 | + Set the new service callback. |
| 38 | + |
| 39 | + The *ns_callback* argument is a function that will be called when the remote processor |
| 40 | + announces new services. At that point the host processor can choose to create the |
| 41 | + announced endpoint, if this particular service is supported, or ignore it if it's |
| 42 | + not. If this function is not set, the host processor should first register the |
| 43 | + endpoint locally, and it will be automatically bound when the remote announces |
| 44 | + the service. |
| 45 | + |
| 46 | +Endpoint class |
| 47 | +-------------- |
| 48 | + |
| 49 | +.. class:: Endpoint(name, callback, src=ENDPOINT_ADDR_ANY, dest=ENDPOINT_ADDR_ANY) |
| 50 | + |
| 51 | + Construct a new RPMsg Endpoint. An endpoint is a bidirectional communication |
| 52 | + channel between two cores. |
| 53 | + |
| 54 | + Arguments are: |
| 55 | + |
| 56 | + - *name* is the name of the endpoint. |
| 57 | + - *callback* is a function that is called when the endpoint receives data with the |
| 58 | + source address of the remote point, and the data as bytes passed by reference. |
| 59 | + - *src* is the endpoint source address. If none is provided one will be assigned |
| 60 | + to the endpoint by the library. |
| 61 | + - *dest* is the endpoint destination address. If the endpoint is created from the |
| 62 | + new_service_callback, this must be provided and it must match the remote endpoint's |
| 63 | + source address. If the endpoint is registered locally, before the announcement, the |
| 64 | + destination address will be assigned by the library when the endpoint is bound. |
| 65 | + |
| 66 | +.. method:: Endpoint.deinit() |
| 67 | + |
| 68 | + Destroy the endpoint and release all of its resources. |
| 69 | + |
| 70 | +.. method:: Endpoint.is_ready() |
| 71 | + |
| 72 | + Returns True if the endpoint is ready to send (i.e., has both a source and destination addresses) |
| 73 | + |
| 74 | +.. method:: Endpoint.send(src=-1, dest=-1, timeout=-1) |
| 75 | + |
| 76 | + Send a message to the remote processor over this endpoint. |
| 77 | + |
| 78 | + Arguments are: |
| 79 | + |
| 80 | + - *src* is the source endpoint address of the message. If none is provided, the |
| 81 | + source address the endpoint is bound to is used. |
| 82 | + - *dest* is the destination endpoint address of the message. If none is provided, |
| 83 | + the destination address the endpoint is bound to is used. |
| 84 | + - *timeout* specifies the time in milliseconds to wait for a free buffer. By default |
| 85 | + the function is blocking. |
| 86 | + |
| 87 | +RemoteProc class |
| 88 | +---------------- |
| 89 | + |
| 90 | +.. class:: RemoteProc(entry) |
| 91 | + |
| 92 | + The RemoteProc object provides processor Life Cycle Management (LCM) support, such as |
| 93 | + loading firmware, starting and stopping a remote core. |
| 94 | + |
| 95 | + The *entry* argument can be a path to firmware image, in which case the firmware is |
| 96 | + loaded from file to its target memory, or an entry point address, in which case the |
| 97 | + firmware must be loaded already at the given address. |
| 98 | + |
| 99 | +.. method:: RemoteProc.start() |
| 100 | + |
| 101 | + Starts the remote processor. |
| 102 | + |
| 103 | +.. method:: RemoteProc.stop() |
| 104 | + |
| 105 | + Stops the remote processor. The exact behavior is platform-dependent. On the STM32H7 for |
| 106 | + example it's not possible to stop and then restart the Cortex-M4 core, so a complete |
| 107 | + system reset is performed on a call to this function. |
| 108 | + |
| 109 | +.. method:: RemoteProc.shutdown() |
| 110 | + |
| 111 | + Shutdown stops the remote processor and releases all of its resources. The exact behavior |
| 112 | + is platform-dependent, however typically it disables power and clocks to the remote core. |
| 113 | + This function is also used as the finaliser (i.e., called when ``RemoteProc`` object is |
| 114 | + collected). Note that on the STM32H7, it's not possible to stop and then restart the |
| 115 | + Cortex-M4 core, so a complete system reset is performed on a call to this function. |
0 commit comments