RPMsg inter-partition messaging
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

OCaml 46.9%
C 43.2%
PHP 3.2%
Dune 1.4%
Roff 1.1%
Other 4.1%
46 1 0

Clone this repository

https://tangled.org/gazagnaire.org/ocaml-rpmsg https://tangled.org/did:plc:jhift2vwcxhou52p3sewcrpx/ocaml-rpmsg
git@git.recoil.org:gazagnaire.org/ocaml-rpmsg git@git.recoil.org:did:plc:jhift2vwcxhou52p3sewcrpx/ocaml-rpmsg

For self-hosted knots, clone URLs may differ based on your setup.

Download tar.gz
README.md

rpmsg#

OCaml bindings to the Linux RPMsg character device interface for inter-partition messaging.

RPMsg (Remote Processor Messaging) provides message-based IPC between partitions on asymmetric multiprocessing platforms. It is used for communication between a Linux host and co-processor partitions via virtio vrings on Jailhouse, Xen, and Zynq UltraScale+ platforms.

Endpoint IO is built on Eio flows, so it integrates directly with the Eio event loop.

Installation#

Install with opam:

$ opam install rpmsg

If opam cannot find the package, it may not yet be released in the public opam-repository. Add the overlay repository, then install it:

$ opam repo add samoht https://tangled.org/gazagnaire.org/opam-overlay.git
$ opam update
$ opam install rpmsg

Usage#

Send and receive messages on an endpoint#

Open an endpoint, wrap the fd in Eio flows, and exchange messages:

let run () =
  Eio_main.run @@ fun env ->
  Eio.Switch.run @@ fun sw ->
  let ctrl = Rpmsg.Ctrl.open_ () in
  let idx =
    Rpmsg.Ctrl.create_endpoint ctrl ~name:"my-ep" ~src:1024 ~dst:1025
  in
  let fd = Rpmsg.Endpoint.open_ idx in
  let flow = Eio_unix.Net.import_socket_stream ~sw ~close_unix:true fd in
  let ep = Rpmsg.Endpoint.of_source_sink ~source:flow ~sink:flow in
  Rpmsg.Endpoint.send ep "hello";
  (match Rpmsg.Endpoint.recv ep ~max_size:Rpmsg.Endpoint.max_message_size with
   | Some reply -> Fmt.pr "got: %s@." reply
   | None -> Fmt.pr "peer closed@.");
  Rpmsg.Endpoint.close ep;
  Rpmsg.Ctrl.destroy_endpoint ctrl ~name:"my-ep" ~src:1024 ~dst:1025;
  Rpmsg.Ctrl.close ctrl

Messages are at most 496 bytes (512 virtio buffer minus the 16-byte RPMsg header); see Rpmsg.Endpoint.max_message_size.

API#

Endpoint messaging#

  • Rpmsg.Endpoint.of_source_sink ~source ~sink -- wrap Eio flows.
  • Rpmsg.Endpoint.send ep msg
  • Rpmsg.Endpoint.recv ep ~max_size -- None on EOF.
  • Rpmsg.Endpoint.close ep
  • Rpmsg.Endpoint.max_message_size

Control device (create / destroy endpoints)#

The control device (/dev/rpmsg_ctrl*) creates and destroys endpoints via ioctl. On macOS every call raises Failure (RPMsg does not exist outside Linux).

  • Rpmsg.Ctrl.open_ ?index () -- open /dev/rpmsg_ctrlN (default N=0).
  • Rpmsg.Ctrl.create_endpoint t ~name ~src ~dst -- returns the /dev/rpmsgN index.
  • Rpmsg.Ctrl.destroy_endpoint t ~name ~src ~dst
  • Rpmsg.Ctrl.close t
  • Rpmsg.Endpoint.open_ n -- open /dev/rpmsgN by index, returning the raw fd.

Wire format#

Rpmsg.endpoint_info_codec : endpoint_info Wire.Codec.t encodes the Linux kernel struct rpmsg_endpoint_info (name[32], src:u32, dst:u32 -- 40 bytes) without manual C struct packing.

References#