utilisation of multiple transmit/receive registers of the Messaging Unit

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

utilisation of multiple transmit/receive registers of the Messaging Unit

Jump to solution
5,169 Views
erikfriedel
Contributor III

Hi

I am currently working with the iMX7. Both IPC examples worked for me.

In the reference manual, there are four transmit/receive registers for data transfer. Does this mean, you can utilize up to four channels independently to transfer data? Or are the used "parallel" so that every register takes a quarter of the message? I know, that you can have multiple channels but I am unable to figure out how to edit the code so I can use them.

Maybe important snippets I found in the code are following:

Linux side:

"mu.c"

   #define MU_RPMSG_HANDSHAKE_INDEX 1

FreeRTOS side:

"rpmsg_platform_porting"

   #define RPMSG_MU_CHANNEL (1)

It would be quiet convenient if I could just assign the channel where I send the message.

Like: "rpmsg_rtos_send(app_chnl2->rp_ept, &msg, sizeof(THE_MESSAGE), app_chnl2->dst);"

instead of "rpmsg_rtos_send(app_chnl->rp_ept, &msg, sizeof(THE_MESSAGE), app_chnl->dst);"

Please try to explain it to me.

Erik

Labels (2)
1 Solution
4,586 Views
dusancervenka-b
NXP Employee
NXP Employee

No, Mu can work with 4 register as 4 messages or one bigger message. Rpmsg using MU is using one register and channel. You can have more endpoints for one channel, but still it will use one register.

View solution in original post

11 Replies
4,586 Views
art
NXP Employee
NXP Employee

Theoretically, the software can use 4 MU channels either independently or as a single channel, it's all defined by software.

The current RPMsg implementation seems to use a single registe as a single channel.

0 Kudos
4,586 Views
erikfriedel
Contributor III

Thank you

I have worked a bit on the mu.c, and now I can change the used Reigster by changing the used Index and not changing a bunch of bits. It have worked for me. I know its kinda dirty but I want to share it in case it could be useful for you.

I am using embedded Linux 4.1.15 2.0.0

To change the Register you just have to increase the MU_LPM_HANDSHAKE_INDEX and the MU_RPMSG_HANDSHAKE_INDEX.

diff --git a/arch/arm/mach-imx/mu.c b/arch/arm/mach-imx/mu.c

index 643fee8c3cfb..04341175e23d 100644

--- a/arch/arm/mach-imx/mu.c

+++ b/arch/arm/mach-imx/mu.c

@@ -267,7 +267,7 @@ static void mu_work_handler(struct work_struct *work)

       }

       m4_message = 0;

       /* enable RIE3 interrupt */

-       writel_relaxed(readl_relaxed(mu_base + MU_ACR) | BIT(27),

+       writel_relaxed(readl_relaxed(mu_base + MU_ACR) | BIT(27 - MU_LPM_HANDSHAKE_INDEX),

               mu_base + MU_ACR);

}

 

@@ -330,17 +330,17 @@ static irqreturn_t imx_mu_isr(int irq, void *param)

       irqs = readl_relaxed(mu_base + MU_ASR);

 

       /* RPMSG */

