MCC for FreeRTOS

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MCC for FreeRTOS

5,334 Views
imanolallende
Contributor III

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?

Labels (1)
25 Replies

3,403 Views
radimkratochvil
NXP Employee
NXP Employee

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.

0 Kudos

3,403 Views
imanolallende
Contributor III

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

0 Kudos

3,403 Views
radimkratochvil
NXP Employee
NXP Employee

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.

3,403 Views
imanolallende
Contributor III

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

0 Kudos

3,403 Views
BiyongSUN
NXP Employee
NXP Employee

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.

Untitled.png

0 Kudos

3,403 Views
imanolallende
Contributor III

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();

0 Kudos

3,403 Views
BiyongSUN
NXP Employee
NXP Employee

You can not comment the code, instead, you need to add the code to configure the MPU(menory protect unit).

please check the attached patch.

The memory layout like following:

Untitled.png

0 Kudos

3,403 Views
imanolallende
Contributor III

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

0 Kudos

3,403 Views
BiyongSUN
NXP Employee
NXP Employee

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

Untitled.png

0 Kudos

3,402 Views
imanolallende
Contributor III

But it is also mapped in those addresses, no? In the linux device tree I use 0x900000.

pastedImage_1.png

    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);

0 Kudos

3,402 Views
BiyongSUN
NXP Employee
NXP Employee

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.

0 Kudos

3,402 Views
imanolallende
Contributor III

Both appear in the CM4 table:

pastedImage_1.png

0 Kudos

3,403 Views
BiyongSUN
NXP Employee
NXP Employee

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 */

0 Kudos

3,403 Views
niranjanbc
Contributor IV

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.

0 Kudos

3,404 Views
radimkratochvil
NXP Employee
NXP Employee

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.

0 Kudos

3,404 Views
imanolallende
Contributor III

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?

0 Kudos

3,404 Views
radimkratochvil
NXP Employee
NXP Employee

Hi Imanol,

 

Did you rebuilt Linux kernel with changes in arch/arm/mach-imx/imx_rpmsg.c?

 

Radim.

0 Kudos

3,404 Views
imanolallende
Contributor III

Hi Radim,

Yes, I did and /dev/ttyRPMSG does not appear.

Imanol

0 Kudos

3,404 Views
radimkratochvil
NXP Employee
NXP Employee

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.

3,404 Views
imanolallende
Contributor III

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

0 Kudos