Issue When Transpose RPMSG-lite project from Zephyr 1.13 to FreeRTOS 1.0.1

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

Hello @neuberfran, thank you for the post! Have you been able to resolve your issue? If not let us know! If you have, it may to useful to post what you did so others can learn from it as well. Thanks again!

This does not come from FreeRTOS. Can you check where it is supposed to come from and why it is not found?

@bsmith @aggarg

I have a message ready here with some links to post. As I am a new user, I cannot place links here. It becomes more difficult to detail the problem. I have an issue to put the RPMSG-lite on the imx7d-pico (where I already managed to put it and removed the normal RPMSG/OpenAMP).

I have said problems mainly in porting/ENV files type: rpmsg_env_freertos.c, rpmsg_platform_zephyr_ipm.c. I think the main problem lies there.

If you can search github (neuberfran) for the newest repositories (and old ones, like zephyr_old_version), there are more details.

You should now be able to post the links.

These files are not from FreeRTOS - you need to contact their author.

@aggarg

OK. In chronological order and with links, it is easier to explain. The first link below is what prompted me to migrate my project to FreeRTOS. Issue on stackoverflow. Using Zephyr 3.3 (Not zephyr 1.13 where the project was originally made) the main script always stops at while (0 == rpmsg_lite_is_link_up(rl_instance)) {. It’s a loop.

At the end of the messages in link 2. I’m having problems migrating zephyr to freertos.

In link 3, I have mcxpresso from NXP with FreeRTOS (working here) to evkmcimx7ulp device. I don’t have it. I have imx7d-pico device. But this project has done some good to transpose my zephyr project to freertos/rpmsg-lite. However, NXP used huge templates and my FreeRTOS-tn did not use a template.

  1. c - RPMSG-lite in imx7d-pico stop in while (0 == rpmsg_lite_is_link_up(rl_instance)) { - Stack Overflow

  2. https://community.nxp.com/t5/Other-NXP-Products/RPMSG-lite-with-Zephyr-1-13-3-3-with-issue-in-imx7d-pico-using/m-p/1774277/emcs_t/S2h8ZW1haWx8dG9waWNfc3Vic2NyaXB0aW9ufExRNEhGMFVKTUQ2UTFFfDE3NzQyNzd8U1VCU0NSSVBUSU9OU3xoSw#M20479

3)https://github.com/neuberfran/pmsg_lite_files/tree/main/boards/evkmcimx7ulp/multicore_examples/rpmsg_lite_str_echo_rtos

The rpmsg_platform_zephyr_ipm.c file is an important file in the zephyr project (to be migrated to freertos) and needs to be analyzed and, if necessary, converted (https://elinux.org/images/4/4b/Linux-and-Zephyr-“Talking”-to-Each-Other-in-the-Same-SoC-Diego-Sueiro-Sepura-Embarcados-1.pdf)

My FreeRTOS=GitHub - neuberfran/freertos-tn

The RPMSG-lite website is well documented, especially the USAGE part where they talk about adapting the build system, etc.:

Attached is my current porting project (from zephyr to freertos) status. It seems that there is an error (as I don’t know much) about porting files and ENV files.

https://github.com/neuberfran/imx7d_pico_m4/blob/main/demo_apps/rpmsg/str_echo_rpmsglite/str_echo_rp…

What error do you see and where do you see this error? What exact steps do you do to reproduce this error?

@bsmith @aggarg

git clone https://github.com/neuberfran/imx7d_pico_m4

cd /home/username/freertos/imx7d_pico_m4/demo_apps/rpmsg/str_echo_rpmsglite/armgcc

export ARMGCC_DIR=${HOME}/neuber/gcc-arm-none-eabi-10.3-2021.10
./build_all.sh

I get this error -

CMake Error at /usr/share/cmake-3.22/Modules/CMakeDetermineSystem.cmake:130 (message):
  Could not find toolchain file:
  ../../../../../../tools/cmake_toolchain_files/armgcc.cmake
Call Stack (most recent call first):
  CMakeLists.txt

Would you please add this tools/cmake_toolchain_files/armgcc.cmake to the repo or tell where do you get these from?

@aggar I resolved these configuration errors. But the app keeps stopping at: while (!rpmsg_lite_is_link_up(rl_instance))
in line 75

I’m trying to put the new version of rpmsg-lite (in place of the old one) but I have a new issue:

/home/neuberfran/neuber/gcc-arm-none-eabi-10.3-2021.10/bin/…/lib/gcc/arm-none-eabi/10.3.1/…/…/…/…/arm-none-eabi/bin/ld: CMakeFiles/rpmsg_str_echo_rpmsglite_example.dir/home/neuberfran/projects/freertos-tn/middleware/multicore/open-amp/lib/rpmsg_lite/porting/environment/rpmsg_env_freertos.c.obj: in function env_tx_callback': rpmsg_env_freertos.c:(.text.env_tx_callback+0x1c): undefined reference to xTimerPendFunctionCallFromISR’
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/rpmsg_str_echo_rpmsglite_example.dir/build.make:560: release/rpmsg_str_echo_rpmsglite_example.elf] Erro 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/rpmsg_str_echo_rpmsglite_example.dir/all] Erro 2
make: *** [Makefile:91: all] Erro 2

