How to add RPMSG to a BSP 5.7 image using yocto

Dear support,
I my quest to get a running project where the M4 can pass data to Linux, I started the generation of a custom BSP5.7 image using Yocto (with some pending issues on the device tree, but that’s another topic).
My question is what steps are to be performed in Yocto to include RPMSG into the image.
And ideally, also some help on how to configure RPMSG for less buffers but larger ones.

Many thanks in advance,
Jeroen

Hi @ompie,

Although it’s possible to create a custom layer to add your M4 binary to your final image with Yocto, we don’t have any examples of how to do that yet.

You can create a custom layer that can access the files that you downloaded from MCUXpresso, will call the build_release.sh script that comes from NXP, and then move the generated binary to the right folder in your root filesystem of the final image (the /lib/firmware, for example). Then, you can also create a custom recipe for the u-boot part to call the M4 binary automatically by editing the environment variables.

This should work without problems because that’s what basically we do by hand but now automated with Yocto.

You can check this guide on how to create a custom layer with some examples: Custom meta layers, recipes and images in Yocto Project (hello-world examples) | Toradex Developer Center

You can also check the Yocto documentation for that: https://docs.yoctoproject.org/

Let me know if you need any help.

Best Regards,
Hiago.

Hi @hfranco.tx,

I think you misunderstood my question. I do not want to include the M4 firmware in the Linux image. I was talking about the Linus RPMSG part.
Perhaps RPMSG is already included by default but as far as I understood, the default generated Linux image does not include RPMSG and it shall thus be added via Yocto.
And my first question was therefore how to do that.
The second question is about configuring the RPMSG module in order to get larger buffers than the default ones and fewer of them…

Thanks,
Jeroen

Hi @ompie,

Ok, got it now, sorry about that. In order to do that, you will need to create a custom layer with the kernel configurations enabled. We have an example in the article that I shared with you.

About the configuration itself, there is something specific that you need to enable in the kernel? I check the downstream for BSP 5.7 (branch toradex_5.4-2.3.x-imx), and these configurations are enabled related to rpmsg:

>> cat .config | grep -i rpmsg
CONFIG_HAVE_IMX_RPMSG=y
# CONFIG_GPIO_IMX_RPMSG is not set
# CONFIG_REGULATOR_PF1550_RPMSG is not set
# CONFIG_SND_SOC_FSL_RPMSG_I2S is not set
# CONFIG_SND_SOC_IMX_RPMSG is not set
# CONFIG_SND_SOC_RPMSG_WM8960 is not set
# CONFIG_SND_SOC_RPMSG_WM8960_I2C is not set
# CONFIG_RTC_DRV_IMX_RPMSG is not set
# Rpmsg drivers
CONFIG_RPMSG=y
# CONFIG_RPMSG_CHAR is not set
# CONFIG_RPMSG_QCOM_GLINK_RPM is not set
CONFIG_RPMSG_VIRTIO=y
CONFIG_IMX_RPMSG_PINGPONG=m
CONFIG_IMX_RPMSG_TTY=m
# end of Rpmsg drivers

And remote proc is not enabled:

>> cat .config | grep -i remoteproc
# Remoteproc drivers
# CONFIG_REMOTEPROC is not set
# end of Remoteproc drivers

Can you share what would you like to enable?

Best Regards,
Hiago.

Hi @hfranco.tx,

Thanks for your answer!

OK, I will try that. I already know that article since also used it to modify the device tree (although there is still a problem with it, perhaps you could also taken a look at my post for that problem).

Concerning the defconfig, it already seems to enable what I need, thanks for pointing that out. I did not know that it is specified in there.
Is there a simple way (on the Linux console) to verify that RPMSG is actually included in the image ?

Best regards,

Jeroen

Hi @ompie,

Try these commands

# zcat /proc/config.gz | grep -i rpmsg
# zcat /proc/config.gz | grep -i remoteproc

inside your module. You should see what configs are activated.

Best Regards,
Hiago.

Hi @hfranco.tx,

RPMSG is indeed present:

CONFIG_HAVE_IMX_RPMSG=y
# CONFIG_GPIO_IMX_RPMSG is not set
# CONFIG_REGULATOR_PF1550_RPMSG is not set
# CONFIG_SND_SOC_FSL_RPMSG_I2S is not set
# CONFIG_SND_SOC_IMX_RPMSG is not set
# CONFIG_SND_SOC_RPMSG_WM8960 is not set
# CONFIG_SND_SOC_RPMSG_WM8960_I2C is not set
# CONFIG_RTC_DRV_IMX_RPMSG is not set
# Rpmsg drivers
CONFIG_RPMSG=y
# CONFIG_RPMSG_CHAR is not set
# CONFIG_RPMSG_QCOM_GLINK_RPM is not set
CONFIG_RPMSG_VIRTIO=y
CONFIG_IMX_RPMSG_PINGPONG=m
CONFIG_IMX_RPMSG_TTY=m
# end of Rpmsg drivers