-       if (irqs & (1 << 26)) {

+       if (irqs & (1 << (26 - MU_LPM_HANDSHAKE_INDEX))) {

               /* get message from receive buffer */

-               m4_message = readl_relaxed(mu_base + MU_ARR1_OFFSET);

+              m4_message = readl_relaxed(mu_base + MU_ARR1_OFFSET + 0x4 * MU_LPM_HANDSHAKE_INDEX);

           //0x14 --> 0x18 bei verwendung von Reg2

               schedule_delayed_work(&rpmsg_work, 0);

       }

 

-       if (irqs & (1 << 27)) {

+       if (irqs & (1 << (27 - MU_LPM_HANDSHAKE_INDEX))) {

               /* get message from receive buffer */

-               m4_message = readl_relaxed(mu_base + MU_ARR0_OFFSET);

+               m4_message = readl_relaxed(mu_base + MU_ARR0_OFFSET + 0x4 * MU_LPM_HANDSHAKE_INDEX);

           //0x10 --> 0x14 bei verwendung von Reg2

               /* disable RIE3 interrupt */

-               writel_relaxed(readl_relaxed(mu_base + MU_ACR) & (~BIT(27)),

+               writel_relaxed(readl_relaxed(mu_base + MU_ACR) & (~BIT(27 - MU_LPM_HANDSHAKE_INDEX)),

                       mu_base + MU_ACR);

               schedule_delayed_work(&mu_work, 0);

       }

@@ -387,7 +387,7 @@ static int imx_mu_probe(struct platform_device *pdev)

              INIT_DELAYED_WORK(&mu_work, mu_work_handler);

               /* enable the bit26(RIE1) of MU_ACR */

               writel_relaxed(readl_relaxed(mu_base + MU_ACR) |

-                       BIT(26) | BIT(27), mu_base + MU_ACR);

+                       BIT(26 - MU_LPM_HANDSHAKE_INDEX) | BIT(27 - MU_LPM_HANDSHAKE_INDEX), mu_base + MU_ACR);

               /* MU always as a wakeup source for low power mode */

               imx_gpcv2_add_m4_wake_up_irq(irq_to_desc(irq)->irq_data.hwirq,

                       true);

@@ -397,10 +397,10 @@ static int imx_mu_probe(struct platform_device *pdev)

               INIT_DELAYED_WORK(&mu_work, mu_work_handler);

 

               /* enable the bit27(RIE3) of MU_ACR */

-               writel_relaxed(readl_relaxed(mu_base + MU_ACR) | BIT(27),

+               writel_relaxed(readl_relaxed(mu_base + MU_ACR) | BIT(27 - MU_LPM_HANDSHAKE_INDEX),

                       mu_base + MU_ACR);

               /* enable the bit31(GIE3) of MU_ACR, used for MCC */

-               writel_relaxed(readl_relaxed(mu_base + MU_ACR) | BIT(31),

+               writel_relaxed(readl_relaxed(mu_base + MU_ACR) | BIT(31 - MU_LPM_HANDSHAKE_INDEX),

                       mu_base + MU_ACR);

 

               /* MU always as a wakeup source for low power mode */

@@ -409,7 +409,7 @@ static int imx_mu_probe(struct platform_device *pdev)

 

       INIT_DELAYED_WORK(&rpmsg_work, rpmsg_work_handler);

       /* enable the bit26(RIE1) of MU_ACR */

-      writel_relaxed(readl_relaxed(mu_base + MU_ACR) | BIT(26),

+       writel_relaxed(readl_relaxed(mu_base + MU_ACR) | BIT(26 - MU_LPM_HANDSHAKE_INDEX),

                       mu_base + MU_ACR);

       BLOCKING_INIT_NOTIFIER_HEAD(&(mu_rpmsg_box.notifier));

4,586 Views
dusancervenka-b
NXP Employee
NXP Employee

Hi erikfriedel‌,

as i know both questions have answer "yes". Can be 4 independent channels, or one channel where you can send 4 words at once. It is used just one because of implementation in linux kernel wants one.

But maybe you will like:
GitHub - codeauroraforum/rpmsg-sysfs at 0aa1817545a765c200b1b2f9b6680a420dcf9171 

c++

erpc-imx-demos/middleware/rpmsg-cpp at master · EmbeddedRPC/erpc-imx-demos · GitHub 

python

erpc-imx-demos/middleware/rpmsg-python at master · EmbeddedRPC/erpc-imx-demos · GitHub 

0 Kudos
4,586 Views
erikfriedel
Contributor III

Hi

Sry for asking again but do you know, what have to be changed, in order to use a different Messaging Unit Register for RPMsg?

In FreeRTOS it should be fine to change the RPMSG_MU_CHANNEL in "rpmsg_platform_porting.h".

In Linux, in "mu.c", I added an offset of 0x4 to MU_ATR0_OFFSET, MU_ARR0_OFFSET and MU_ARR1_OFFSET and added 1 to MU_LPM_HANDSHAKE_INDEX and MU_RPMSG_HANDSHAKE_INDEX.

So everything should be the same except one Channel higher, but the service Handshake between the cores did not happen.

Is there some hidden file or a clock I have to activate or something else I forgot?

Edit:

MU_ACR and MU_ASR are the Control and Status Register of processor A messaging unit. They contain Information about every register. The code uses a Mask and an Index to extract the needed Bit. So changing the Index will make it work? NO!

In some cases the Bit, which has to be read, is declared without the Index of which channel is used. So one have to change some of them by hand.

e.g.: line 153: (((val & (1 << (20 + 3 - index))) == 0) || (ep == BIT(4)));            //Bit 20-23 ASR -->Transmit Register n Empty

        line 270: writel_relaxed(readl_relaxed(mu_base + MU_ACR) | BIT(27),mu_base + MU_ACR);      //Bit 24-27 ACR --> Processor A Receive Interrupt Enable n

I'll update this later.

0 Kudos
4,586 Views
erikfriedel
Contributor III

Thank you for your reply.

So there is no "easy" way to tell Linux and FreeRTOS to use the 4 channels separately, other than dig deep into the API?

In the kernel doc (https://www.kernel.org/doc/Documentation/rpmsg.txt) I found this line: "At this point we only support dynamic allocations of rpmsg channels. [...] The plan is also to add static creation of rpmsg channels via the virtio
config space, but it's not implemented yet."

Does this confirm my assumption?

Best Regards

Erik

0 Kudos
4,586 Views
dusancervenka-b
NXP Employee
NXP Employee

Sorry i am not sure. But do you really need them? Are you communicating between linux and Freertos or between linux and multiple Freertos... Because you can have several endpoints on that channel...

0 Kudos
4,586 Views
erikfriedel
Contributor III

Hi

I got the task, to find out if you can use multiple channels within one FreeRTOS. So if you receive signals through two interfaces with the M4, you can use channel 1 for one signal and channel 2 for the other signal. It would be more easy to manage if each signal have an own channel.

Or am I thinking completely wrong and you can achieve the same thing with different endpoints?

0 Kudos
4,586 Views
dusancervenka-b
NXP Employee
NXP Employee

You can probably have multiple channels with rpmsg but for MU it is not implemented i think. 

RPMsg endpoints provide logical connections on top of RPMsg channel. It allows the user to bind multiple rx callbacks on the same channel.

Every RPMsg endpoint has a unique src address and associated call back function. When an application creates an endpoint with the local address, all the further inbound messages with the destination address equal to local address of endpoint are routed to that callback function. Every channel has a default endpoint which enables applications to communicate without even creating new endpoints.

4,586 Views
erikfriedel
Contributor III

ok now I understand.

So if I run the demo apps, all 4 registers are used by default. And if I want do assign a signal to a channel, I instead assign to an endpoint.

So in conclution I can have one channel, which uses all 4 registers and have multiple endpoints on this channel?

0 Kudos
4,587 Views
dusancervenka-b
NXP Employee
NXP Employee

No, Mu can work with 4 register as 4 messages or one bigger message. Rpmsg using MU is using one register and channel. You can have more endpoints for one channel, but still it will use one register.

4,586 Views
erikfriedel
Contributor III

Ok. So no 4 registers with the demo apps.

Thank you for you help. :smileyhappy:

0 Kudos