cancel
Showing results for 
Search instead for 
Did you mean: 

OPENAMP framework, initialize UART in seperate c file on DK2

meiss.M
Associate III

Hello,

I have started to use the OPENAMP framework, especially with the CubeMX generated file openamp.h to communicate between the A7 and M4.

The example DK2_TIMER1_OpenAmp_Solution works fine, but unfortunately the CubeMX generates all the initialization of the OPENAMP framework in the main.c . Equivalent to the DK2_Timer1 example is also the following example on github:

https://github.com/STMicroelectronics/STM32CubeMP1/tree/master/Projects/STM32MP157C-DK2/Applications/OpenAMP/OpenAMP_TTY_echo )

Within my project, I would like to move the OPENAMP stuff into a separate c-file. However, when doing this I experienced a re-initialization of the rpmsg_virtio_device *rvdev e.g. rpmsg_endpoint ept. This resulted into a linux kernel crash on the A7 when too many endpoints are created ...

Even though, as I can see in the directory structure, the file

Middlewares/Third_Party/OpenAMP/virtual_driver/virt_uart.h

does include the "openamp.h" and respectively uses functions from this CubeMX generated file. This confuses me a bit?

1st question: why is Middlewares/Third_Party/OpenAMP/virtual_driver/virt_uart.h not independent from the DK2_TIMER1_OpenAmp_Soluttion/Src/openamp.c ?

virt_uart.c for instance includes the VIRT_UART_Init( *huart ) initialization which is called from the main.c ?!

2nd question: where does the Middlewares/Third_Party/OpenAMP/virtual_driver/virt_uart.c/h come from? from ST? What is the intention of placing this into Middleware?

3rd question: Is it possible to keep the CubeMX initialization of the OPENAMP framework in the main.c:

MX_OPENAMP_Init(RPMSG_REMOTE, NULL);

and put any other function, like the UART device initialization and especially:

OPENAMP_check_for_message();

into a different c file?

4th question: Is there a possibility not to poll the mbox device, like:

void OPENAMP_check_for_message(void)
{
  MAILBOX_Poll(rvdev.vdev);
}

-> but instead is it possible, such that the A7 generates an interrupt on the M4, but only when a message is sent from the A7 processor to the M4, to start the routine for parsing the message?

2 REPLIES 2
Olivier GALLIEN
ST Employee

Hi @meiss.M​ 

Please find answer below.

1- The openamp.c is an ST abstraction layer on top of OpenAMP library, that is used to ensure legacy compatibility in case of OpenAMP libray API change.

Template files used to generate are available here: https://github.com/STMicroelectronics/STM32CubeMP1/tree/master/Middlewares/Third_Party/OpenAMP/app_if

2- Yes the virt_uart comes from ST. It shall be considered as a RPMsg service (so on top of OpenAMP) that simulates a serial interface. On Linux side there is an equivalence: a rpmsg_tty driver on top of rpmsg that exports a UART interface for the Linux userland

3- Yes the code we provide is “as example�?. So you can redesign it according to your need. But be careful, in this case your implementation could be overwritten if you reconfigure your project with STM32CubeMX

4- Theoretically it is possible. If you have a look in MAILBOX_Poll, this function just checks if flags(e.g. msg_received_ch1) have been set. Theses flags are set in IPCC interrupt handler.

So you could parse the message directly in the interrupt by modifying mbox_ipcc.c

But I'm discouraging you to do it. It is recommended to execute the minimum code under interrupt context. But more critical, This could result in deadlock because some OpenAMP resources are protected by mutexes. Thus, you could

Lock a mutex while sending a message, be interrupted on RPMsg reception (IPCC interrupt) and try again to lock the mutex under interruption context.

Hope this help,

BR,

Olivier

Olivier GALLIEN
In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
debugging
Lead

For 4. I have the same situation to wish to trigger M4 code from the A7 and get data form it not having to poll as the M4 runs time critical code. Would it not be an option for user space to trigger an (output) I/O pin that connects to the A4 on another (input) pin to trigger an interrupt on the M4 which then checks for a message or ? A bit cumbersome .. but it would be the only other way ?