From d7d48b6cd217a1806ef31fb7d00e0dcb9e9e1fb0 Mon Sep 17 00:00:00 2001 From: Damian Krolik Date: Sun, 28 Apr 2024 02:24:27 +0200 Subject: [PATCH] nrf_rpc: Add initial protocol specification Add initial version of the nRF RPC protocol specification that describes the nRF RPC packet format. Signed-off-by: Damian Krolik --- nrf_rpc/README.rst | 22 +++-- nrf_rpc/doc/protocol_specification.rst | 125 +++++++++++++++++++++++++ 2 files changed, 138 insertions(+), 9 deletions(-) create mode 100644 nrf_rpc/doc/protocol_specification.rst diff --git a/nrf_rpc/README.rst b/nrf_rpc/README.rst index 2ef6ee0f49..f502869c24 100644 --- a/nrf_rpc/README.rst +++ b/nrf_rpc/README.rst @@ -3,19 +3,22 @@ Remote procedure call library (nRF RPC) ####################################### -nRF RPC is a remote procedure call library for |NCS| enabling inter-processor communication on Nordic Semiconductor SoCs. -The library is RTOS-agnostic and implements serialization of function calls. -It is designed to be used with an underlying transport layer, for example `OpenAMP`_. +nRF RPC is a remote procedure call library for enabling inter-processor communication on Nordic Semiconductor SoCs. +The library provides a framework for function call serialization. +It is RTOS-agnostic and designed to be used with an underlying transport layer, such as one based on `OpenAMP`_. -The nRF RPC library allows for calling a function on remote processors from a local processor, in both synchronous and asynchronous way. +The nRF RPC library allows for calling a function on a remote processor from a local processor, in both synchronous and asynchronous way. +The library simplifies: -Depending on the transport layer, the remote processor is not limited to a single device. -It can also be a separate device of any type (for example, a PC), or another core on the same system. +* The serialization of user APIs, such as those of a Bluetooth stack. +* The execution of functions implementing those APIs on a remote processor. -The nRF RPC library simplifies the serialization of user APIs, such as a Bluetooth stack, and executing of functions implementing those APIs on a remote CPU. -The library is operating system independent so it can be used with any operating system after porting the OS-dependent layers of the library. +Depending on the transport layer, the local and remote processors are not confined to just one device. +The remote processor can be located on a separate device of any kind, such as a PC, or it can be another CPU core within the same device. -The API layer on top of the core nRF RPC API uses the `zcbor`_ library for serialization. +The library can be used with any operating system after porting the OS-dependent layers of the library. + +The CBOR API layer on top of the core nRF RPC API uses the `zcbor`_ library for serializing the function arguments and return values. .. toctree:: :maxdepth: 2 @@ -23,5 +26,6 @@ The API layer on top of the core nRF RPC API uses the `zcbor`_ library for seria doc/architecture doc/usage + doc/protocol_specification CHANGELOG doc/api diff --git a/nrf_rpc/doc/protocol_specification.rst b/nrf_rpc/doc/protocol_specification.rst new file mode 100644 index 0000000000..c298e97cc0 --- /dev/null +++ b/nrf_rpc/doc/protocol_specification.rst @@ -0,0 +1,125 @@ +.. _nrf_rpc_protocol_specification: + +nRF RPC protocol specification +############################## + +.. contents:: + :local: + :depth: 2 + +Two processors that communicate with each other using the remote procedure call (nRF RPC) library follow the nRF RPC protocol. +The nRF RPC protocol specifies the binary format and rules for constructing packets that are exchanged within an nRF RPC communication. + +The nRF RPC packets that are constructed by the nRF RPC core library are relayed to the selected transport layer, where they can be additionally encoded to ensure a reliable delivery of the packet to the other processor using the selected medium. +The nRF RPC transport's specification is outside the scope of this document. + +The types of communication, threading model and other general concepts of the nRF RPC are described in :ref:`nrf_rpc_architecture`. + +nRF RPC packet format +********************* + +Each nRF RPC packet consists of a 5-byte header and an optional, variable-length payload: + +.. table:: + :align: center + + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + |0 |1 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + |0 |1 |2 |3 |4 |5 |6 |7 |0 |1 |2 |3 |4 |5 |6 |7 | + +===+===+===+===+===+===+===+===+===+===+===+===+===+===+===+===+ + | Type [\| Source Context ID] | Command ID | + +-------------------------------+-------------------------------+ + | Destination Context ID | Source Group ID | + +-------------------------------+-------------------------------+ + | Destination Group ID | [Payload...] | + +-------------------------------+-------------------------------+ + | [...] | + +---------------------------------------------------------------+ + +A description of the various fields and their meaning: + +``Type [| Source Context ID]``: 8 bits + The packet type determines the function of the packet and it can be one of the following values: + + * ``0x00`` - event + * ``0x01`` - response + * ``0x02`` - event acknowledgment + * ``0x03`` - error report + * ``0x04`` - initialization packet + * ``0x80`` - command + + If the packet type is ``0x80`` (command), this field is additionally bitwise ORed with the source context ID. + + The source context ID is a numeric identifier of the conversation to which the packet is associated, chosen by the packet sender. + + The source context ID is a feature of the nRF RPC protocol that facilitates concurrent conversations. + When two threads on the local processor want to start an nRF RPC conversation at the same time, they shall use distinct source context IDs when constructing a packet to the remote processor. + The remote processor is then obliged to use the source context ID as the destination context ID in the response packet. + This ensures that responses and any packets that follow within each conversation are correctly routed to the initiating thread. + + The exact source context ID allocation pattern is implementation-defined, meaning that when the packet sender intiates a new conversation or responds to the initiating packet, it is free to allocate any unused source context ID for the new conversation. + +``Command ID``: 8 bits + Identifies an individual command or event within an nRF RPC group. + + If the packet is a **response** or an **initialization packet**, this field has no meaning and shall be set to ``0xff``. + +``Destination Context ID``: 8 bits + A numeric identifier of the conversation to which the packet is associated, chosen by the packet receiver. + + In a packet that starts a new conversation, this field shall be assigned the value ``0xff`` (indicating it is unknown). + In all subsequent packets within the conversation, the sender of the packet shall carry over the source context ID that was included in the last packet received from the peer. + +``Source Group ID``: 8 bits + A numeric identifier of the nRF RPC group associated with the packet, chosen by the packet sender. + + Each processor that uses the nRF RPC protocol chooses unique numeric identifiers for all nRF RPC groups that it supports. + During the nRF RPC protocol initialization, it then communicates its own mapping of the pre-shared string group identifiers to these unique numeric identifiers. + +``Destination Group ID``: 8 bits + A numeric identifier of the nRF RPC group associated with the packet, chosen by the packet receiver. + + The sender learns this identifier by receiving an **initialization packet** from the peer during the nRF RPC protocol initialization. + +``Payload``: variable length + The payload format depends on the packet type: + + * **event acknowledgment** - the payload is empty. + * **error report** - the payload is a 32-bit integer representing an error code, in little-endian byte order. + * **initialization packet** - the payload has the following format: + + .. table:: + :align: center + + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + |0 |1 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + |0 |1 |2 |3 |4 |5 |6 |7 |0 |1 |2 |3 |4 |5 |6 |7 | + +===+===+===+===+===+===+===+===+===+===+===+===+===+===+===+===+ + | Max Version | Min Version | Group name.... | + +---------------+---------------+-------------------------------+ + | ... | + +---------------------------------------------------------------+ + + The ``Min Version`` and ``Max Version`` fields indicate the minimum and maximum version of the nRF RPC protocol supported by the sender. + The ``Group name`` field has a variable length and contains the string identifier of the nRF RPC group to which this packet is associated with, without the null terminator. + + * **event**, **response**, **command** - the payload contains remote procedure call arguments or return values, represented in an implementation-defined format. + + If the nRF RPC protocol is used together with the CBOR encoding, then the arguments and return values are represented as a sequence of CBOR data items, terminated by the null data item (``0xf6``). + + For example, if a packet is an nRF RPC command that represents the C function call ``foo(100, "bar")``, the packet might look as follows: + + .. code-block:: none + + 80 01 ff 00 00 18 64 63 62 61 72 f6 + + 80: Command | Source Context ID (0) + 01: Command ID (1) + ff: Destination Context ID (unknown) + 00: Source Group ID (0) + 00: Destination Group ID (0) + 18 64: CBOR unsigned int (100) + 63 62 61 72: CBOR text string ("bar") + f6: CBOR null