Cover image for OpenAMP

OpenAMP

Words 1.7k
Views
Visitors

Timeline

Timeline

2026-07-04

init

This article introduces the background of the OpenAMP open asymmetric multiprocessing software framework and its application in multi-core heterogeneous systems. It discusses in detail the three core components: Virtio, RPMsg, and Remoteproc, and summarizes the specific working mechanisms for lifecycle management and message communication between the Linux main processor and bare-metal or RTOS coprocessors based on shared memory and inter-core interrupts.

OpenAMP (Open Asymmetric Multiprocessing) was initially developed by Mentor Graphics and Xilinx as a software framework to enable communication between RTOS or bare-metal programs and Linux interfaces in AMP systems. Currently, OpenAMP can be used on platforms such as ST, NXP, TI, and Xilinx, where these manufacturers have provided ported OpenAMP development examples for users to reference during development. This article takesSTM32Cube_FW_MP1_V1.2.0\Projects\STM32MP157C-DK2\Applications\OpenAMPas a reference example.

OpenAMP Project Official Website

OpenAMP Official Documentation

OpenAMP Github Open Source Repository

The main OpenAMP library (implementing RPMSG, Virtio, and Remoteproc for RTOS etc)

STM32CubeMP1 MPU Firmware Package

  • STM32MP157C-EV1 RevC
  • STM32MP157C-DK2 RevC

OpenAMP provides implementations of RPMsg, VirtIO, and RemoteProc:

virtio

Virtio is a virtual device framework that provides shared memory management. The vring in Virtio is a FIFO queue of pointers to data buffers, and there are two unidirectional vrings:

  • One vring is dedicated to messages sent to the remote processor
  • The other vring is used for messages received from the remote processor

The two vrings form a ring, and data between A7 and M4 is shared through the vring buffers. The vring buffers are the shared memory of the two processors (Shared memory, also known as IPC Buffers or Vring buffers).

In the reference configuration provided by ST, the shared memory of the STM32MP157 is located in SRAM3. As shown in the figure below, the processor completes data flow forwarding through the vring ring buffer.

virtio vring forwarding data
virtio vring forwarding data

The relevant code is located atlinux-5.10.256/drivers/virtio

rpmsg

The RPMsg framework is shown in the figure below. It can be seen that the RPMsg framework is located on the upper layer of Virtio. The RPMsg (Remote Processor Messaging) framework is a message bus based on Virtio. RPMsg can communicate messages with the remote end through Virtio under the coordination of IPCC, while Remoteproc can write firmware to the remote end or control the lifecycle and status of the remote end under the control of IPCC.

RPMsg Framework Schematic Diagram
RPMsg Framework Schematic Diagram

As shown in the figure, OpenAMP uses IPCC at the bottom layer, refer to:

IPC Communication Structure Block Diagram
IPC Communication Structure Block Diagram

On the Cortex-A7, the RemoteProc framework activates Linux-based inter-process communication (IPC) based on the available information in the coprocessor’s firmware resource table. The RPMsg service is implemented through the RPMsg framework, and the mailbox service is implemented by the mailbox driver stm32_ipcc.

On the Cortex-M4, the RPMsg service is implemented by the OpenAMP library, and the mailbox service is implemented by the HAL_IPCC driver.

This is a bit convoluted, but the general idea is that the A core running Linux and the M core running bare-metal or FreeRTOS communicate through OpenAMP. The A core and M core have corresponding OpenAMP designs, but they are compatible with each other; the difference lies only in the underlying calls, such as the A mailbox driver stm32_ipcc implementation, and the M core mailbox service is implemented by HAL_IPCC driver.

In the default configuration provided by ST, the SRAM3 area in MCUSRAM has two vrings, used for sending and receiving messages respectively, and the vring buffers are the shared memory. The RPMsg framework is based on Virtio’s vrings; it sends messages to or receives messages from the remote processor through Virtio’s vrings. When a new message is already in the shared memory, the mailbox framework notifies the processor that a message is available to be received.

RPMsg is actually a message bus based on Virtio, used to implement message passing (transferring inter-core data). It can be considered that RPMsg is a channel for communicating with remote processors, which we can also call an RPMsg device. Each channel has a local source address and a remote destination address, and messages are transmitted between the source and destination addresses. The communication process is shown in the figure below:

Communication Process Diagram
Communication Process Diagram

For RPMsg, refer to:

rpmsg.drawio
rpmsg.drawio