With the new RPMSG-lite version I will can use something like this: rpmsg_lite_wait_for_link_up(my_rpmsg, RL_BLOCK);

Another thing I’m trying is to change UART0 to UART6 from NXP’s mcxpresso project. Since the m4-Cortex of my pico_pi_m4 uses UART6 and not UART0. I’m not able to change all the MCXpresso project settings, like board name, etc… That would be ideal. But still with issues:pmsg_lite_files/boards/evkmcimx7ulp/multicore_examples/rpmsg_lite_str_echo_rtos/main_remote.c at main · neuberfran/pmsg_lite_files · GitHub

Set INCLUDE_xTimerPendFunctionCall to 1 in FreeRTOSConfig.h and make sure you are compiling timers.c.

@aggarg /home/neuberfran/projects/freertos-tn/rtos/FreeRTOS/Source/timers.c:80:3: error: #error configUSE_TIMERS must be set to 1 to make the xTimerPendFunctionCall() function available.
80 | #error configUSE_TIMERS must be set to 1 to make the xTimerPendFunctionCall() function available.

make sure you are compiling timers.c .

Everything seems to be ok with timers

  |   ^~~~~

make[2]: *** [CMakeFiles/rpmsg_str_echo_rpmsglite_example.dir/build.make:285: CMakeFiles/rpmsg_str_echo_rpmsglite_example.dir/home/neuberfran/projects/freertos-tn/rtos/FreeRTOS/Source/timers.c.obj] Erro 1
make[2]: ** Esperando que outros processos terminem.
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/rpmsg_str_echo_rpmsglite_example.dir/all] Erro 2

The error message is clear here - you need to set configUSE_TIMERS to 1 in FreeRTOSConfig.h.

@aggarg Still no success here.Unfortunately

I guess now your question is about why rpmsg is not working. That library is from NXP and you need to contact NXP for that.

@aggarg I can`t run RPMSG-lite in Zephyr 3.3 in imx7d-pico/m4 side. Zephyr 1.13 Works. Issue in new APM changes in Zephyr · zephyrproject-rtos/zephyr · Discussion #66669 · GitHub In Zephyr the issue stay in latest Zephyr IPC infrastructure. But in FreeRTOS it should have worked. Because I’m just replacing RPMSG (which worked) with RPMSG-lite. It should still be missing the correct configuration files, porting and environments files.

The entire transport project (Zephyr to FreeRTOS) is building on the video above. I haven’t seen anything in FreeRTOS that is equivalent to the rpmsg_platform_zephyr_ipm.c file that is linked below:


As I said before, this software is not from FreeRTOS but from NXP. Therefore, it is hard for me to answer questions about it. Would you please contact NXP?

@aggarg I think the my FreeRTOS 1.0.1 can run Old(Or New) rpmsg-lite version. Look mcxspresso by nxp to imx7ulp device using rpmsg-lite New version.

?

Windows runs AutoCad, would you therefore expect Microsoft to provide support for Autocad?

I believe if anyone here were familiar enough with rpmsg on FreeRTOS, they would have been happy to share their knowledge and experiences, but since that has not happened, it would be a better utilization of your time to contact the makers of your middleware.

1 Like