- Note
- These APIs are to be used from NORTOS/RTOS. When working with Linux on A53 refer to Linux documentation for Linux side APIs.
Features Supported
- RP Message + VRING protocol implementation
- Uses IPC Notify underneath for interrupts and uses shared memory (VRING) for message buffers
- Uses 'IPC Notify' underneath for interrupts and uses shared memory (VRING) for message buffers
- Supports message passing between NORTOS, FreeRTOS and Linux based CPUs
- Logical communication channels can be created using unique "end points". This allows multiple tasks on a CPU to talk to multiple tasks on another CPU using the same underlying HW mailbox and shared memory.
- Between NORTOS and RTOS, below can be configured in RP Message to control the shared memory size,
- Max message size, default is 128 bytes
- Number of buffers in a VRING, default is 8 messages
- VRING shared memory buffer address can be configured, can be DDR or internal memory address.
- Between Linux and NORTOS/RTOS, the VRING parameters are fixed as below
- Max message is 512B
- NUmber of messages in a VRING is 256
- VRING shared memory address is determined by value in Linux device tree and is placed in DDR.
- APIs to send and receive messages to user specified end points
- Blocking, as well as non-blocking APIs with time out based blocking.
- APIs to announce a created end point, needed when talking to Linux
- API to sync and wait for LInux to be ready, needed when talking to Linux
- APIs to use callback to receive message notifications instead of blocking, see RPMessage_CreateParams for more details.
- APIs to use callback to receive and handle messages in callback itself, see RPMessage_CreateParams for more details.
- Logging to Linux shared memory when IPC with Linux is enabled. Allows to view logs from RTOS/NORTOS on Linux using Linux debugfs.
SysConfig Features
- Note
- It is strongly recommend to use SysConfig where it is available instead of using direct SW API calls. This will help simplify the SW application and also catch common mistakes early in the development cycle.
- Enable/Disable IPC RPMessage between different CPUs
- Enable IPC RPMessage between NORTOS/RTOS and Linux. When enabled, SysConfig generates the resource table that is needed to talk with Linux.
- Select RP Message max message size, number of buffer in a VRING
- Enable IPC RPMessage between NORTOS/RTOS and Linux. When enabled, SysConfig generates the resource table that is needed to talk with Linux.
Features NOT Supported
NA
Important Usage Guidelines
- Note
- It is strongly recommended to refer to the IPC examples
examples/drivers/ipc
to understand the linker command file setup for IPC applications.
- When Linux runs along side RTOS/NORTOS, do below to make sure NORTOS/RTOS can talk to Linux.
- Make sure to call RPMessage_waitForLinuxReady() before starting communication with Linux.
- Also for any RPMessage point created on NORTOS/RTOS, make sure to announce it to Linux using RPMessage_announce()
- Make sure to assign the shared memory used for VRING between Linux and this CPU as mentioned in the Linux device tree. Also make sure to mark this section as non-cached
- If the CPU code will run out of DDR, make sure to setup a MPU entry for the code/data section in DDR. This can be marked as cached.
- Again refer to Linux device tree to find out the space in DDR and MSMC where the NORTOS/RTOS applications can execute from.
- Make sure to assign the shared memory used for VRINGs between NORTOS/RTOS in a common memory section in each CPUs linker command file and make sure to mark this section as non-cached in the R5F MPU.
- Maximum Message size is limited to 1152 Bytes in Syscfg and the maximum number of buffers is limited to 16. The recommended approach is to keep the number of buffers and message size within this limit.
- If larger messages need to be passed, the data should be kept in a shared memory and a pointer to the same should be passed via IPC.
Example Usage
Include the below files to access the APIs
#include <stdio.h>
#include <string.h>
Define the following macros
#define IPC_RPMESSAGE_SERVICE_CHRDEV "rpmsg_chrdev"
#define IPC_RPMESSAGE_ENDPT_CHRDEV_PING (14U)
#define IPC_RPMESSAGE_MAX_MSG_SIZE (96u)
Setup resource table to be used by Linux, this snippet is for reference and is generated by SysConfig when SysConfig is used for IPC.
const RPMessage_ResourceTable gRPMessage_linuxResourceTable
__attribute__ ((section (
".resource_table"), aligned (4096))) =
{
{
1U,
2U,
{ 0U, 0U, }
},
{
offsetof(RPMessage_ResourceTable, vdev),
offsetof(RPMessage_ResourceTable, trace),
},
{
RPMESSAGE_RSC_TYPE_VDEV, RPMESSAGE_RSC_VIRTIO_ID_RPMSG,
0U, 1U, 0U, 0U, 0U, 2U, { 0U, 0U },
},
{ RPMESSAGE_RSC_VRING_ADDR_ANY, 4096U, 256U, 1U, 0U },
{ RPMESSAGE_RSC_VRING_ADDR_ANY, 4096U, 256U, 2U, 0U },
{
(RPMESSAGE_RSC_TRACE_INTS_VER0 | RPMESSAGE_RSC_TYPE_TRACE),
0, "trace:m4fss0_0",
},
};
Initialize IPC RPMessage, this snippet is for reference and is generated by SysConfig when SysConfig is used for IPC.
Define RPMessage_Object objects for receive endpoints,
Create RPMessage end points for receive endpoints,
createParams.
localEndPt = IPC_RPMESSAGE_ENDPT_CHRDEV_PING;
Receive message at MCU core from A53 Linux and send ack to A53 Linux,
while(1)
{
char recvMsg[IPC_RPMESSAGE_MAX_MSG_SIZE + 1];
char replyMsg[IPC_RPMESSAGE_MAX_MSG_SIZE + 1];
uint16_t recvMsgSize, remoteCoreId;
uint32_t remoteCoreEndPt;
recvMsgSize = sizeof(recvMsg);
recvMsg, &recvMsgSize,
&remoteCoreId, &remoteCoreEndPt,
strcpy(replyMsg, recvMsg);
replyMsg, strlen(replyMsg),
remoteCoreId, remoteCoreEndPt,
}
API
APIs for IPC RPMessage