cancel
Showing results for 
Search instead for 
Did you mean: 

How to use DMA to transfer data from SRAM to a DDR buffer

PComb.1
Associate

Hi everyone,

I'm new to using MPUs.

For an application, I need to transfer data from the SRAM (data obtained with the M4) to a DDR buffer in order to communicate with the A7. I based my application on the example here : How to exchange large data buffers with the coprocessor - example - stm32mpu

But in this code, the address of the buffer where to transfer the data by DMA is not given explicitly.

So I'm trying to find these addresses to develop my application.

I am using STM32MP157C-DK2 board.

I hope my question is not too confusing.

Thanks,

PComb.1

1 REPLY 1
Kevin HUBER
ST Employee

Hello @PComb.1​ 

Since the time you created the post, I think you answered your question, but I will try to explain how it works. (It can help other people with the same issue).

First, please a look again at the page: https://wiki.st.com/stm32mpu/wiki/How_to_exchange_data_buffers_with_the_coprocessor

This page changed a lot since you asked your question. The latest version at this time is from 20 July 2021.

In this page, you can download the M4 sources and A7 sources of the example to understand how it works.

Little explanation:

The DDR buffers are mapped from the linux side (A7) in the function sdb_thread() of the backend.c

 mmappedData[i] = mmap(NULL,
                                DATA_BUF_POOL_SIZE,
                                PROT_READ | PROT_WRITE,
                                MAP_PRIVATE,
                                mFdSdbRpmsg,
                                0);
        printf("\nCA7 : DBG mmappedData[%d]:%p\n", i, mmappedData[i]);

The first parameter of mmap is NULL, which means that the kernel chooses the (page-aligned) address at which to create the mapping. But as explained in the mmap man, you can specify an ADDR in the first parameter and the kernel takes it as a hint about where to place the mapping.

Once the DDR buffer is allocated, the information of the buffers (ADDR and size) is shared with the CM4 side by using the RPMsg service.

The information are then read from M4 side.

On M4 side, the buffer information is got from the function treatSDBEvent() which is called by the statemachine from main.c:

/**
  * @brief  Function which implements tha LogicAnalyser machine state.
  * @retval none
  */
void LAStateMachine(void) {
    OPENAMP_check_for_message();
    switch (mMachineState) {
    case INITIALIZING:
    	// waiting for SDB driver events, with at least 3 DDR buffers
        if (SDB0RxMsg) {
            SDB0RxMsg = RESET;
            treatSDBEvent();
        	if (mArrayDdrBuffCount >= mDdrBuffCount) {	// is number of buffer in line with received command ?
        		mMachineState = DDR_BUFFERS_OK;

The function treatSDBEvent handles the data and gets the addr and the size of the DDR buffer sent by the linux side:

    // save DDR buff @ and size
    mArrayDdrBuff[mArrayDdrBuffCount].physAddr = (uint32_t)strtoll((char*)&SDB0ChannelBuffRx[3], NULL, 16);
    mArrayDdrBuff[mArrayDdrBuffCount].physSize = (uint32_t)strtoll((char*)&SDB0ChannelBuffRx[12], NULL, 16);

Once this step is done, A7 side and M4 side have the physical addresses, the sizes of the DDR buffers and can use them to exchange data.

Regards,

Kévin

In order to give better visibility on the answered topics, please click on 'Select as Best' on the reply which solved your issue or answered your question. See also 'Best Answers'

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.