I have the IMX6SoloX SABRESD board. I have seen that there is a MCC example for MQX which achieve communication between both cores sharing a section of the RAM memory. However, for FreeRTOS there is only available the pingpong example which achieve communication through the MU. Is this correct?
I would like to achieve communication through the shared RAM but in FreeRTOS. Does someone know where I can founf the code?
Hi Imanol,
the freeRTOS have RPMSG instead of MCC, but it also use share memory. You can find example str_echo_freertos for RPMSG.
Radim.
Hi Radim,
Where can I find the RAM memory address used for the communication? Is the same as the shared region of the DTB?
Thank you for your response,
Imanol
Hi Imanol,
it looks like, that it is hardcoded in the file arch/arm/mach-imx/imx_rpmsg.c
if (!strcmp(rpdev->rproc_name, "m4")) {
ret = of_device_is_compatible(np, "fsl,imx7d-rpmsg");
ret |= of_device_is_compatible(np, "fsl,imx6sx-rpmsg");
if (ret) {
/* hardcodes here now. */
rpdev->vring[0] = 0xBFFF0000;
rpdev->vring[1] = 0xBFFF8000;
}
} else {
break;
}
For more information you can look in the section 51 of i.MX_Linux_Reference_Manual and in the RPMSG_RTOS_Layer_User's_Guide
Radim.
An which is the function of the MU in this example?
Apart form that, those memory addresses are of the DDR. Is it possible to change them in Linux and FreeRTOS (/freertos/middleware/multicore/open-amp/porting/imx6sx_m4/platform_info.c) to the Shared RAM addresses (0x91F000). Besides, which size does its ring need?
Thank you very much
Like cortexA core has MMU. Typically, cortexM core uses MPU(Memory Protect Unit).
Please make your share memory no cacheable. 0xBFFF0000 map the default.
You need to modify the platform/devices/MCIMX6X/startup/system_MCIMX6X_M4.c.
Hi Biyong,
I commented the following part of the system_MCIMX6SX_M4.c file and worked. The /dev/ttyRPMSG appears. However, when I do an "echo "test" > /dev/ttyRPMSG" Linux shows "root@imx6sx_all:/# virtio_rpmsg_bus virtio0: inbound msg too big: (512, 1026)" "virtio_rpmsg_bus virtio0: inbound msg too big: (-3584, 2)". I do not why this happens, besides, the M4 core receives the data correctly.
// /* M4 core clock root configuration. */
// /* Initialize Cache */
// /* Enable System Bus Cache */
// /* set command to invalidate all ways and write GO bit
// to initiate command */
// LMEM_PSCCR = LMEM_PSCCR_INVW1_MASK | LMEM_PSCCR_INVW0_MASK;
// LMEM_PSCCR |= LMEM_PSCCR_GO_MASK;
// /* Wait until the command completes */
// while (LMEM_PSCCR & LMEM_PSCCR_GO_MASK);
// /* Enable system bus cache, enable write buffer */
// LMEM_PSCCR = (LMEM_PSCCR_ENWRBUF_MASK | LMEM_PSCCR_ENCACHE_MASK);
// __ISB();
// /* Enable Code Bus Cache */
// /* set command to invalidate all ways and write GO bit
// to initiate command */
// LMEM_PCCCR = LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_INVW0_MASK;
// LMEM_PCCCR |= LMEM_PCCCR_GO_MASK;
// /* Wait until the command completes */
// while (LMEM_PCCCR & LMEM_PCCCR_GO_MASK);
// /* Enable code bus cache, enable write buffer */
// LMEM_PCCCR = (LMEM_PCCCR_ENWRBUF_MASK | LMEM_PCCCR_ENCACHE_MASK);
// __ISB();
// __DSB();
Hi Biyong,
The example is done for the DDR but I am interested in the OCRAM. Therefore, I tried doing something similar to what you attached. However, it does not appear /dev/ttyRPMSG. If I comment the Enable Code Cache it does but with the message I commented in the previous comment.
I attached you my modifications.
Thank you
At lease the code following is wrong:
OCRAM from M4 side is 0x20900000, which is already set in bar 2 in the sample code.
wrong code
/* Select Region 1 to configure share memory with A9(1M). */
MPU->RNR = 1;
MPU->RBAR = 0x900000;
MPU->RASR = 0x30B0021;
Table 2-2. CM4 memory map
But it is also mapped in those addresses, no? In the linux device tree I use 0x900000.
fsl,shared-mem-addr = <0x910000>;
fsl,shared-mem-size = <0x10000>;
The only way I achieve to work (with the warning) is modifying the following:
- LMEM_PCCCR = (LMEM_PCCCR_ENWRBUF_MASK | LMEM_PCCCR_ENCACHE_MASK);
+ LMEM_PCCCR = (LMEM_PCCCR_ENWRBUF_MASK);
What you show is on A9 side. The code you change is freeRTOS on M4 side.
Please check the memory map carefully.
It has three parts, System memory(A9),CM4, AIPS.
For the LMEM, if your changes of disabling cache will make the M4 running slow.
It is not a correct way. The correct way is to configure the MPU on M4 side to make a bar non cacheable. Not disable all the cache.
Both appear in the CM4 table:
If you are just intertested in run the rpmsg in the ocram. Please read the comments in the imx_rpmsg.c carefully.
And the entire rpmsg could fit in the ocram.
Maybe you can try make only the message in it. but other in DDR.
And it is not any value in a real project.
imx_rpmsg.c
/*
* For now, allocate 256 buffers of 512 bytes for each side. each buffer
* will then have 16B for the msg header and 496B for the payload.
* This will require a total space of 256KB for the buffers themselves, and
* 3 pages for every vring (the size of the vring depends on the number of
* buffers it supports).
*/
#define RPMSG_NUM_BUFS (512)
#define RPMSG_BUF_SIZE (512)
#define RPMSG_BUFS_SPACE (RPMSG_NUM_BUFS * RPMSG_BUF_SIZE)
/*
* The alignment between the consumer and producer parts of the vring.
* Note: this is part of the "wire" protocol. If you change this, you need
* to update your BIOS image as well
*/
#define RPMSG_VRING_ALIGN (4096)
/* With 256 buffers, our vring will occupy 3 pages */
Hi Biyong
i am working on multiple endpoint RPMSG, i was able to modify the shared memory and use DDR.
but if I change/increase the "RPMSG_BUF_SIZE" multiple endpoint wont work, channel wont get created by installing the module.
insmod /lib/modules/3.14.28-1.0.0_ga+g91cf351/kernel/drivers/rpmsg/rpmsg_multiept.ko
i have attached source file for rpmsg_multiept.ko
below please find the my code of imx_rpmsg.c
+ * For now, allocate 256 buffers of 512 bytes for each side. each buffer
+ * will then have 16B for the msg header and 496B for the payload.
+ * This will require a total space of 256KB for the buffers themselves, and
+ * 3 pages for every vring (the size of the vring depends on the number of
+ * buffers it supports).
+ */
+#define RPMSG_NUM_BUFS (1024)
+#define RPMSG_BUF_SIZE (512)
+#define RPMSG_BUFS_SPACE (RPMSG_NUM_BUFS * RPMSG_BUF_SIZE)
+
+
+
.........
...........
MODULE_DEVICE_TABLE(of, imx_rpmsg_dt_ids);
+
+static int imx_rpmsg_probe(struct platform_device *pdev)
+{
+ int i, ret = 0;
+ struct device_node *np = pdev->dev.of_node;
+
+ for (i = 0; i < ARRAY_SIZE(imx_rpmsg_vprocs); i++) {
+ struct imx_rpmsg_vproc *rpdev = &imx_rpmsg_vprocs[i];
+
+ if (!strcmp(rpdev->rproc_name, "m4")) {
+ ret = of_device_is_compatible(np, "fsl,imx7d-rpmsg");
+ ret |= of_device_is_compatible(np, "fsl,imx6sx-rpmsg");
+ if (ret) {
+ /* hardcodes here now. */
+ rpdev->vring[0] = 0xBF800000;
+ rpdev->vring[1] = 0xBF880000;
+ }
+ } else {
+ break;
+ }
+
+ pr_debug("%s rpdev%d: vring0 0x%x, vring1 0x%x\n", __func__,
+ i, rpdev->vring[0], rpdev->vring[1]);
if i change RPMSG_NUM_BUFS back to (512), channel gets created.
am i doing calculation wrong.
how to calculate vring address.
Hi Imanol,
It should be possible to use Shared RAM, but check in RDC if both cores can access this region of memory. The size of one buffer is 512 bytes. The MU isn't used in this example.
Radim.
Hi Radim,
I have changed the address in the imx_rpmsg.c to:
rpdev->vring[0] = 0x91F000;
rpdev->vring[1] = 0x91F800;
The used DTB has the following shared memory:
fsl,shared-mem-addr = <0x91F000>;
fsl,shared-mem-size = <0x1000>;
In FreeRTOS the hardware_init.c file:
RDC_SetMrAccess(RDC, rdcMrOcram, 0x91f000, 0x920000, 0xFF, true, false);
The platform_info.c;
#define VRING0_BASE 0x91F000
#define VRING1_BASE 0x91F800
However, when I load the imx_rpmsg_tty.ko it does not create /dev/ttyRPMSG and it does with the default values. Do I miss something?
Hi Imanol,
Did you rebuilt Linux kernel with changes in arch/arm/mach-imx/imx_rpmsg.c?
Radim.
Hi Radim,
Yes, I did and /dev/ttyRPMSG does not appear.
Imanol
Hi Imanol,
I tried to change the address and it worked. The only thing that I had to change was the addresses in the files imx_rpmsg.c and platform_info.c.
Radim.
Hi Radim,
I only change those both and use the imx6sx-sdb-m4.dtb and I do not get it.
Which new addresses have you set?
Imanol