Reading and Writing rpmsg in .NET


RPMSG Receive on Linux side

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.

Is there a way to retrieve the message from rpmsg bus to .Net environment?

However, I tried to use file reading using System.IO.File to read from the ttyRPMSG30, but it hangs whenever I try to read it. (this app is a docker container, and I am using the torizon extension in vscode) the configurations are properly created following the examples provided in the developer pages and the samples provided in github. aspnet-core-app

Yet, I have also used the docker-compose.arm64v8 for installing weston with the proper configuration and I did add

“c 236:* rmw”

as I have seen that the major when modprobe used for imx_rpmsg_tty is 236

So again, is there a way to retrieve the messages from cortex M4 to .Net? if not please suggest me the best practice upon it.

Colibri iMX8DX 1GB V1.0D
Col Evaluation V3.2B
TorizonCore (2022-04-09 | 5.6.0+build.13)

Hi @pkg_su,

I never tried to use .NET, but despite the programming language, any operation to read/write to serial ports should be possible. For example, can you test it using C or python to check if you can achieve the same behavior? On python, I believe there is a library called pyserial that can be used.

For the docker container, you need to expose the /dev/ttyRPMSG to the container with the “–device” parameter. Have you done that?

Have you tried to use the SerialPort Class?

Best Regards,

Hello Hiago,

I’ll share my config.yaml that is created from the extension that you provide in VSCode I think this will be the best way to clarify what is going on here. As well, the source code of this small program.

config.yaml (3.8 KB)
docker-compose.arm64v8.yml (1.2 KB)

using System;
using System.Threading;
using System.IO.Ports;
using System.IO;

namespace gps
    class Program
        static void Main(string[] args)
            SerialPort serialDev;

            // serial configs
            serialDev = new SerialPort();
            serialDev.PortName = Environment.GetEnvironmentVariable("TTY_SERIAL_PORT");
            serialDev.BaudRate = 9600;
            serialDev.DataReceived += new SerialDataReceivedEventHandler(OnMessageReceived);

            // on ctrl+c close connection
            Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs eventArgs) =>

            // wait for RPMSG inputs

        static void OnMessageReceived(object sender, SerialDataReceivedEventArgs args)
            SerialPort sp = (SerialPort)sender;
            string indata = sp.ReadExisting();
            Console.WriteLine("Data Received: " + indata);

OK, I’ll check that in python if I am receiving the same behavior.

I actually did that, and as well I added in cgroups for Weston the major 236: and minor as * just wondering if Weston has anything to do here, as in your example connecting the kiosk to the Linux layer as shown in the Blazor .net example app done by firing the two apps up (Kiosk and Weston)

yes I did as it shows above

Error Inappropriate ioctl for device opening port /dev/ttyRPMSG30
Execution terminated by user.

My overlay is:
fdt_overlays=colibri-imx8x_parallel-rgb-lvds_overlay.dtbo display-dpi-lt170410_overlay.dtbo colibri-imx8x_atmel-mxt-connector_overlay.dtbo colibri-imx8x_disable-cm40-uart_overlay.dtbo

Hi @pkg_su,

I’m not used to .NET myself, so I tested on my side using Python and it worked. I used the baud rate 115200. Can you try to change to 115200 to see if it works?

I deployed it inside a container with python, using the pyserial library.


import serial

def main():
        with serial.Serial("/dev/ttyRPMSG30", 115200, timeout=1) as ser:
    except Exception as err:

if __name__ == "__main__":

Please note that we need to write the bytes to the serial, not the actual string ("bToradex!").

And exposed the ttyRPMSG to my container on the docker-compose file:

      context: .
      dockerfile: Dockerfile.debug
    image: ${LOCAL_REGISTRY}:5002/hmp-debug:${TAG}
      - 6502:6502
      - 6512:6512
      - "/dev/ttyRPMSG30:/dev/ttyRPMSG30"

After running the container, everything worked fine:


torizon@colibri-imx8x-06995803:~$ cat /boot/ostree/torizon-0b063e02951e998cfb713cab409e226f0ed7ec343933815517ec68930a8f0228/dtb/overlays.txt
fdt_overlays=colibri-imx8x_parallel-rgb_overlay.dtbo colibri-imx8x_ad7879_overlay.dtbo display-vga_overlay.dtbo colibri-imx8x_disable-cm40-uart_overlay.dtbo

Let me know if that helps. Unfortunately, I can’t help too much with .NET, but I believe it’s just a matter of finding the right way to write to the serial with your code.

Best Regards,

1 Like

Yeah, thanks, the problem was in the .NET framework as the serialPort class package 7.0.0 is not supported in .netcore3.1 that is why I couldn’t open the serial port.

My approach was based on the samples that you provide from git. And I didn’t notice at first that the framework would not be supporting the serialPort class.

Best of luck!

1 Like

Hi @hfranco.tx,

Sorry for bothering you again, but I still have a couple of questions regarding the rpmsg protocol and retrieving it back to the user space.

  1. Is it possible to retrieve the data other than the tty approach? As I see in the ping-pong sample, the kernel module and the m4 runtime are communicating, however the data is not shared to the user space. If yes, can you please provide an example?

  2. Again, if yes, can you please also provide a scenario or a sample code in python or c how to retrieve these data to the user space?

Best of luck

Hi @pkg_su,

No need to be sorry, feel free to ask any questions.

Indeed, there are other ways to expose the RPMSG to userspace. The TTY was chosen by NXP I believe to provide an easy-to-use demo for their customers. Behind the scenes, RPMSG is just a shared memory between the two processors, one buffer to read and another one to write. On the ping-pong example, the driver accesses these shared buffers directly to communicate with the other processor, without the need for creating a serial interface like the TTY.

I don’t believe this is possible with python, only C, because here we need to access the kernel API for the RPMSG. For examples, please check the example from the mainline kernel:

And the documentation example:

Best Regards,