mirror of
https://github.com/apache/nuttx.git
synced 2026-05-28 03:45:50 +08:00
Documentation/rpmsg: add RPMsg Port UART transport documentation
Add documentation for RPMsg Port UART, a transport layer that enables RPMsg communication between SoCs via UART when shared memory is not available. The documentation covers: - Hardware requirements (UART with flow control) - Software architecture - Escape coding protocol for command/data separation - Connection establishment protocol - Data frame format - Low power support with ping-pong wake mechanism Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
This commit is contained in:
@@ -11,3 +11,4 @@ for inter-processor communication in Asymmetric Multiprocessing (AMP) systems.
|
||||
|
||||
concepts
|
||||
rpmsg_port
|
||||
rpmsg_port_uart
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
RPMsg Port UART
|
||||
===============
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
RPMsg Port UART is a transport layer implementation that enables RPMsg
|
||||
communication between two SoCs connected via UART. This is useful when
|
||||
shared memory is not available between chips, such as two separate chips
|
||||
on the same PCB.
|
||||
|
||||
Hardware Requirements
|
||||
---------------------
|
||||
|
||||
The UART interface requires four signals with hardware flow control support:
|
||||
|
||||
::
|
||||
|
||||
┌─────────────┐ ┌─────────────┐
|
||||
│ SoC A │ │ SoC B │
|
||||
│ │ TX ────────> │ │
|
||||
│ UART │ RX <──────── │ UART │
|
||||
│ │ RTS ────────> │ │
|
||||
│ │ CTS <──────── │ │
|
||||
└─────────────┘ └─────────────┘
|
||||
|
||||
Requirements:
|
||||
|
||||
- Hardware flow control (RTS/CTS) must be supported to prevent data loss
|
||||
- RX pin should support wake-up for low power mode
|
||||
- Data corruption during wake-up is not allowed, but data loss is acceptable
|
||||
(handled by software)
|
||||
|
||||
Software Architecture
|
||||
---------------------
|
||||
|
||||
::
|
||||
|
||||
┌────────────────────────────────────────┐
|
||||
│ RPMsg Framework │
|
||||
├────────────────────────────────────────┤
|
||||
│ RPMsg Port │
|
||||
│ (Buffer Management, Name Service) │
|
||||
├────────────────────────────────────────┤
|
||||
│ RPMsg Port UART │
|
||||
│ (Escape Coding, Connection Protocol, │
|
||||
│ Data Transfer, Low Power Support) │
|
||||
├────────────────────────────────────────┤
|
||||
│ UART Driver │
|
||||
└────────────────────────────────────────┘
|
||||
|
||||
Protocol Details
|
||||
----------------
|
||||
|
||||
Escape Coding
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Special characters (0x70-0x7f) are used to distinguish commands from data:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define RPMSG_PORT_UART_START 0x7f /* Frame start */
|
||||
#define RPMSG_PORT_UART_END 0x70 /* Frame end */
|
||||
#define RPMSG_PORT_UART_ESCAPE 0x7c /* Escape character */
|
||||
#define RPMSG_PORT_UART_CONNREQ 0x7e /* Connection request */
|
||||
#define RPMSG_PORT_UART_CONNACK 0x7d /* Connection acknowledge */
|
||||
#define RPMSG_PORT_UART_ESCAPE_MASK 0x20 /* Escape XOR mask */
|
||||
|
||||
Encoding example:
|
||||
|
||||
::
|
||||
|
||||
Original: [0x01, 0x7f, 0x02, 0x70, 0x03]
|
||||
Encoded: [START] [0x01] [ESC] [0x5f] [0x02] [ESC] [0x50] [0x03] [END]
|
||||
[0x7f] [0x01] [0x7c][0x5f] [0x02] [0x7c][0x50] [0x03] [0x70]
|
||||
|
||||
When a byte falls in the 0x70-0x7f range, it is escaped by sending the
|
||||
ESCAPE character followed by the original byte XORed with 0x20.
|
||||
|
||||
Connection Protocol
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The connection protocol supports:
|
||||
|
||||
- Either side can start first during system boot
|
||||
- Reconnection after either side restarts
|
||||
|
||||
::
|
||||
|
||||
Normal startup:
|
||||
┌────────┐ ┌────────┐
|
||||
│ CPU A │ │ CPU B │
|
||||
└────────┘ └────────┘
|
||||
│ │
|
||||
│ ──── CONNREQ (0x7e) ────────> │
|
||||
│ │ Initialize resources
|
||||
│ <──── CONNACK (0x7d) ──────── │
|
||||
│ Initialize resources │
|
||||
│ │
|
||||
│ Connection established │
|
||||
|
||||
Restart scenario (CPU B restarts):
|
||||
┌────────┐ ┌────────┐
|
||||
│ CPU A │ │ CPU B │
|
||||
│(running)│ │(restart)│
|
||||
└────────┘ └────────┘
|
||||
│ │
|
||||
│ <──── CONNREQ (0x7e) ──────── │
|
||||
│ Reinitialize resources │
|
||||
│ ──── CONNACK (0x7d) ────────> │
|
||||
│ │ Initialize resources
|
||||
│ Connection established │
|
||||
|
||||
Data Frame Format
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
┌───────┬─────────────────────────────────┬───────┐
|
||||
│ START │ Header + Payload (escaped) │ END │
|
||||
│ 0x7f │ │ 0x70 │
|
||||
└───────┴─────────────────────────────────┴───────┘
|
||||
|
||||
Header structure (rpmsg_port_header_s):
|
||||
┌────────┬────────┬────────┬────────┬──────────────┐
|
||||
│ crc │ cmd │ avail │ len │ payload │
|
||||
│ 2 byte │ 2 byte │ 2 byte │ 2 byte │ N bytes │
|
||||
└────────┴────────┴────────┴────────┴──────────────┘
|
||||
|
||||
- crc: CRC16 checksum (optional, enabled via CONFIG_RPMSG_PORT_UART_CRC)
|
||||
- cmd: Command field (unused for data frames, set to 0)
|
||||
- avail: Available space (unused for data frames, set to 0)
|
||||
- len: Total length including header
|
||||
- payload: Actual RPMsg data
|
||||
|
||||
Low Power Support
|
||||
-----------------
|
||||
|
||||
RPMsg Port UART implements low power support without additional GPIOs using
|
||||
special wake/sleep commands:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define RPMSG_PORT_UART_STAYWAKE1 0x79 /* Wake request 1 */
|
||||
#define RPMSG_PORT_UART_STAYWAKEACK1 0x78 /* Wake acknowledge 1 */
|
||||
#define RPMSG_PORT_UART_STAYWAKE2 0x75 /* Wake request 2 */
|
||||
#define RPMSG_PORT_UART_STAYWAKEACK2 0x74 /* Wake acknowledge 2 */
|
||||
#define RPMSG_PORT_UART_RELAXWAKE 0x77 /* Allow sleep */
|
||||
|
||||
Wake/Sleep Flow
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
┌────────┐ ┌────────┐
|
||||
│ CPU A │ │ CPU B │
|
||||
│(sender)│ │(asleep)│
|
||||
└────────┘ └────────┘
|
||||
│ │
|
||||
│ Acquire TX PM lock │
|
||||
│ ──── STAYWAKE1 ──────────────────> │
|
||||
│ │ Acquire RX PM lock
|
||||
│ <──── STAYWAKEACK1 ─────────────── │
|
||||
│ │
|
||||
│ ════ Data Transfer ══════════════> │
|
||||
│ │
|
||||
│ ──── RELAXWAKE ──────────────────> │
|
||||
│ Release TX PM lock │ Release RX PM lock
|
||||
│ │
|
||||
|
||||
Ping-Pong Wake Mechanism
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Two sets of wake commands (STAYWAKE1/ACK1 and STAYWAKE2/ACK2) are used
|
||||
alternately to prevent false wake acknowledgments:
|
||||
|
||||
::
|
||||
|
||||
First transfer: STAYWAKE1 → STAYWAKEACK1 → Data → RELAXWAKE
|
||||
Second transfer: STAYWAKE2 → STAYWAKEACK2 → Data → RELAXWAKE
|
||||
Third transfer: STAYWAKE1 → STAYWAKEACK1 → Data → RELAXWAKE
|
||||
...
|
||||
|
||||
This prevents the sender from mistakenly accepting a delayed ACK from a
|
||||
previous transfer as confirmation for the current transfer.
|
||||
|
||||
Source Files
|
||||
------------
|
||||
|
||||
- ``nuttx/drivers/rpmsg/rpmsg_port_uart.c``
|
||||
Reference in New Issue
Block a user