Based on these software frameworks, all data is transmitted over RPMsg. RPMsg transfers data to the RPMsg client in the kernel layer, and then transmits it to the user space through the device node under the kernel. Combining the hierarchical relationship of the network TCP/IP structure, shared memory and inter-core interrupts are equivalent to the physical hardware layer, Virtio is equivalent to the MAC sublayer, and RPMsg is equivalent to the transport layer, as shown in the following figure:

RPMsg Analogy to TCP/IP Structural Relationship
RPMsg Analogy to TCP/IP Structural Relationship

remoteproc

For SoCs with asymmetric multiprocessing, different cores may run different operating systems. For example, the Cortex-A7 of the STM32MP157 runs the Linux operating system, while the Cortex-M4 can run the OneOS operating system or bare-metal programs.

To enable easy communication between the main processor running Linux and the coprocessor, the Remoteproc inter-core communication framework was introduced after Linux version 3.4.X. The Remoteproc framework was developed by Texas Instruments. Based on this, Mentor Graphics developed a software framework called OpenAMP. Under this framework, the Linux operating system on the main processor can perform lifecycle management of the remote processor and its related software environment, i.e., starting or shutting down the remote processor.

Let’s take the STM32MP157 as an example to look at the Remoteproc framework for M4 and A7, as shown in the following figure:

Remoteproc Framework
Remoteproc Framework

Remoteproc is the general remote processing framework part, and its functions are:

  1. A7 loads the code segment and data segment of the M4 firmware image into the M4 memory for in-place execution of the program;
  2. Parsing the firmware resource table to set up associated resources (such as the start address and size of each segment in the firmware, Virtio device features, vring address, size, and alignment information);
  3. Controlling the startup and shutdown of the M4 core firmware;
  4. Establishing an RPMsg communication channel for communication with M4;
  5. Providing monitoring and debugging of remote services (using the sysfs and debugfs file systems, which are already configured by default in the Linux file system of the development board and are ready to use upon boot).

Note: RPMsg communication uses Mailbox, but this is not well reflected in the diagram. The general process can be understood as: Remoteproc loads the firmware into the M core, and message transmission needs to go through the channel established after initialization. In the diagram, RCC, etc., are automatically configured by stm32 after the firmware image is loaded_rproc automatically, that is, stm32_rproc is the backend driver of Remoteproc, which will perform a series of subsequent operations.

stm32_rproc is the driver for the remote processor (M4 core), and its functions are:

  1. Registering vendor-specific functions with the Remoteproc framework (such as callback functions);
  2. Handling platform resources associated with M4 (such as registers, watchdog, reset, clock, and memory);
  3. Forwarding notifications to M4 through the Mailbox framework.

The firmware mentioned above is the executable file of M4, such as the one compiled under MDK.axffile or the one compiled under STM32CubeIDE.elffile.

A7 is called the main processor, and M4 is called the coprocessor or remote processor. The main processor starts first, and then boots the coprocessor:

  • The host processor can first load the coprocessor’s firmware through the Remoteproc framework, and then parse the information published in the firmware resource table to configure the coprocessor’s system resources and create Virtio devices
  • Once the Remoteproc on the host processor loads and starts the firmware of the remote processor, the coprocessor begins to run.
  • After the coprocessor starts, inter-core communication between the two cores is not yet possible. An RPMsg channel needs to be created first, and only after the host processor sends the first message can inter-core communication and data exchange between the two cores take place.
  • If it is necessary to stop running the firmware, the host processor can also shut down the firmware, and the coprocessor program will stop running immediately. In summary, the Remoteproc framework implements the management (LCM) and control of the remote coprocessor’s lifecycle, as shown in the figure below:

Remoteproc controls the coprocessor
Remoteproc controls the coprocessor

The relevant code is located atlinux-5.10.256/drivers/remoteproc

Summary

Based on the above analysis, the OpenAMP open-source software framework has the following functions and features:

  • Provides remote processor lifecycle management and inter-processor communication functions;
  • Provides independent libraries that can be used in RTOS and bare-metal software environments;
  • Compatible with upstream Linux Remoteproc, RPMsg, and VirtIO components.

The process of implementing inter-core communication using OpenAMP:

Assume that the host processor is already running and the remote processor is in a certain state, such as standby or powered off

  1. Based on the Remoteproc framework, the host processor first loads the firmware of the remote processor into memory
  2. Then the host processor starts the remote processor (runs the firmware) and waits for it to complete initialization, such as wake-up, de-reset, power-on, etc.
  3. The remote processor notifies the host processor after initialization is complete
  4. The host processor and the remote processor establish an RPMsg communication channel
  5. Through the RPMsg channel, the two can perform inter-core communication.

Reference materials