This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

J721EXSOMXEVM: IPC synchronization MCU2_0 to MCU2_1

Part Number: J721EXSOMXEVM

Tool/software:

I am having trouble getting IPC to consistently work between two R5 cores using the J721EXSOMXEVM and carrier board using IPC on freertos.  

I did get the IPC echotest freertos to work, Though it is complex to work with becasue of all the different possible processors and boards it supports.

However, I used it as an example for a much simpler application that I wanted to prove out.

MCU2_0 has data that it wants to send to MCU2_1 who will receive it. However, This does not consistently work depending on how the two processors are started up. So  I did some searching and found the following forum discussion that seemed relevant:

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/917749/tda4vmxevm-ipc-lld-sequence/3440000#3440000

So I implemented a method/function that tries to do exaclty what is outlined in that "solution" 

So each of my processors has a function they implement in a task that does the following:

 - Initializes all the IPC stuff (Ipc_init, VirtIO, RPMessage_init)

-  Call an RPMessage_create to get a handle and my endpoint

- RPMessage_annouce a common service name

- RPMessage_getREmoteEndPt

- RPMessage_send a dummy message ("TestX where X is the source processor number)

- RPMessage_recv the dummy message.

However, that synchronization does not work for me.  I have to start the MCU2_1 processor first to even get past the Announce and get to the message sends and receives. Then MPU2_1 gets the sent message but MPU2_0 never gets MPU2_1's sent message.

If I start MCU2_0 first then I never get the Announce from either of them.  

This order and timing of how the IPC must be started is not making sense to me.

  • Hello,

    I did get the IPC echotest freertos to work, Though it is complex to work with becasue of all the different possible processors and boards it supports.

    However, I used it as an example for a much simpler application that I wanted to prove out.

    ipc_echo_test is a very basic sample application in IPC. If you don't want communication with all cores then you can keep only remote proc what are needed.

    So each of my processors has a function they implement in a task that does the following:

     - Initializes all the IPC stuff (Ipc_init, VirtIO, RPMessage_init)

    -  Call an RPMessage_create to get a handle and my endpoint

    - RPMessage_annouce a common service name

    - RPMessage_getREmoteEndPt

    - RPMessage_send a dummy message ("TestX where X is the source processor number)

    - RPMessage_recv the dummy message.

    This is the same thing we do in ipc echo test.

    RPMessage_Announce , announces message to all the cores or respective cores as needed.

    By the time RPMessage_Announce is called the other core has to be up to receive the messages otherwise we can lose the message.If you announce from MCU2_1 then make sure MCU2_0 is ready before MCU2_1 it is that simple.

    If it appears complex to you beacuse of freeRTOS tasks you can go ahead with  ipc_testsetup_baremetal.c example.

    Regards

    Tarun Mukesh

  • Tarun,

    Thank you for your response. 

    Please understand that we are not beginner embedded programmers and have a lot of experience with RTOS, baremetal, multi-threaded applications, low level drivers etc.  But, we are new to the TI platform and way of working and are struggling with some "basic" things as you put it.

    It may also be helpful to mention that since we are running 2 RTOS cores we are not using Linux to run the apps but using a JTAG. It is hard to get consistent  startup timing using CCS UI to start the two cores. Maybe I should be using a script to start them?

    ipc_echo_test is a very basic sample application in IPC. If you don't want communication with all cores then you can keep only remote proc what are needed.

    Yes, We have already done that and used the examples as an educational experience to understand how the IPC should be working. Though, it is worth mentioning that even the basic examples only worked for us if we built and ran them in "release" mode. If built and run in "debug" mode then they would not consistently work. Thus, our suspision that there was some timing or other principles going on. After getting the very basic example working we then used that as a template to write our own IPC application using MCU2_0 and MCU2_1 trying to follow the same principles. When our app did not act as expected and after trying to trouble shoot it with no sucess we reached out here, to the forums, for some help.

    By the time RPMessage_Announce is called the other core has to be up to receive the messages otherwise we can lose the message.If you announce from MCU2_1 then make sure MCU2_0 is ready before MCU2_1 it is that simple.

    I do understand that the processors have to be "up" to some extent before the IPC announce from one to the other can happen.  Though this is not in and of itself an obvious fact but something we learned from the forum posts and experience. However, what does "up" or "ready" mean? Powered up, starting to run, having called the IPC_Init function?  I think it would be useful if you could define "up" a bit more concicely. 

    If our app has both cores announce to eachother at what state of "up" does each processor need to be at? The forum post I referenced mentioned that RPMessage_init() had to be called on the receiving processor before the Announce on the other processor or it would not get the announce. Is this true?

     Finally, Our app has, on occasion, successfully announced to eachother and received the announcement on each processor, but then, about half the time, the next step of sending dummy messagages to eachother has resulted in one receiving a message and the the other one never getting its message. I had hoped that once they had synched up that the sending of messages would just work.

    I am not expecting anyone to debug our code or anyting like that. I just need ideas, things to look at, information about IPC timing or function that I am maybe missing.

    Thank you.

  • Hello,

    Ok sure.Great to know about your details.

    Let me breakdown your queries and answer one by one.

    It may also be helpful to mention that since we are running 2 RTOS cores we are not using Linux to run the apps but using a JTAG. It is hard to get consistent  startup timing using CCS UI to start the two cores. Maybe I should be using a script to start them?

    If you want to start 2 cores at once select the both cores in your case MCU2_0 and MCU2_1 in CCS and make them as a group.

    No need of scripts additionally. If you run the group then both cores will start simultaneously.

    I do understand that the processors have to be "up" to some extent before the IPC announce from one to the other can happen.  Though this is not in and of itself an obvious fact but something we learned from the forum posts and experience. However, what does "up" or "ready" mean? Powered up, starting to run, having called the IPC_Init function?  I think it would be useful if you could define "up" a bit more concicely. 

    Ready  means , already core is running and IPC initialization is done.

    If our app has both cores announce to eachother at what state of "up" does each processor need to be at? The forum post I referenced mentioned that RPMessage_init() had to be called on the receiving processor before the Announce on the other processor or it would not get the announce. Is this true?

    If both cores are doing RPMessage_Announce then you can always use RPMessage_getRemoteEndPt as a blocking call on one core .

    and also based on status from RPMessage_Announce you can re-announce if it is failed in the earlier scenario.

     Finally, Our app has, on occasion, successfully announced to eachother and received the announcement on each processor, but then, about half the time, the next step of sending dummy messagages to eachother has resulted in one receiving a message and the the other one never getting its message. I had hoped that once they had synched up that the sending of messages would just work.

    If Announce is successful and other received the end point details means the sync happened. unless the other core shutdown or aborts or go into exception mode the send and receive should go on without hassle.

    We have 512*256 buffer limit , 496 bytes of data into 256 buffers .If you keep sending data more than this , and other core doesn't read up then we might lose messages but anything below this should not be an issue.

    Reference material :https://dev.ti.com/tirex/explore/content/tda4vm_academy_1_01_00_00/_build_tda4vm_academy_1_01_00_00/_downloads/29e369bee60741ce211f389f47fb9bd4/IPC-training.pdf

    Thanks for understanding.

    Regards

    Tarun Mukesh

  • Tarun,

    That is helpful information.  Especially the ability to group the CPUs and start them at the same time.

    I am in the process of taking the IPC echo test example, which we can get to work, and step by step changing it into the form that we need for our application.  I will let you known if an when I run into trouble.

  • Hi ,

    Thanks.

    Sure let me know if you face any trouble.

    Regards

    Tarun Mukesh