Because of the Thanksgiving holiday in the U.S., TI E2E™ design support forum responses may be delayed from November 25 through December 2. Thank you for your patience.

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.

TDA4AL-Q1: how to map a physical addr to virtual addr on linux platform

Part Number: TDA4AL-Q1

mcu2_0:

physical_addr_ = appMemGetVirt2PhyBufPtr

send the physical_addr to Linux

and then how to map the physcal addr to virtual address?

  • Hi Bruce,

    You can use the below function in Linux drivers to get virtual address for a physical address: https://www.thegeekdiary.com/what-is-ioremap/

    Best Regards,
    Keerthy

  • if use function ioremap, the header file <asm/io.h> have to be included.

    But how set the include path?

    Additionally,  i wanna describe the background

    we allocate the vx_image on MCU2_0, then get the data_ptr by map

    and then get pyhsical addr of the data_ptr by calling function appMemGetVirt2PhyBufPtr

    and then send the physical addr to A72 on Linux, we need to dump vx_image content and pass the physical addr to ldc node,  how to use or translate the physical addr?

  • Hi Bruce,

    In the SDK, OpenVX runs with A72 as host. Hence, allocation of the data objects such as vx_image would be done by A72 using the dma_buf framework, where the framework keeps track of the virtual address and the corresponding physical addresses using file descriptor.

    You could see this in the appMemAlloc() API in ${PSDKRA}/vision_apps/utils/mem/src/app_mem_linux_dma_heap.c

    This allocation by A72 happens in the DDR_SHARED_MEM region which is accessible to all cores.

    Hence calling appMemGetVirt2PhyBufPtr() would return the physical address from the virtual address from the mem_map_list created during appMemAlloc().

    If appMemGetVirt2PhyBufPtr() is called from R5, then here virt addr = phy addr (as the allocation happens directly using physical address.

    Regards,

    Nikhil

  • In order to quickly get the image, we construct the CaptureNode on mcu2_0, so the host is mcu2_0, and then we need to send the physical addr of vx_image to A72 linux.  and the dump the vx_image or send to other openvx Node on Linux.

    Now, the issue is  how to get the virtual addr on linux?

    mcu2_0 code

    vx_char name[VX_MAX_REFERENCE_NAME];
                        snprintf(name, VX_MAX_REFERENCE_NAME, "capture_node_raw_image_arr_%d", q);
                        vxSetReferenceName((vx_reference)captureObj->raw_image_arr[q], name);
                        /// new added code for quick capture
                        int k = 0;
                        for (k = 0; k < sensorObj->num_cameras_enabled; k++) {
                            vx_image img = (vx_image)vxGetObjectArrayItem(captureObj->raw_image_arr[q],k);
                            void *ptr[1] = {appMemAlloc(APP_MEM_HEAP_DDR, 1920*1300*2, 1)};
                            void *pre_ptr[1];
                            vxSwapImageHandle(img, ptr, pre_ptr, 1);                        
                        }

    frameInfo.info[index].data_ptr[i] = appMemGetVirt2PhyBufPtr((uint64_t)data_ptr, APP_MEM_HEAP_DDR);

    status = appIpcSendNotifyPort(APP_IPC_CPU_MPU1_0, &frameInfo, obj->port_id, sizeof(frameInfo));

    //Linux code:

    if (devMemFd == -1)
        {
            // devMemFd = open("/dev/dma_heap/vision_apps_shared-memories", O_RDWR | O_SYNC);
            // devMemFd = open("/dev/dma_heap/cam_apps_shared-memories", O_RDWR | O_SYNC);

             devMemFd = appMemGetDmaBufFd((void *)phyAddr, &offset);
             printf("APP_MEM: %d: Exported dmaBufId with offset %d\n", devMemFd, offset);
           
            if (devMemFd < 0)
            {
                status = -1;
            }
            printf(" Allocated!\n");
        }

        if ((0 == status) && (0 <= devMemFd))
        {
            //taddr = (uintptr_t)phyAddr;
            //tsize = size;
            //tsize = appAlign(tsize + (taddr % pageSize), ...?);
            //taddr = appFloor(taddr, pageSize);
            printf("Before mmap physical_addr %ld size %u\n", (uint64_t)phyAddr, size);
            virtAddr = mmap(0, size, (PROT_READ|PROT_WRITE), MAP_SHARED, devMemFd, (int64_t)phyAddr);
            printf("After mmap\n");

            if (MAP_FAILED == virtAddr)
            {
                virtAddr = NULL;
                perror("Error: ");
                printf("mmap failed\n");
            }
        }

    appMemGetDmaBuffFd return -1

    Does it need some configuration?  such as dtsi...

    how to config dtsi and how to use it?

  • Hi,

    The issue here is that when you do appMemAlloc() from MCU2_0, there exists only a physical address. There is no virtual address and fd present here.

    So, if you pass the physical address to appMemGetDmaBufFd(), it would return -1 because this function expects virtual address as its input and as per its implementation in app_mem_free_rtos.c in vision_apps/utils/mem/src/ this would return -1.

    This is the current implementation in the SDK as R5 as host is not supported in the SDK.

    However, if you have R5 as host running and you would want to convert physical to virtual address and send it to A72, 
    You could try the below approach.

    Step 1: You should run a linux application before running the rtos application.

    Step 2: In this Linux application, you would have to do mmap to the DDR_SHARED_MEM region as shown below 

    /*Global Variables*/
    void *PHY_VIRT_ADDR_OFFSET;
    
    void mem_Mapping_DDR_Shared_to_virt_offset()
    {
        void *DDR_shared_addr_virt = appMemMap((void *)DDR_SHARED_MEM_ADDR, (uint32_t)DDR_SHARED_MEM_SIZE);
        PHY_VIRT_ADDR_OFFSET = (DDR_shared_addr_virt - DDR_SHARED_MEM_ADDR);
    }

    appMemMap() is available at vision_apps/utils/console_io/src/app_log_linux.c

    Step 3: add this offset PHY_VIRT_ADDR_OFFSET to the physical address the MCU2_0 has allocated in DDR_SHARED_MEM to obtain the virtual address.

    The implementation of the offset is as shown below 

    Regards,

    Nikhil

  • Because of an user's requirement,  imges from capture is expected to get as soon as possibly. MCU2_0 start much earlier than A72 linux. So we construct openvx framework to get image with mcu2_0 as host.

    So we still need to allocate space on mcu2_0 firstly,  and then send a physical addr to A72 linux.

    Does not there exist a way to map a physical addr to virtual addr on Linux on this situation?

  • Hi Bruce,

    Is it a node that is running on A72 or is it another application?

    The reason for additional A72 application was because currently if it is a node on A72, R5 Host cannot send the ipc command to A72 within the OpenVX framework, without knowing the A72 endpoint. 

    Because of this, we are sending a dummy IPC command from A72 first and store the endpoint at R5F and then use this to send the data to A72 by the framework.

    Step 2: In this Linux application, you would have to do mmap to the DDR_SHARED_MEM region as shown below 

    If you are not using an OpenVX node on A72, then you could do the above on A72 once, and as you receive the physical address from R5, you could add this offset PHY_VIRT_ADDR_OFFSET to the physical address the MCU2_0 has allocated in DDR_SHARED_MEM to obtain the virtual address on A72.

    Is my understanding about your usecase correct?

    Regards,

    Nikhil

  • "Because of this, we are sending a dummy IPC command from A72 first and store the endpoint at R5F and then use this to send the data to A72 by the framework."

    Indeed, A72 receive the physical addr by the way you describe above.

    we have ever tried several ways to mmap the physical addr to virtual addr,  but all failed !

    // devMemFd = open("/dev/dma_heap/vision_apps_shared-memories", O_RDWR | O_SYNC);
    // devMemFd = open("/dev/dma_heap/cam_apps_shared-memories", O_RDWR | O_SYNC);
    devMemFd = open("/dev/mem", O_RDWR | O_SYNC);
    virtAddr = mmap(0, size, (PROT_READ|PROT_WRITE), MAP_SHARED, devMemFd, (int64_t)phyAddr);

    how to get devMemFd?

    "Step 2: In this Linux application, you would have to do mmap to the DDR_SHARED_MEM region as shown below "

    I can't see anything below, it's a blank table.

    "you could add this offset PHY_VIRT_ADDR_OFFSET to the physical address the MCU2_0 has allocated in DDR_SHARED_MEM to obtain the virtual address on A72."

    Could you describe the way in detail you said above?