Hi,
/*
* 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 "app_srtm.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define RPMSG_LITE_SHMEM_BASE (VDEV1_VRING_BASE)
#define RPMSG_LITE_LINK_ID (1U)
#define RPMSG_LITE_NS_ANNOUNCE_STRING "rpmsg-virtual-tty-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 struct rpmsg_lite_instance *volatile my_rpmsg = NULL;
static struct rpmsg_lite_endpoint *volatile my_ept = NULL;
static volatile rpmsg_queue_handle my_queue = NULL;
void app_destroy_task(void)
{
if (app_task_handle)
{
vTaskDelete(app_task_handle);
app_task_handle = NULL;
}
if (my_ept)
{
rpmsg_lite_destroy_ept(my_rpmsg, my_ept);
my_ept = NULL;
}
if (my_queue)
{
rpmsg_queue_destroy(my_rpmsg, my_queue);
my_queue = NULL;
}
if (my_rpmsg)
{
rpmsg_lite_deinit(my_rpmsg);
my_rpmsg = NULL;
}
}
void app_task(void *param)
{
volatile uint32_t remote_addr;
void *rx_buf;
uint32_t len;
int32_t result;
void *tx_buf;
uint32_t size;
/* Print the initial banner */
PRINTF("\r\nRPMSG String Echo FreeRTOS RTOS API Demo...\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 */
rpmsg_lite_wait_for_link_up(my_rpmsg, RL_BLOCK);
my_queue = rpmsg_queue_create(my_rpmsg);
my_ept = rpmsg_lite_create_ept(my_rpmsg, LOCAL_EPT_ADDR, rpmsg_queue_rx_cb, my_queue);
(void)rpmsg_ns_announce(my_rpmsg, my_ept, RPMSG_LITE_NS_ANNOUNCE_STRING, RL_NS_CREATE);
PRINTF("\r\nNameservice sent, ready for incoming messages...\r\n");
for (;;)
{
/* Get RPMsg rx buffer with message */
result =
rpmsg_queue_recv_nocopy(my_rpmsg, my_queue, (uint32_t *)&remote_addr, (char **)&rx_buf, &len, RL_BLOCK);
if (result != 0)
{
assert(false);
}
/* 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);
/* 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);
}
/* Release held RPMsg rx buffer */
result = rpmsg_queue_nocopy_free(my_rpmsg, rx_buf);
if (result != 0)
{
assert(false);
}
}
}
void app_create_task(void)
{
if (app_task_handle == NULL &&
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 (;;)
;
}
}
/*!
* @brief Main function
*/
int main(void)
{
/* Initialize standard SDK demo application pins */
CLOCK_EnableClock(kCLOCK_PctlA);
CLOCK_EnableClock(kCLOCK_PctlB);
CLOCK_EnableClock(kCLOCK_Rgpio2p0);
BOARD_InitBootPins();
BOARD_BootClockRUN();
APP_SRTM_I2C_ReleaseBus();
BOARD_I2C_ConfigurePins();
BOARD_InitDebugConsole();
CLOCK_SetIpSrc(kCLOCK_Lpi2c3, kCLOCK_IpSrcSircAsync);
CLOCK_SetIpSrc(kCLOCK_Lpi2c0, kCLOCK_IpSrcSystem);
/* Use AUXPLL main clock source */
CLOCK_SetIpSrcDiv(kCLOCK_Sai0, kCLOCK_IpSrcRtcAuxPllAsync, 0, 0);
APP_SRTM_Init();
APP_SRTM_BootCA7();
#ifdef MCMGR_USED
/* Initialize MCMGR before calling its API */
(void)MCMGR_Init();
#endif /* MCMGR_USED */
app_create_task();
vTaskStartScheduler();
PRINTF("Failed to start FreeRTOS on core0.\n");
for (;;)
;
}
I have this project running in FreeRTOS 1.0.1. I will change the str_echo_freertos.c SCRIPT to this (in Zephyr) :
> #include <zephyr/kernel.h>
> #include <zephyr/toolchain.h>
> #include <stddef.h>
> #include <stdarg.h>
> #include <inttypes.h>
> #include <zephyr/device.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include "rpmsg_lite.h"
> #include "rpmsg_queue.h"
> #include "rpmsg_ns.h"
>
> //#define APP_TASK_STACK_SIZE (4096)
> //#define APP_TASK_STACK_SIZE (1024)
> #define APP_TASK_STACK_SIZE (256)
> #define LOCAL_EPT_ADDR (30)
>
> //#define RPMSG_MAX_SIZE 1024
> //#define RPMSG_MAX_SIZE 512
> #define RPMSG_MAX_SIZE 256
> #define RPMSG_LITE_LINK_ID (RL_PLATFORM_IMX7D_M4_LINK_ID)
> #define RPMSG_LITE_SHMEM_BASE (0x9FFF0000)
> #define RPMSG_LITE_NS_USED (1)
> #define RPMSG_LITE_NS_ANNOUNCE_STRING "rpmsg-openamp-demo-channel"
>
> #ifdef CONFIG_SOC_SERIES_IMX7_M4
> /* Settings bellow aligned with Linux i.MX RPMsg side */
> //#define RPMSG_MAX_SIZE 512
> #define RPMSG_MAX_SIZE 256
> #define RPMSG_LITE_LINK_ID (RL_PLATFORM_IMX7D_M4_LINK_ID)
> #define RPMSG_LITE_SHMEM_BASE (0x9FFF0000)
> #define RPMSG_LITE_NS_USED (1)
> #define RPMSG_LITE_NS_ANNOUNCE_STRING "rpmsg-openamp-demo-channel"
> #else
> #error Please define RPMSG_MAX_SIZE, RPMSG_LITE_LINK_ID, RPMSG_LITE_SHMEM_BASE,\
> RPMSG_LITE_NS_USED and RPMSG_LITE_NS_ANNOUNCE_STRING values for the CPU used.
> #endif
>
> K_THREAD_STACK_DEFINE(thread_stack, APP_TASK_STACK_SIZE);
> static struct k_thread thread_data;
>
> void app_nameservice_isr_cb(unsigned int new_ept, const char *new_ept_name,
> unsigned long flags, void *user_data)
> {
> }
>
> void app_task(void *arg1, void *arg2, void *arg3)
> {
> ARG_UNUSED(arg1);
> ARG_UNUSED(arg2);
> ARG_UNUSED(arg3);
> int recved = 0;
> char buf[RPMSG_MAX_SIZE];
> char rsp[RPMSG_MAX_SIZE];
> int len;
> volatile unsigned long remote_addr;
> struct rpmsg_lite_endpoint *volatile rl_endpoint;
> volatile rpmsg_queue_handle rl_queue;
> struct rpmsg_lite_instance *volatile rl_instance;
> #ifdef RPMSG_LITE_NS_USED
> volatile rpmsg_ns_handle ns_handle;
> #endif /*RPMSG_LITE_NS_USED*/
>
> // usleep(100000);
> // k_sleep(K_MSEC(100000));
> /* Initialize RPMsg Core and create virtqueues */
> rl_instance = rpmsg_lite_remote_init((void *)RPMSG_LITE_SHMEM_BASE,
> RPMSG_LITE_LINK_ID, RL_NO_FLAGS);
> // usleep(100000);
> printk("Waiting for Master.\r\n");
> printk("Pin config failed: %d\n",(rpmsg_lite_is_link_up(rl_instance)));
> printk("rl_instance: %d\n",rl_instance);
> // while (rpmsg_lite_is_link_up(rl_instance) == 0) {
> while (!rpmsg_lite_is_link_up(rl_instance)) {
> // while (0 == rpmsg_lite_is_link_up(rl_instance)) {
> // k_sleep(K_MSEC(100000));
>
> // usleep(100000);
> }
> printk("Exit.\r\n");
>
> rl_queue = rpmsg_queue_create(rl_instance);
> rl_endpoint = rpmsg_lite_create_ept(rl_instance, LOCAL_EPT_ADDR,
> rpmsg_queue_rx_cb, rl_queue);
>
> #ifdef RPMSG_LITE_NS_USED
> ns_handle = rpmsg_ns_bind(rl_instance, app_nameservice_isr_cb, NULL);
> rpmsg_ns_announce(rl_instance, rl_endpoint,
> RPMSG_LITE_NS_ANNOUNCE_STRING, RL_NS_CREATE);
> printk("Nameservice announce sent.\r\n");
> #endif /*RPMSG_LITE_NS_USED*/
>
> while(1)
> {
> rpmsg_queue_recv(rl_instance, rl_queue,
> (unsigned long*)&remote_addr, (char*)buf,
> sizeof(buf), &recved, RL_BLOCK);
> printk("\nFrom endpoint 0x%X received %d bytes:\n",
> (unsigned int)remote_addr, recved);
> buf[recved] = '\0';
> printk("%s\n",buf);
>
> /* Format the echo response */
> len = snprintf(rsp, sizeof(rsp), "echo: %s\r\n", buf);
> printk("Sending %d bytes to endpoint 0x%X:\n", len,
> (int)remote_addr);
> printk("%s",rsp);
> rpmsg_lite_send(rl_instance, rl_endpoint, remote_addr, rsp, len,
> RL_BLOCK);
> }
> }
>
> void main(void)
> {
> printk("======== rpmsg_lite remote_echo ========\n");
>
> k_thread_create(&thread_data, thread_stack, APP_TASK_STACK_SIZE,
> (k_thread_entry_t)app_task,
> //NULL, NULL, NULL, K_PRIO_COOP(7), 0,k_timeout_t 0);
> NULL, NULL, NULL, K_PRIO_COOP(7), 0,K_MSEC(0));
> }
In official rpmsg-lite site have USAGE option to prepare build system (in my case CMakeLists.txt) to use RPMSG-lite.
I stay with issue in this part(change CMakeLists.txt to include rpmsg-lite libs)
issue: /home/neuberfran/gcc-arm-none-eabi-10.3-2021.10/bin/…/lib/gcc/arm-none-eabi/10.3.1/…/…/…/…/arm-none-eabi/bin/ld: cannot find -lrpmsg_lite