I have create a communication protocol between core A53 and M40 on apalis IMX8 (using rpmsg character driver and using linux toradex 5.7.2). I created the endpoints successfully like the picture, but when I send message from A53, M4 cannot receive this message.
Here are my code on A53 and M4:
A53:
void IPCStateMachine::run(QQueue<IPCEventData> &eventQueue, QMutex &mutex)
{
msg_data_t data_buf = {
"Hello World!"
};
fprintf(stderr, "==========================\n");
fprintf(stderr, "* RPMsg Hello World demo *\n");
fprintf(stderr, "==========================\n");
fprintf(stderr, "Creating endpoint...\n");
struct rpmsg_endpoint_info ept_info = {"rpmsg-openamp-demo-channel", 0x2, 0x1e};
int fd = open("/dev/rpmsg_ctrl0", O_RDWR);
fprintf(stderr, "File descriptor created '%d'\n", fd);
fprintf(stderr, "Channel info: '%s' [ '%x' --> '%x' ]\n", ept_info.name, ept_info.src, ept_info.dst);
/* create endpoint interface */
int ret = ioctl(fd, RPMSG_CREATE_EPT_IOCTL, &ept_info); // /dev/rpmsg0 is created
fprintf(stderr, "Endpoint created\n");
if(ret < 0) qDebug() << "Failed to create ept!!!";
else qDebug() << "Success to create ept!!!";
/* create endpoint */
int fd_ept = open("/dev/rpmsg0", O_RDWR); // backend creates endpoint
if(fd_ept < 0)
{
qDebug() << "End point cannot created!";
}
fprintf(stderr, "Endpoint file descriptor created '%d'\n", fd_ept);
/* send data to remote device */
fprintf(stderr, "Sending...\n");
write(fd_ept, &data_buf, sizeof(data_buf));
/* receive data from remote device */
// fprintf(stderr, "Receiving...\n");
// read(fd_ept, &data_buf, sizeof(data_buf));
/* destroy endpoint */
fprintf(stderr, "Destroying endpoint...\n");
ioctl(fd_ept, RPMSG_DESTROY_EPT_IOCTL);
fprintf(stderr, "Endpoint destroyed\n");
close(fd_ept);
close(fd);
}
M4:
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rpmsg_lite.h"
#include "rpmsg_queue.h"
#include "rpmsg_ns.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "fsl_debug_console.h"
#include "FreeRTOS.h"
#include "task.h"
#include "fsl_lpuart.h"
#include "fsl_irqsteer.h"
#include "rsc_table.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define RPMSG_LITE_SHMEM_BASE (VDEV1_VRING_BASE)
#define RPMSG_LITE_LINK_ID (RL_PLATFORM_IMX8QM_M4_A_USER_LINK_ID)
#define RPMSG_LITE_NS_ANNOUNCE_STRING "rpmsg-openamp-demo-channel"
#define APP_TASK_STACK_SIZE (256)
#ifndef LOCAL_EPT_ADDR
#define LOCAL_EPT_ADDR (30)
#endif
/* Globals */
static char app_buf[512]; /* Each RPMSG buffer can carry less than 512 payload */
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
static TaskHandle_t app_task_handle = NULL;
static void ipcIf_nameservice_isr_cb(uint32_t new_ept, const char *new_ept_name, uint32_t flags, void *user_data)
{
}
static char helloMsg[13];
static void app_task(void *param)
{
volatile uint32_t remote_addr;
struct rpmsg_lite_endpoint *volatile my_ept;
volatile rpmsg_queue_handle my_queue;
struct rpmsg_lite_instance *volatile my_rpmsg;
void *rx_buf;
uint32_t len;
int32_t result;
void *tx_buf;
uint32_t size;
/* Print the initial banner */
PRINTF("\r\n...RPMSG String Echo FreeRTOS RTOS API Demo...v227\r\n");
#ifdef MCMGR_USED
uint32_t startupData;
/* Get the startup data */
(void)MCMGR_GetStartupData(kMCMGR_Core1, &startupData);
my_rpmsg = rpmsg_lite_remote_init((void *)startupData, RPMSG_LITE_LINK_ID, RL_NO_FLAGS);
/* Signal the other core we are ready */
(void)MCMGR_SignalReady(kMCMGR_Core1);
#else
my_rpmsg = rpmsg_lite_remote_init((void *)RPMSG_LITE_SHMEM_BASE, RPMSG_LITE_LINK_ID, RL_NO_FLAGS);
#endif /* MCMGR_USED */
while (0 == rpmsg_lite_is_link_up(my_rpmsg))
;
my_queue = rpmsg_queue_create(my_rpmsg);
my_ept = rpmsg_lite_create_ept(my_rpmsg, LOCAL_EPT_ADDR, rpmsg_queue_rx_cb, my_queue);
rpmsg_ns_bind(my_rpmsg, ipcIf_nameservice_isr_cb, NULL);
(void)rpmsg_ns_announce(my_rpmsg, my_ept, RPMSG_LITE_NS_ANNOUNCE_STRING, RL_NS_CREATE);
PRINTF("\r\nNameservice sent, ready for incoming messages, wait wait...\r\n");
for (;;)
{
// (void)rpmsg_ns_announce(my_rpmsg, my_ept, "Waiting for new data...", RL_NS_CREATE);
PRINTF("\nM4 Running.....");
/* Get RPMsg rx buffer with message */
/*result =*/ (void)rpmsg_queue_recv(my_rpmsg, my_queue, (uint32_t )&remote_addr, helloMsg, sizeof(helloMsg), ((void *)0),
RL_BLOCK + 2000);
// rpmsg_queue_recv_nocopy(my_rpmsg, my_queue, (uint32_t *)&remote_addr, (char **)&rx_buf, &len, RL_BLOCK + 2000);
PRINTF("\nRemote addr: %x", remote_addr);
if (result != 0)
{
// assert(false);
PRINTF("\nresult != 0");
continue;
}
PRINTF("\nM4 Running...1");
/* Copy string from RPMsg rx buffer */
// assert(len < sizeof(app_buf));
memcpy(app_buf, rx_buf, len);
app_buf[len] = 0; /* End string by '\0' */
if ((len == 2) && (app_buf[0] == 0xd) && (app_buf[1] == 0xa))
PRINTF("Get New Line From Master Side\r\n");
else
PRINTF("Get Message From Master Side : \"%s\" [len : %d]\r\n", app_buf, len);
/* Get tx buffer from RPMsg */
tx_buf = rpmsg_lite_alloc_tx_buffer(my_rpmsg, &size, RL_BLOCK);
// assert(tx_buf);
/* Copy string to RPMsg tx buffer */
memcpy(tx_buf, app_buf, len);
PRINTF("\nM4 Running...2");
/* Echo back received message with nocopy send */
result = rpmsg_lite_send_nocopy(my_rpmsg, my_ept, remote_addr, tx_buf, len);
if (result != 0)
{
// assert(false);
PRINTF("\nresult != 0 .. 2");
continue;
}
PRINTF("\nM4 Running...3");
/* Release held RPMsg rx buffer */
result = rpmsg_queue_nocopy_free(my_rpmsg, rx_buf);
if (result != 0)
{
// assert(false);
PRINTF("\nresult != 0 .. 3");
continue;
}
}
}
/*!
* @brief Main function
*/
int main(void)
{
/* Initialize standard SDK demo application pins */
sc_ipc_t ipc;
ipc = BOARD_InitRpc();
BOARD_InitPins(ipc);
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
BOARD_InitMemory();
/* Power up the MU used for RPMSG */
if (sc_pm_set_resource_power_mode(ipc, SC_R_MU_5B, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
{
PRINTF("Error: Failed to power on MU!\r\n");
}
if (sc_pm_set_resource_power_mode(ipc, SC_R_MU_7A, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
{
PRINTF("Error: Failed to power on MU!\r\n");
}
if (sc_pm_set_resource_power_mode(ipc, SC_R_IRQSTR_M4_0, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
{
PRINTF("Error: Failed to power on IRQSTEER!\r\n");
}
IRQSTEER_Init(IRQSTEER);
copyResourceTable();
#ifdef MCMGR_USED
/* Initialize MCMGR before calling its API */
(void)MCMGR_Init();
#endif /* MCMGR_USED */
if (xTaskCreate(app_task, "APP_TASK", APP_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, &app_task_handle) != pdPASS)
{
PRINTF("\r\nFailed to create application task\r\n");
for (;;)
;
}
vTaskStartScheduler();
PRINTF("Failed to start FreeRTOS on core0.\n");
for (;;)
;
}
Please help me this problem