RPMSG Receive on Linux side

Hi,
I’ve been able to run the RPMSG echo example, even customize it for my needs and sending messages from the linux to the M4 works fine. I was using simple echo commands in terminal as suggested in the readme of the example.
When I run the ping pong example though, the M4 side does everything fine, it prints out all the pings and pongs, but I don’t get any output in the Linux terminal. The readme pingpong file suggests otherwise:
“The Cortex-A terminal displays the following information:”

get 1 (src: 0x1e)
get 3 (src: 0x1e)
......
get 99 (src: 0x1e)
get 101 (src: 0x1e)

But I get no output whatsoever. I am using the Verdin Mini and the SDK_2_12_1_MIMX8MM6xxxKZ

The second question that might be directly connected to the first: I then tried running a small C program to try and read any rpmsg messages on linux. I tried reading the ping pong and the str echo example.
The ONLY code example that reads the rpmsg messages on linux I could find was this one Rpmsg protocol failing with ims_rpmsg_tty on Linux. I only changed the tty device to “/dev/ttyRPMSG30”
When debugging through the file I am already stuck on opening of the virtual device where the open function returns -1. I feel that this has to do more with my lack of experience with containers, I guess I have to announce the rpmsg device somewhere in the configuration, I have zero experience with this though, so any help or starting point would be appreciated!
Thanks

Hi @swiss,

I’m glad you could run the RPMSG without errors.

How are you connected to the board? Are you using SSH? The driver outputs its messages using the kernel print, so you will be able to see it in real-time using a UART console (using the ttyUSB3 in the verdin, for example) or if you are using SSH you can run

# dmesg | grep get

Then you’ll be able to see the messages after they have been received. Can you check that, please?

You are using TorizonCore, correct? Can you share your docker run command? Try to run your container with the --device /dev/ttyRPMSG30 so it will be available inside your container (or if you’re using the VSCode extensions, you can also add it to the device filed on the extension configuration).

Best Regards.
Hiago.

I am connecting over UART, and after running this I was able to see the messages!

I am using a custom TorizonCore with a device tree overlay built with torizoncore-builder. I am also using VSCode for development. I added /dev/ttyRPMSG30 under devices in the extension and I’m getting the following error:

Remote docker exception. :: Error (525) - Docker exception: 500 
Server Error for http://127.0.0.1:45703/v1.40/containers/86fa340e8647f7175e65ada6d1d55171890e67eb2c9a8da08a08630bdc807547/start:
Internal Server Error ("error gathering device information while
adding custom device "/dev/ttyRPMSG30 ": no such file or directory") 

Before running this I run the sudo modprobe imx_rpmsg_tty over the UART terminal, and I see ttyRPMSG30 under /dev. But that’s not inside of the container is it? I probably need to add the modprobe command somewhere inside of the extension?

EDIT:
Also when running the pingpong example, I use the sudo modprobe imx_rpmsg_pingpong and then the messages are visible using dmesg | grep get. When I run the customized echo example (where M4 receives messages without any problems) I run modprobe imx_rpmsg_tty. There I don’t see any messages with dmesg | grep get. BUT if I run just dmesg, I see

virtio_rpmsg_bus virtio0: msg received with no recipient

for each message that should have arrived. But let’s not focus on that but rather on just opening the tty inside a C app developed through VSCode

EDIT 2:
Sorry for the chaotic edits, I am learning on the fly :slight_smile:
The error message doesn’t show up if I receive the handshake from linux before sending:

/* Wait Hello handshake message from Remote Core. */
    (void)rpmsg_queue_recv(my_rpmsg, my_queue, (uint32_t *)&remote_addr, helloMsg, sizeof(helloMsg), ((void *)0),
                           RL_BLOCK);

I guess this is needed before the first send call, so that the remote_addr is initialized. But still my send function call:

result = rpmsg_lite_send(my_rpmsg, my_ept, remote_addr, (char*)&counted_freq, sizeof(counted_freq), RL_BLOCK);

Result returns success, but now there are absolutely no traces in dmesg of the sent messages.

Hi @swiss,

don’t worry, feel free to send as many messages as you want.

I made a quick test here:

I created a simple container running C and exposed the ttyRPMSG30 (you can see in the left image the “devices” configuration). Then I deployed pressing F5 and it worked.

However, using the ttyRPMSG is not the best solution here. It’s a little hard to read and write to the tty environment, I agree with you that using the kernel libraries and the functions from RPMsg directly to your code is better. Have you checked how it’s done inside the tty driver? Check it here, maybe it will give some insights into your code: imx_rpmsg_tty.c « rpmsg « drivers - linux-toradex.git - Linux kernel for Apalis, Colibri and Verdin modules

Meanwhile, I will try to run my C code with the kernel libraries as well, and see if I can help you in any way here.

Also, take a look into RPMsg from NXP: GitHub - nxp-mcuxpresso/rpmsg-lite: RPMsg implementation for small MCUs

Best Regards,
Hiago.

Hi @hfranco.tx ,

So you didn’t have to run modprobe in any moment? I will try changing things around a bit more but I’m still getting a docker exception "/dev/ttyRPMSG30 “: no such file or directory”).
I also think the problem is that the rpmsg namespace is announced to the “base linux” and not to the “container linux” that is running the app (if that makes sense).

Also please help me understand this: I created this custom torizon core image with a device tree overlay. Does the overlay automatically apply to the container?

Hi @swiss,

I’m sorry, I forgot to mention that part. Yes, it’s necessary to sudo modprobe imx_rpmsg_tty to activate the RPMSG TTY driver inside the kernel. This module is compiled as a module (.ko), so the modprobe is necessary here.

If you want to make this driver permanent as a built-in inside the kernel (so no modprobe would be needed), you will need to change the kernel configuration and activate this driver. For TorizonCore, I wouldn’t recommend that, since it would require you to create your own version of TorizonCore modified with Yocto with a custom kernel. The goal of TorizonCore is to be easy and out of the box, so no Yocto is required. I

Instead, I would recommend an initialization script or something related to activate the modprobe after your module has been initialized.

After the modprobe, can you see the /dev/ttyRPMSG30? Can you send a message like echo "hello" > /dev/ttyRPMSG30?

Please check this link: TorizonCore Builder Tool - Customizing Torizon OS Images | Toradex Developer Center

You can add your overlay to the tcbuild.yaml and it will be automatically applied. Otherwise, you can check the overlays.txt inside the /boot/ostree//dtb/overlays.txt and manually edit the overlays.

Best Regards,
Hiago.

Hi Hiago,

The echo example works now! I wiped my changes away and just ran the original SDK code. Apparently my changes were making the problem. I will start a new question concernig this,

Thanks!

1 Like