OpenAMP remoteproc interface for asymmetric multiprocessing

Files
README.md

openamp #

Control of remote processors through the Linux remoteproc sysfs interface.

Many embedded systems-on-chip put Linux application cores next to a real-time co-processor. On a Zynq UltraScale+ (K26), for instance, Linux runs on the A53 cores and has to load firmware into the R5 core before starting it. The kernel offers this through remoteproc, its side of the OpenAMP framework, as files under /sys/class/remoteproc. openamp reads and writes those files from OCaml, using Eio.

Each operation takes an fs path, which lets a test point it at a temporary tree. On a host without remoteproc, macOS for example, Remoteproc.find returns None.

Installation #

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

Usage #

Boot a co-processor #

The program below installs a firmware file, points the remote processor at it and starts it. The same handle is then used to read the state, stop the processor and start it again.

let run () =
  Eio_main.run @@ fun env ->
  let fs = Eio.Stdenv.fs env in
  Openamp.Firmware.install ~fs ~src:"./build/r5-app.elf" ~name:"r5-app.elf";
  match Openamp.Remoteproc.find ~fs () with
  | None -> Fmt.pr "No remote processor found@."
  | Some rp -> (
      Openamp.Remoteproc.set_firmware ~fs rp "r5-app.elf";
      match Openamp.Remoteproc.start ~fs rp with
      | Ok () -> Fmt.pr "Started %s@." (Openamp.Remoteproc.name ~fs rp)
      | Error e -> Fmt.epr "start failed: %s@." e)

Restart after a crash #

let restart_if_crashed ~fs rp =
  match Openamp.Remoteproc.state ~fs rp with
  | Openamp.Remoteproc.Crashed ->
      let _ = Openamp.Remoteproc.stop ~fs rp in
      Openamp.Remoteproc.start ~fs rp
  | _ -> Ok ()

API #

Remoteproc lifecycle #

  • Openamp.Remoteproc.find ~fs ?index () is Some t if a remote processor exists at that index (default 0), and None otherwise.
  • Openamp.Remoteproc.find_all ~fs () lists every processor.
  • Openamp.Remoteproc.set_firmware ~fs t name sets the firmware file, as a path under /lib/firmware/. A failed write is ignored.
  • Openamp.Remoteproc.start ~fs t and stop ~fs t return a (unit, string) result, whose error is the one the kernel reported.
  • Openamp.Remoteproc.state ~fs t is Offline, Running, Crashed, Suspended or Unknown s.
  • Openamp.Remoteproc.name ~fs t and index t identify the processor.

Firmware #

  • Openamp.Firmware.install ~fs ~src ~name copies src to /lib/firmware/<name>.
  • Openamp.Firmware.exists ~fs name is true if the firmware file is there.
  • Openamp.Firmware.base_path () is the firmware directory.

Testing #

Openamp.For_testing changes the sysfs and firmware base paths, so a test can lay out its own tree in a temporary directory. reset () puts the defaults back.

References #

License #

ISC. See LICENSE.md.