nxp-mcuxpresso / rpmsg-lite

RPMsg implementation for small MCUs
BSD 3-Clause "New" or "Revised" License
235 stars 74 forks source link

RPMsg-Lite Bare Metal Example #45

Closed wonk-andy closed 11 months ago

wonk-andy commented 11 months ago

Hello,

Is there a working example of running RPMsg-Lite on bare metal (my target is i.MX8MM but the example doesn't need to be)?

The FreeRTOS example uses a queue, which bare metal doesn't have, and uses a blocking rpmsg_queue_recv() function.

If I try to use the FreeRTOS example as-is in my bare metal code then the linker complains about missing env_put_queue() and env_create_queue() functions. The bare metal Cortex-M4 firmware is the "remote" side.

Thanks in advance.

-Andy

MichalPrincNXP commented 11 months ago

Hello @wonk-andy , see https://github.com/nxp-mcuxpresso/rpmsg-lite#examples section for information about RPMsg_Lite multicore examples. There are baremetal examples available for several platforms like lpcxpresso55s69, frdmk32l3a6, evkmimxrt1160, evkmimxrt1170. In general, when switching from FreeRTOS to BM example: a. replace rpmsg_env_freertos.c by rpmsg_env_bm.c b. replace .../freertos/rpmsg_env_specific.h by .../bm/rpmsg_env_specific.h c. remove rpmsg_queue.c and rpmsg_queue.h from project

Regards Michal

wonk-andy commented 11 months ago

Hello @MichalPrincNXP

When using BM do you have to switch to using the static API (RL_USE_STATIC_API == 1) as per the other examples or can it be left disabled?

I have made the suggested changes and am testing using the imx_rpmsg_pingpong example under Linux on the master side. From what I can tell, the link is coming up on the remote side (rpmsg_lite_wait_for_link_up(my_rpmsg, RL_BLOCK); returns). My endpoint is being created (rpmsg_lite_create_ept() returns a non-zero value) but the callback never gets called.

Also, do I need to use MCMGR (the low level multicore management library)?

Any ideas?

-Andy.

MichalPrincNXP commented 11 months ago

Hi @wonk-andy one can use either static or dynamic API when using BM, so it can be left disabled. malloc/free functions will then be called for dynamic allocations, as defined in rpmsg_env_bm.c

I would test if the MU_M4_IRQHandler on the cm4 side is reached first. If so, it can be then debugged what happens when the MU interrupt is reached and why the callback is not reached.

MCMGR is not needed, it is used for cores management between two Cortex-Mx cores, not between Cortex-Ax and Cortex-Mx

Regards Michal

wonk-andy commented 11 months ago

Hi @MichalPrincNXP

The only time I see the MU_M4_IRQHandler get called is when the Linux kernel starts and the message is received to unblock rpmsg_lite_wait_for_link_up.

Update:

If I add the calls to rpmsg_ns_bind and rpmsg_ns_announce then I see a second interrupt occur. Working back from the interrupt handler functions then I get

MU_M4_IRQHandler() env_isr() (passed vector parameter is 0 and ISR_COUNT is 12) virtqueue_notification() (both of the null checks pass so vq->callback_fc(vq); must be getting executed.

What I don't ever see for these first two interrupts is my callback function being called.

Update 2:

vq->callback_fc(vq); appears to be calling rpmsg_lite_tx_callback() which then calls env_tx_callback() the empty function.

Update 3:

Found the issue! The Linux ping-pong example needs the rpmsg_ns_bind() and rpmsg_ns_announce() calls but also needs to announce using the same string as Linux is expecting!

I now have my bare metal firmware replicating the ping-pong example with Linux. Onto the next step, swap Linux for QNX!

-Andy