So that’s good news !

Can you also shed some light on how to configure the RPMSG module in order to get larger buffers (about 4K each) than the default ones and fewer of them (4 or 8 buffers in the ring would be enough).
Issues here are probably where to configure these numbers a where to specify which RAM memory range must be reserved for shared access. I believe this is done in the device tree.
Any example code ?

Thanks Hiago !

Jeroen

Hi @ompie,

I’ve never changed that myself, so I don’t know exactly how this going to work, but I can point out some files that I believe you will need to change to achieve that.

One that I can see some buffer definitions is the imx_rpmsg.c:

/*
 * The time consumption by remote ready is less than 1ms in the
 * evaluation. Set the max wait timeout as 50ms here.
 */
#define REMOTE_READY_WAIT_MAX_RETRIES	500

#define RPMSG_NUM_BUFS		(512)
#define RPMSG_BUF_SIZE		(512)
#define RPMSG_BUFS_SPACE	(RPMSG_NUM_BUFS * RPMSG_BUF_SIZE)
#define RPMSG_VRING_ALIGN	(4096)
#define RPMSG_RING_SIZE	((DIV_ROUND_UP(vring_size(RPMSG_NUM_BUFS / 2, \
				RPMSG_VRING_ALIGN), PAGE_SIZE)) * PAGE_SIZE)

#define to_imx_virdev(vd) container_of(vd, struct imx_virdev, vdev)

Also, the same changes will be required on the M4 side as well.

/* Globals */
static struct rpmsg_channel *app_chnl = NULL;
static app_message_t app_msg[STRING_BUFFER_CNT];
static char app_buf[512]; /* Each RPMSG buffer can carry less than 512 payload */
static uint8_t app_idx = 0;
static uint8_t handler_idx = 0;
static volatile int32_t msg_count = 0;

Please check these files:

  • examples/imx7_colibri_m4/demo_apps/rpmsg/str_echo_bm/str_echo_bm.c
  • middleware/multicore/open-amp/rpmsg/rpmsg.h
  • middleware/multicore/open-amp/rpmsg/rpmsg_core.h
  • middleware/multicore/open-amp/rpmsg/rpmsg_ext.h
  • middleware/multicore/open-amp/rpmsg/rpmsg_rtos.h

Best Regards,
Hiago.

Thanks @hfranco.tx,

I came to the same conclusion concerning which files to change. The M4 side will not cause any problems, since it is a straight compilation into an executable.

The complexity is on the Linux side. The file you mentioned can be found under oe-core/build/tmp/work-shared/colibri-imx7-emmc/kernel-source/drivers/rpmsg/imx_rpmsg.c in my Yocto directory but since this is a tmp directory, it is not the one to change.

I suppose I have to add a recipe similar to what is described here but that example describes a patch, not the replacement of a source file as a whole.
Being very new to Yocto, I would really appreciate to have an (detailed) description of what to do in Yocto for this particular case.
Or you may perhaps be able to point me to another page which describes a similar case…

Before I can test it, I also need to solve the other issue I have with the modified device tree (here).

Best regards,
Jeroen

Hi @ompie,

You can also delete files with a patch. Actually, a patch is the way to go here if you want to change the source code of the Linux kernel.

To create a patch inside Yocto, first, you can run this command:

$ bitbake virtual/kernel -c devshell

This will open a new terminal with the source code of the Linux kernel inside Yocto. Then, you can make your changes inside this terminal. For example, try to change the imx_rpmsg.c file inside the drivers’ directory.

Next, you can check the modifications with

$ git status

You can add all your changes and create a patch with

$ git diff > my-patch.patch

Then, you will need to move your file my-patch.patch to your Yocto layer and add it to your recipe, as described on the Custom meta layers, recipes and images in Yocto Project (hello-world examples) | Toradex Developer Center guide.

Hope this helps.

Best Regards,
Hiago.

1 Like

Hi @hfranco.tx,
Thanks for the explanation and the procedure to follow. I’ll give it a try after the other issues with Yocto are solved since I’m not sure whether the changes will show up on the module.
You’re also active on the other thread so let’s concentrate on that one first.

Anyway, your help is very much appreciated !

Jeroen

1 Like