Documents/rptun: add the new rptun framework documents

Rmove the old rptun document and add new folder to add the new
rptun frameworks documents.

Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
This commit is contained in:
Bowen Wang
2026-01-16 10:43:23 +08:00
committed by GUIDINGLI
parent 1fa6a43a40
commit 949b519aa5
8 changed files with 854 additions and 25 deletions
+1 -1
View File
@@ -206,7 +206,7 @@ Subdirectories of ``nuttx/drivers``
RF Device Support. RF Device Support.
* ``rptun/`` :doc:`special/rptun` * ``rptun/`` :doc:`special/rptun/index`
Remote Proc Tunnel Driver Support. Remote Proc Tunnel Driver Support.
@@ -35,7 +35,7 @@ following section.
mtd/index.rst mtd/index.rst
regmap.rst regmap.rst
reset.rst reset.rst
rptun.rst rptun/index.rst
rwbuffer.rst rwbuffer.rst
sensors.rst sensors.rst
segger.rst segger.rst
@@ -1,23 +0,0 @@
==========================
Remote Proc Tunnel Drivers
==========================
RPTUN driver is used for multi-cores' communication.
Supported RPTUN drivers:
- RPMSG File System
- RPMSG domain (remote) sockets
- RPMSG UART Driver
- RPMSG net Driver
- RPMSG Usersock
- RPMSG Sensor Driver
- RPMSG RTC Driver
- RPMSG MTD
- RPMSG Device
- RPMSG Block Driver
- RPMSG IO expander
- RPMSG uinput
- RPMSG clk Driver
- RPMSG syslog
- RPMSG regulator
@@ -0,0 +1,226 @@
=============
API Reference
=============
This section describes the kernel APIs and NSH commands available for
RPTUN operations.
Kernel API
==========
rptun_initialize
----------------
.. c:function:: int rptun_initialize(FAR struct rptun_dev_s *dev)
Initialize and register an RPTUN device.
:param dev: Pointer to the RPTUN device structure with ops configured
:return: OK on success; a negated errno value on failure
This function creates an RPTUN instance and registers it with the system.
If the device is configured for auto-start, it will also start the
remote core.
rptun_boot
----------
.. c:function:: int rptun_boot(FAR const char *cpuname)
Start the remote CPU.
:param cpuname: Name of the remote CPU to start
:return: OK on success; a negated errno value on failure
Example:
.. code-block:: c
/* Start remote CPU named "M33" */
ret = rptun_boot("M33");
if (ret < 0)
{
syslog(LOG_ERR, "Failed to boot remote CPU: %d\n", ret);
}
rptun_poweroff
--------------
.. c:function:: int rptun_poweroff(FAR const char *cpuname)
Stop the remote CPU.
:param cpuname: Name of the remote CPU to stop
:return: OK on success; a negated errno value on failure
Example:
.. code-block:: c
/* Stop remote CPU named "M33" */
ret = rptun_poweroff("M33");
rptun_reset
-----------
.. c:function:: int rptun_reset(FAR const char *cpuname, int value)
Reset the remote CPU.
:param cpuname: Name of the remote CPU to reset
:param value: Reset value (implementation-specific)
:return: OK on success; a negated errno value on failure
Example:
.. code-block:: c
/* Reset remote CPU named "M33" */
ret = rptun_reset("M33", 0);
IOCTL Commands
==============
The RPTUN character device supports the following ioctl commands:
RPTUNIOC_START
--------------
Start the remote CPU associated with this RPTUN device.
.. code-block:: c
int fd = open("/dev/rptun/remote", O_RDWR);
ret = ioctl(fd, RPTUNIOC_START, 0);
RPTUNIOC_STOP
-------------
Stop the remote CPU associated with this RPTUN device.
.. code-block:: c
ret = ioctl(fd, RPTUNIOC_STOP, 0);
RPTUNIOC_RESET
--------------
Reset the remote CPU associated with this RPTUN device.
.. code-block:: c
int reset_value = 0;
ret = ioctl(fd, RPTUNIOC_RESET, reset_value);
NSH Commands
============
The ``rptun`` NSH command provides user-space control over RPTUN devices.
rptun start
-----------
Start the remote core.
::
nsh> rptun start /dev/rptun/<cpuname>
Example:
::
nsh> rptun start /dev/rptun/M33
rptun stop
----------
Stop the remote core.
::
nsh> rptun stop /dev/rptun/<cpuname>
Example:
::
nsh> rptun stop /dev/rptun/M33
Configuration Options
=====================
The following Kconfig options are available for RPTUN:
CONFIG_RPTUN
------------
Enable RPTUN driver support.
CONFIG_RPTUN_PRIORITY
---------------------
RPTUN thread priority. Default is 224.
CONFIG_RPTUN_STACKSIZE
----------------------
RPTUN thread stack size. Default is 4096.
Header Files
============
- ``include/nuttx/rptun/rptun.h`` - Main RPTUN header file containing
all structures, macros, and function prototypes.
Access Macros
=============
The following macros are provided for accessing RPTUN operations:
.. code-block:: c
/* Get local CPU name */
RPTUN_GET_LOCAL_CPUNAME(dev)
/* Get remote CPU name */
RPTUN_GET_CPUNAME(dev)
/* Get firmware path */
RPTUN_GET_FIRMWARE(dev)
/* Get address environment */
RPTUN_GET_ADDRENV(dev)
/* Get resource table */
RPTUN_GET_RESOURCE(dev)
/* Check if auto-start is enabled */
RPTUN_IS_AUTOSTART(dev)
/* Check if this is the master core */
RPTUN_IS_MASTER(dev)
/* Configure remote core */
RPTUN_CONFIG(dev, data)
/* Start remote core */
RPTUN_START(dev)
/* Stop remote core */
RPTUN_STOP(dev)
/* Send notification to remote core */
RPTUN_NOTIFY(dev, vqid)
/* Register callback for remote notifications */
RPTUN_REGISTER_CALLBACK(dev, callback, arg)
/* Unregister callback */
RPTUN_UNREGISTER_CALLBACK(dev)
/* Reset remote core */
RPTUN_RESET(dev, value)
/* Trigger panic on remote core */
RPTUN_PANIC(dev)
@@ -0,0 +1,189 @@
============
Architecture
============
RPTUN sits at the system's lower level, bridging the upper-level VirtIO/Vhost
drivers with the underlying OpenAMP framework.
Overview
========
The RPTUN architecture consists of the following layers:
::
+------------------+ +------------------+
| VirtIO Drivers | | Vhost Drivers |
+--------+---------+ +--------+---------+
| |
v v
+----------------------------------------+
| VirtIO/Vhost Bus |
+----------------------------------------+
| |
v v
+----------------------------------------+
| RPTUN Framework |
| +----------------------------------+ |
| | RPTUN Remoteproc | |
| | (Lifecycle Management) | |
| +----------------------------------+ |
| +----------------------------------+ |
| | VirtIO/Vhost RPTUN | |
| | (Transport Layer) | |
| +----------------------------------+ |
+----------------------------------------+
|
v
+----------------------------------------+
| RPTUN Driver (BSP) |
| (Platform-specific Implementation) |
+----------------------------------------+
|
v
+----------------------------------------+
| OpenAMP |
+----------------------------------------+
Component Description
=====================
RPTUN Remoteproc
----------------
- **Function**: Based on OpenAMP's Remoteproc functionality, implements
lifecycle management of remote CPUs (start, stop, reset, etc.). It depends
on the underlying driver (RPTUN Driver) to provide chip-specific
implementations related to startup, shutdown, and interrupts.
- **User Interface**: Registers character devices through the Virtual File
System (VFS), allowing user space to control remote CPUs using ``ioctl()``
system calls or NuttShell (NSH) commands.
VirtIO/Vhost RPTUN
------------------
- **Function**: Utilizes shared memory and inter-core interrupts provided by
Remoteproc to implement a VirtIO-standard compatible Remoteproc transport
layer, enabling VirtIO/Vhost drivers to communicate across cores.
- **Interaction**: RPTUN associates with the VirtIO/Vhost framework through
the ``virtio/vhost_register_device()`` interface.
RPTUN Driver (Adaptation Layer)
-------------------------------
- **Function**: Implements chip-specific functionality related to lifecycle
management, shared memory, and inter-core interrupts.
- **Responsibilities**:
- Remote CPU start/stop functionality
- Provide shared memory regions (address and size)
- Implement inter-core interrupt sending (notify) and reception handling
- Provide physical-to-device address translation tables for shared memory
Initialization and Startup
==========================
Driver Initialization
---------------------
The platform driver calls ``rptun_initialize()`` to create and register an
RPTUN instance. Each instance manages a communication channel with a remote
CPU. The channel name can be specified through the ``rptun_ops->get_cpuname()``
interface. If communication with multiple remote cores is needed, multiple
RPTUN instances must be created.
Core Service Startup
--------------------
RPTUN's core service is started through ``rptun_dev_start()``. This function
creates a kernel thread to execute time-consuming tasks. There are two startup
modes:
- **Auto Start**: If the driver is configured for auto-start
(``RPTUN_IS_AUTOSTART()`` returns true), ``rptun_initialize()`` will
automatically call ``rptun_dev_start()``.
- **Manual Start**: After driver initialization, users can manually trigger
the startup process through the NSH command
``rptun start /dev/rptun/<cpuname>`` or ``ioctl()`` system call.
Core Initialization Tasks
-------------------------
In the startup thread, RPTUN performs the following key operations:
1. Configure Remoteproc
2. Obtain and parse the Resource Table provided by the driver
3. Create VirtIO/Vhost devices based on information in the Resource Table
4. Register created devices to the VirtIO/Vhost bus
5. Register interrupt callback function ``rptun_callback()`` through
``ops->register_callback()`` to respond to interrupt notifications
from the remote core
Remote CPU Lifecycle Management
===============================
RPTUN Remoteproc provides two ways for users and kernel code to manage
remote CPUs:
User Space Interface
--------------------
- **NSH Commands**: Use ``rptun start <dev>`` and ``rptun stop <dev>`` commands
- **Character Device**: Open device file ``/dev/rptun/<cpuname>``, then use
``ioctl()`` to send control codes like ``RPTUNIOC_START`` or ``RPTUNIOC_STOP``
Kernel Space API
----------------
Kernel modules can directly call API functions provided by RPTUN to control
remote CPUs. See :doc:`api_reference` for details.
VirtIO/Vhost Communication Flow
===============================
Device Initialization
---------------------
During RPTUN core service startup, it parses each VirtIO device defined in
the Resource Table, creates actual VirtIO devices, and registers them to
the VirtIO/Vhost bus. The main steps are:
1. **Parse Resources**: RPTUN framework parses the Resource Table, looking
for all vdev and carveout resources.
2. **Create Device Instance**: Based on found vdev resource information,
call OpenAMP interface ``remoteproc_create_virtio()`` to create VirtIO
device instances.
3. **Initialize Shared Memory Heap**: Based on corresponding carveout
resources, initialize an independent shared memory heap. This heap is
dedicated to the VirtIO device for dynamic data buffer management.
4. **Register Device**: Register the initialized VirtIO/Vhost device to
the system, making it visible to upper-layer applications.
5. **Loop Processing**: Repeat the above steps until all VirtIO devices
in the Resource Table are created and registered.
Interrupt Handling
------------------
**Interrupt Callback (Remote to Local)**
When the RPTUN driver receives an inter-core interrupt from the remote core,
it calls the registered ``rptun_callback()`` function. This function internally
calls ``remoteproc_get_notification()``, ultimately triggering the callback
function of the VirtIO/Vhost driver associated with that Virtqueue to process
received data.
**Interrupt Notification (Local to Remote)**
When a VirtIO/Vhost driver needs to notify the remote end (e.g., data has
been placed in the Virtqueue), it calls ``virtqueue_kick()``. This call
ultimately invokes the RPTUN framework's ``rptun_notify()`` function, which
then calls the driver-implemented ``ops->notify()`` function to trigger
hardware to send an inter-core interrupt.
@@ -0,0 +1,250 @@
=========================
Driver Porting Guide
=========================
The RPTUN framework is designed to be portable. It decouples from specific
hardware platforms through a set of callback functions defined in the
``rptun_ops`` structure. To support RPTUN on a new hardware platform,
platform driver developers must implement the following core interfaces
to meet the framework's operational requirements.
Driver Core Responsibilities
============================
Provide Resource Information
----------------------------
- The driver must define shared memory regions and correctly populate the
Resource Table within them.
- The driver needs to provide the Resource Table or remote firmware address
to the RPTUN framework through the ``get_resource()`` or ``get_firmware()``
interface.
Implement Core Operation Interfaces (rptun_ops)
-----------------------------------------------
**Lifecycle Management**
Provide underlying implementations for starting (``start``) and stopping
(``stop``) the remote core.
**Inter-core Communication**
- ``notify``: Implement the logic for sending notifications to the remote
core (typically triggering a hardware interrupt).
- ``register_callback``: Register a callback function that should be called
by the underlying interrupt service routine when receiving interrupts
from the remote core.
**Address Space Translation**
If the address spaces of the host core and remote core are inconsistent,
the ``get_addrenv()`` interface must be implemented to provide the address
translation table.
Associate Hardware Interrupts
-----------------------------
In the platform's Interrupt Service Routine (ISR), it must be able to
identify hardware interrupts from the remote core and accurately call
the callback function registered through ``register_callback``.
rptun_ops Structure
===================
Each RPTUN driver must implement an instance of ``struct rptun_ops_s``:
.. code-block:: c
struct rptun_ops_s
{
CODE FAR const char *(*get_local_cpuname)(FAR struct rptun_dev_s *dev);
CODE FAR const char *(*get_cpuname)(FAR struct rptun_dev_s *dev);
CODE FAR const char *(*get_firmware)(FAR struct rptun_dev_s *dev);
CODE FAR const struct rptun_addrenv_s *(*get_addrenv)(
FAR struct rptun_dev_s *dev);
CODE FAR struct rptun_rsc_s *(*get_resource)(FAR struct rptun_dev_s *dev);
CODE bool (*is_autostart)(FAR struct rptun_dev_s *dev);
CODE bool (*is_master)(FAR struct rptun_dev_s *dev);
CODE int (*config)(struct rptun_dev_s *dev, void *data);
CODE int (*start)(FAR struct rptun_dev_s *dev);
CODE int (*stop)(FAR struct rptun_dev_s *dev);
CODE int (*notify)(FAR struct rptun_dev_s *dev, uint32_t vqid);
CODE int (*register_callback)(FAR struct rptun_dev_s *dev,
rptun_callback_t callback, FAR void *arg);
CODE void (*reset)(FAR struct rptun_dev_s *dev, int value);
CODE void (*panic)(FAR struct rptun_dev_s *dev);
};
Interface Descriptions
======================
get_local_cpuname
-----------------
Returns the local CPU name string.
get_cpuname
-----------
Returns the remote CPU name string. This name is used to identify the
communication channel and register the character device.
get_firmware
------------
Returns the remote firmware file path. If the remote core firmware needs
to be loaded by the host core, this interface should return the firmware
path.
get_addrenv
-----------
Returns the address environment translation table. Used when physical
addresses differ between cores.
.. code-block:: c
struct rptun_addrenv_s
{
uintptr_t pa; /* Physical address on local core */
uintptr_t da; /* Device address on remote core */
size_t size; /* Size of the memory region */
};
get_resource
------------
Returns a pointer to the Resource Table. The driver must prepare the
Resource Table in shared memory and return its address through this
interface.
is_autostart
------------
Returns whether to automatically start the remote core. If ``true``,
``rptun_initialize()`` will automatically call ``rptun_dev_start()``.
is_master
---------
Returns whether the local core is the master. The master core is typically
responsible for initializing shared memory and the Resource Table.
config
------
Configures the remote core. Called before starting the remote core.
start
-----
Starts the remote core. Implements the hardware-specific startup sequence.
stop
----
Stops the remote core. Implements the hardware-specific shutdown sequence.
notify
------
Sends a notification to the remote core. Typically implemented by triggering
a hardware interrupt (e.g., mailbox, software interrupt).
register_callback
-----------------
Registers a callback function for receiving notifications from the remote
core. The driver's ISR should call this callback when an inter-core
interrupt is received.
reset
-----
Resets the remote core with the specified reset value.
panic
-----
Triggers a panic state on the remote core.
Example Implementation
======================
Here's a minimal example of implementing RPTUN driver operations:
.. code-block:: c
static FAR const char *myboard_rptun_get_cpuname(FAR struct rptun_dev_s *dev)
{
return "remote";
}
static FAR struct rptun_rsc_s *
myboard_rptun_get_resource(FAR struct rptun_dev_s *dev)
{
return &g_rptun_rsc; /* Pre-defined resource table */
}
static bool myboard_rptun_is_master(FAR struct rptun_dev_s *dev)
{
return true;
}
static int myboard_rptun_start(FAR struct rptun_dev_s *dev)
{
/* Hardware-specific remote core startup */
return OK;
}
static int myboard_rptun_stop(FAR struct rptun_dev_s *dev)
{
/* Hardware-specific remote core shutdown */
return OK;
}
static int myboard_rptun_notify(FAR struct rptun_dev_s *dev, uint32_t vqid)
{
/* Trigger inter-core interrupt */
return OK;
}
static int myboard_rptun_register_callback(FAR struct rptun_dev_s *dev,
rptun_callback_t callback,
FAR void *arg)
{
/* Store callback for ISR to use */
g_callback = callback;
g_arg = arg;
return OK;
}
static const struct rptun_ops_s g_myboard_rptun_ops =
{
.get_cpuname = myboard_rptun_get_cpuname,
.get_resource = myboard_rptun_get_resource,
.is_master = myboard_rptun_is_master,
.start = myboard_rptun_start,
.stop = myboard_rptun_stop,
.notify = myboard_rptun_notify,
.register_callback = myboard_rptun_register_callback,
};
Existing Implementations
========================
Reference implementations can be found in the following files:
- ``arch/sim/src/sim/sim_rptun.c`` - Simulator RPTUN driver
- ``arch/arm/src/stm32h7/stm32_rptun.c`` - STM32H7 RPTUN driver
- ``arch/arm/src/imx9/imx9_rptun.c`` - i.MX9 RPTUN driver
- ``arch/arm/src/nrf53/nrf53_rptun.c`` - nRF53 RPTUN driver
- ``arch/risc-v/src/k230/k230_rptun.c`` - K230 RPTUN driver
- ``arch/risc-v/src/qemu-rv/qemu_rv_rptun.c`` - QEMU RISC-V RPTUN driver
@@ -0,0 +1,61 @@
==========================
RPTUN (Remoteproc Tunnel)
==========================
RPTUN (Remoteproc Tunnel) is an efficient inter-core communication framework
based on OpenAMP. It primarily addresses the lifecycle management and data
exchange issues between the host core (running NuttX) and remote cores in
Asymmetric Multiprocessing (AMP) architectures.
The RPTUN framework consists of two core components:
- **RPTUN Remoteproc**: Manages the lifecycle of remote cores, including
start, stop, and reset operations.
- **VirtIO/Vhost RPTUN**: Serves as the transport layer for VirtIO, enabling
standard VirtIO/Vhost devices to communicate across physical cores.
Additionally, RPTUN exports standard character device interfaces to user space,
allowing developers to debug and control through command line or applications.
.. toctree::
:maxdepth: 2
architecture.rst
resource_table.rst
driver_porting.rst
api_reference.rst
Target Audience
===============
This documentation is intended for embedded system engineers who need to
develop and port multi-core systems in NuttX environment, including:
- Application developers who need to use RPTUN for inter-core communication.
- Driver developers who need to adapt RPTUN on new hardware platforms (BSP).
Supported RPTUN Services
========================
- RPMSG File System
- RPMSG Domain (Remote) Sockets
- RPMSG UART Driver
- RPMSG Net Driver
- RPMSG Usersock
- RPMSG Sensor Driver
- RPMSG RTC Driver
- RPMSG MTD
- RPMSG Device
- RPMSG Block Driver
- RPMSG IO Expander
- RPMSG uinput
- RPMSG CLK Driver
- RPMSG Syslog
- RPMSG Regulator
Source Files
============
- Framework implementation: ``nuttx/drivers/rptun/rptun.c``
- Public header file: ``nuttx/include/nuttx/rptun/rptun.h``
@@ -0,0 +1,126 @@
==============
Resource Table
==============
The Resource Table is a critical data structure defined in shared memory,
provided by the RPTUN driver to the RPTUN framework. It describes available
system resources.
Resource Table Contents
=======================
VirtIO Device (vdev resource)
-----------------------------
Defines the VirtIO device type, features, and Vring-related parameters.
Shared Memory Region (carveout resource)
----------------------------------------
Defines the physical address and size of shared memory used for Virtqueue,
data buffers, and special buffer regions.
Shared Memory Layout
====================
The shared memory used in the RPTUN framework is utilized by various elements
including Resource Table, Vrings, Vring Buffers, Carveout, etc. The layout
of this shared memory is crucial for the framework.
The RPTUN framework relies on the driver to declare a contiguous shared
memory block in the Resource Table. RPTUN builds the following structures
on this memory:
::
+------------------------------------------+
| Resource Table (RSC) |
| +------------------------------------+ |
| | VirtIO Device 0 Description | |
| | (vdev resource + carveout) | |
| +------------------------------------+ |
| | VirtIO Device 1 Description | |
| | (vdev resource + carveout) | |
| +------------------------------------+ |
| | ... | |
| +------------------------------------+ |
+------------------------------------------+
| Vrings |
| +------------------------------------+ |
| | Vring 0 (TX) | |
| +------------------------------------+ |
| | Vring 1 (RX) | |
| +------------------------------------+ |
+------------------------------------------+
| Carveout (Shared Heap) |
| (Dynamic allocation for Vring Buffers) |
+------------------------------------------+
Resource Table (RSC)
--------------------
Describes all shared resources. Its address is directly provided by the
driver to the RPTUN framework. RSC internally contains descriptions of
one or more VirtIO devices. Each VirtIO device is represented by a vdev
resource and a carveout resource together.
Vrings
------
Stores the ring buffer data structures for Virtqueue. Each vdev resource
describes multiple vrings according to the standard. The address allocation
rules are as follows:
- **Dynamic Allocation**: If the ``vring.da`` (device address) field in the
vdev resource of the Resource Table is 0 or ANY, the RPTUN framework will
automatically allocate a memory block from the carveout region for Vrings.
- **Static Specification**: If ``vring.da`` is a valid address, it indicates
that the driver has statically specified the memory location for Vrings,
and the framework will use that address directly.
Carveout (Shared Memory Heap)
-----------------------------
Each VirtIO device must correspond to a carveout resource to provide
dynamically allocated shared memory. The RPTUN framework uses the carveout
region (minus the portion possibly already allocated to Vrings) to initialize
an independent shared memory heap.
Upper-layer VirtIO/Vhost drivers can dynamically allocate and free data
buffers (Vring Buffers) transmitted in Vrings through this heap, achieving
flexible memory management.
Address Translation
===================
In AMP architectures, different cores may access the same shared memory
block at different physical addresses. To ensure pointer validity on the
remote core, when passing a local core's pointer to the remote end, the
address needs to be converted to an address accessible by the remote end.
The RPTUN framework obtains the address translation table through the
``get_addrenv()`` interface in ``rptun_ops``. When adapting drivers, if
there is a situation where physical addresses are inconsistent between
the two cores, this interface must be implemented.
Resource Table Structure
========================
The standard resource table structure used by RPTUN:
.. code-block:: c
struct aligned_data(8) rptun_rsc_s
{
struct resource_table rsc_tbl_hdr;
uint32_t offset[2];
struct fw_rsc_trace log_trace;
struct fw_rsc_vdev rpmsg_vdev;
struct fw_rsc_vdev_vring rpmsg_vring0;
struct fw_rsc_vdev_vring rpmsg_vring1;
struct fw_rsc_config config;
};
For detailed information about Resource Table, please refer to the
OpenAMP documentation.