1# RPMsg Design Document 2RPMsg is a framework to allow communication between two processors. 3RPMsg implementation in OpenAMP library is based on virtio. It complies 4the RPMsg Linux kernel implementation. It defines the handshaking on 5setting up and tearing down the communication between applications 6running on two processors. 7 8## RPMsg User API Flow Chats 9### RPMsg Static Endpoint 10![Static Endpoint](img/coprocessor-rpmsg-static-ep.png) 11### Binding Endpoint Dynamically with Name Service 12![Binding Endpoint Dynamically with Name Service](img/coprocessor-rpmsg-ns.png) 13### Creating Endpoint Dynamically with Name Service 14![Creating Endpoint Dynamically with Name Service](img/coprocessor-rpmsg-ns-dynamic.png) 15 16## RPMsg User APIs 17* RPMsg virtio driver to initialize the shared buffers pool(RPMsg virtio device 18 doesn't need to use this API): 19 ``` 20 void rpmsg_virtio_init_shm_pool(struct rpmsg_virtio_shm_pool *shpool, 21 void *shbuf, size_t size) 22 ``` 23* Initialize RPMsg virtio device: 24 ``` 25 int rpmsg_init_vdev(struct rpmsg_virtio_device *rvdev, 26 struct virtio_device *vdev, 27 rpmsg_ns_bind_cb ns_bind_cb, 28 struct metal_io_region *shm_io, 29 struct rpmsg_virtio_shm_pool *shpool) 30 ``` 31* Deinitialize RPMsg virtio device: 32 ``` 33 void rpmsg_deinit_vdev(struct rpmsg_virtio_device *rvdev)` 34 ``` 35* Get RPMsg device from RPMsg virtio device: 36 ``` 37 struct rpmsg_device *rpmsg_virtio_get_rpmsg_device(struct rpmsg_virtio_device *rvdev) 38 ``` 39### RPMsg virtio endpoint APIs 40* Create RPMsg endpoint: 41 ``` 42 int rpmsg_create_ept(struct rpmsg_endpoint *ept, 43 struct rpmsg_device *rdev, 44 const char *name, uint32_t src, uint32_t dest, 45 rpmsg_ept_cb cb, rpmsg_ns_unbind_cb ns_unbind_cb) 46 ``` 47* Destroy RPMsg endpoint: 48 ``` 49 void rpmsg_destroy_ept(struct rpsmg_endpoint *ept) 50 ``` 51* Check if the local RPMsg endpoint is binded to the remote, and ready to send 52 message: 53 ``` 54 int is_rpmsg_ept_ready(struct rpmsg_endpoint *ept) 55 ``` 56### RPMsg messaging APIs 57* Send message with RPMsg endpoint default binding: 58 ``` 59 int rpmsg_send(struct rpmsg_endpoint *ept, const void *data, int len) 60 ``` 61* Send message with RPMsg endpoint, specify destination address: 62 ``` 63 int rpmsg_sendto(struct rpmsg_endpoint *ept, void *data, int len, 64 uint32_t dst) 65 ``` 66* Send message with RPMsg endpoint using explicit source and destination 67 addresses: 68 ``` 69 int rpmsg_send_offchannel(struct rpmsg_endpoint *ept, 70 uint32_t src, uint32_t dst, 71 const void *data, int len) 72 ``` 73* Try to send message with RPMsg endpoint default binding, if no buffer 74 available, returns: 75 ``` 76 int rpmsg_trysend(struct rpmsg_endpoint *ept, const void *data, 77 int len) 78 ``` 79* Try to send message with RPMsg endpoint, specify destination address, 80 if no buffer available, returns: 81 ``` 82 int rpmsg_trysendto(struct rpmsg_endpoint *ept, void *data, int len, 83 uint32_t dst) 84 ``` 85* Try to send message with RPMsg endpoint using explicit source and destination 86 addresses, if no buffer available, returns: 87 ``` 88 int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, 89 uint32_t src, uint32_t dst, 90 const void *data, int len)` 91 ``` 92 93* Hold the rx buffer for usage outside the receive callback: 94 ``` 95 void rpmsg_hold_rx_buffer(struct rpmsg_endpoint *ept, void *rxbuf) 96 ``` 97 98* Release the rx buffer held thanks to the rpmsg_hold_rx_buffer() function: 99 ``` 100 void rpmsg_release_rx_buffer(struct rpmsg_endpoint *ept, void *rxbuf) 101 102 ``` 103* Gets the tx buffer for message payload. 104 ``` 105 void *rpmsg_get_tx_payload_buffer(struct rpmsg_endpoint *ept, 106 uint32_t *len, int wait) 107 ``` 108 109* Using a buffer obtained by calling the rpmsg_get_tx_payload_buffer() function, 110 Send a message with the RPMsg endpoint default binding: 111 ``` 112 int rpmsg_send_nocopy(struct rpmsg_endpoint *ept, 113 const void *data, int len) 114 ``` 115 116* Using a buffer obtained by calling the rpmsg_get_tx_payload_buffer() function, 117 send a message with RPMsg endpoint, specifying the destination address: 118 ``` 119 int rpmsg_sendto_nocopy(struct rpmsg_endpoint *ept, 120 const void *data, int len, uint32_t dst) 121 ``` 122 123* Using a buffer obtained by calling the rpmsg_get_tx_payload_buffer() function, 124 send a message with RPMsg endpoint using explicit source and destination addresses: 125 ``` 126 int rpmsg_send_offchannel_nocopy(struct rpmsg_endpoint *ept, uint32_t src, 127 uint32_t dst, const void *data, int len) 128 ``` 129 130* Releases unused Tx buffer reserved by rpmsg_get_tx_payload_buffer() function: 131 ``` 132 int rpmsg_release_tx_buffer(struct rpmsg_endpoint *ept, void *txbuf) 133 ``` 134 135## RPMsg User Defined Callbacks 136* RPMsg endpoint message received callback: 137 ``` 138 int (*rpmsg_ept_cb)(struct rpmsg_endpoint *ept, void *data, 139 size_t len, uint32_t src, void *priv) 140 ``` 141* RPMsg name service binding callback. If user defines such callback, when 142 there is a name service announcement arrives, if there is no registered 143 endpoint found to bind to this name service, it will call this callback. 144 If this callback is not defined, it will drop this name service.: 145 ``` 146 void (*rpmsg_ns_bind_cb)(struct rpmsg_device *rdev, 147 const char *name, uint32_t dest) 148 ``` 149* RPMsg name service unbind callback. If user defines such callback, when 150 there is name service destroy arrives, it will call this callback.: 151 ``` 152 void (*rpmsg_ns_unbind_cb)(struct rpmsg_device *rdev, 153 const char *name, uint32_t dest) 154 ``` 155* RPMsg endpoint name service unbind callback. If user defines such callback, 156 when there is name service destroy arrives, it will call this callback to 157 notify the user application about the remote has destroyed the service.: 158 ``` 159 void (*rpmsg_ns_unbind_cb)(struct rpmsg_endpoint *ept) 160 ``` 161