Hi,
I am working with TI8168 and EZSDK 5.03, I am trying to use EDMA for data transfers on capture-encode OMX A8 application, the problem is as follows:I have a buffer declared on an A8 OMX file in the capture-encode example main.c, which gets a virtual address, the EDMA need a physical address in order to transfer data.
1. How can i translate the virtual address to address that can be used by the EDMA?
2. I am trying another approach which is to allocate the buffer in a physical address that i have read at the following post http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/716/t/164186.aspx where Tarakesh sais as follows:
You could do this:
Allocate buffers from shared region 2 in A8. Following is the code snippet
#include <ti/syslink/utils/IHeap.h>#include <ti/ipc/SharedRegion.h>
IHeap_Handle heap;
heap = SharedRegion_getHeap(2);
Buffer1 = Memory_alloc (heap,MAX_BUF_SIZE, 128, NULL);
I am trying to do this myself but i get the following error message:
Assertion at Line no: 1081 in /home/gabi/z3/z3-netra/z3-netra-RPS-20120221/ezsdk/component-sources/syslink_2_00_05_85/packages/ti/syslink/ipc/hlos/usr/SharedRegion.c: (id < SharedRegion_module->cfg.numEntries) : failed
Can anyone please help with that?
Thanks,Gabi
Hi Gabi,
I just noticed, previously I have already shared sample code on this thread (which was not working). I modified the same logic (marked with green color) and it started working for me.
Use below code and check if it works for you.
=========================================================
#include <stdio.h>#include <ti/syslink/Std.h>#include <ti/syslink/utils/IHeap.h>#include <ti/ipc/SharedRegion.h>#include <ti/syslink/utils/Memory.h>
/* Uncomment this define if OMX_Init() is already done */
#define OMX_ALREADY_DONE_IN_OTHER_PROCESS 1
int main(){ uint8_t *pBuffer = NULL; uint32_t IL_CLIENT_SR = 2; IHeap_Handle heap = NULL;
#ifndef OMX_ALREADY_DONE_IN_OTHER_PROCESS
OMX_Init();
#else
SysLink_setup();
#endif heap = (IHeap_Handle)SharedRegion_getHeap(IL_CLIENT_SR); if(NULL == heap) printf("Failed to allocate memory from shared region."); else { pBuffer = Memory_alloc(heap, 1382400, 128, NULL); if (pBuffer == NULL) printf("Memory Allocation successfull from Heap: %p.", heap); else printf("Allocated buffer from shared region: %0x ", (uint32_t)pBuffer); } return 0;}============================================================
Hi Kurnal,
Thank you very much for your help.
1. I am working with EZSDK ver 5.03.2. I am working with Z3 board, i haven't done any changes in memory map.
i didn't update to EZSDK ver 5.04 yet because Z3 are modifying the EZSDK before it can be used on there board and they havedn't released EZSDK ver 5.04 for their board yet. I am working with the capture encode_example and not the decode_mosicdisplay but i don't think it is making any difference.
Best regards,Gabi
I have updated my EZSDK ver to 5.04, in that version there is an OMX example called decode_mosaicdisplay.Memory allocation and translation of virtual address to physical is done there as follows:
heap = SharedRegion_getHeap(IL_CLIENT_SR);
pBuffer = Memory_alloc (heap, pAppData->decILComp->outPortParams->nBufferSize, 128, NULL);
pTempBuffer = (OMX_PTR) DomxCore_mapUsrVirtualAddr2phy ((uint32_t)pBuffer);
Hello Gabi,
I succeeded in allocating the buffer in SR 2 thanks to your help. I was wondering how you went about using the EDMA in the A8 and DSP. I'm having trouble figuring how best to communicate with the kernel driver (edma_test). On the DSP side, I have tried compiling the demo with my VLPB code as well as including the libraries, 4 of them total, but I get a couple missing symbols. Is there anything you say about these topics?
-Roberto
Hi Roberto,
The DSP can not use the edma_test similar to the A8, the edma_test uses linux kernel low level driver, in the DSP there is no linux, therefor you should use EDMA_LLD library which is suitable for the DSP/BIOS operating system on the DSP. You should write your something like the edma_test using EDMA_LLD functions. A good start will be the edma example found in
<ezsdk>/component-sources/edma3lld_xx_xx_xx_02/examples/CSL2_DAT_DEMO/src/dat_edma3LLD/
Good luck,Gabi
Gabi,
Yes I realized that for the A8 I would have to use the kernel module and for the DSP I would need CSL2_DAT_DEMO. I have resolved using the driver for A8 by using ioctl to communicate with the drive. A very similar use case can be found at http://processors.wiki.ti.com/index.php/TI81XX_PSP_PCI_Express_Endpoint_Driver_User_Guide, which I merged with the one located in the psp examples.
For the DSP I copied the CSL2_DAT_DEMO into VLPB source and linked the 4 EDMA libraries to the final DSP firmware, but I got unrecognized symbols. If you got this to succeed any help would be appreciated as I may still have use for EDMA in the DSP.
For now I have developed a way to pass DSP allocated memory to the Arm via a pointer through the VLPB output buffer. This will help to reduce the need to copy by passing structures back to the Arm without a memcpy or dma transfer. There are some downsides to it, but less copying means less wasted memory :)
Regards,Roberto
Sorry for the long time it took me to answer i was at a long vacation, what EZSDK version are you using? i had some problems compiling the EDMA_LLD in EZSDK 5.04 but they were solved in EZSDK 5.05.
Gabi
I am using Ezsdk 5.05 from Z3 tech. Turns out my problem was that I wasn't using the configuration options that were in the example. As soon I added those in it started to work. Anyway, thanks for replying.
Even using EDMA, we still don't get the kind of performance we need. But perhaps we still need to refine our code and use EDMA in more places.
Thank you,
Roberto
Hi Robero,
Are you familiar with writing optimal code for DSP using intrinsic functions?Are you familiar with the scheme of slice processing with double input and output buffers copied to/from DSP L2 using EDMA?The idea of double buffer is that when the edma copies one input buffer to L2 the DSP processes the other L2 input buffer and then they switch. same for the output.
This can give you much better performances with the DSP.
I didn't want to bother you again but I can't find information about setting the L2 memory to be RAM instead of cache.
I also couldn't find an appropriate C command to allocate memory within this L2 RAM. I did try Memory_alloc() which should allocate in whatever heap I choose, but fails when I select DSP_Internal_heap as the location.
Thank you for all the help.
In the file ezsdk/component-sources/omx_xx_xx_xx_xx/src/ti/omx/build/dspsubsys.xs
you can see that L2 is set to be 64K of cache, all other L2 can be used for placing your L2 buffers
else if (soc == 'ti816x') {var device = 'TMS320TI816X';Build.platformTable['ti.platforms.generic:plat'] ={ clockRate: 800.0, catalogName: 'ti.catalog.c6000', deviceName: device, regs: {l1DMode: "32k"}, regs: {l1PMode: "32k"}, regs: {l2Mode: "64k"}, customMemoryMap: MemSegDefine.getMemSegmentDefinition(platFormMem), codeMemory:"DSP", dataMemory:"DSP", stackMemory:"DSP"};
In the file ezsdk/component-sources/omx_xx_xx_xx_xx/src/ti/omx/build/MemSegmentDefinition.xs you can add something like this:
memory[2] = ["DSP_L2", { name: "DSP_L2", base: 0x800000, len: 0x0030000, space: "code/data" }];
and in the file ezsdk/component-sources/omx_xx_xx_xx_xx/examples/ti/omx/demos/dm81xx/AppMemSegPlacement.cfg you can write
if (cfgArgs.coreName.match("DSP")) { /* * Do section mapping to memory regions */ Program.sectMap[".vecs"] = "DSP";Program.sectMap[".cinit"] = "DSP"; Program.sectMap[".pinit"] = "DSP"; Program.sectMap[".args"] = "DSP"; Program.sectMap[".switch"] = "DSP"; Program.sectMap[".bss:eventList"] = "DSP"; Program.sectMap[".const"] = "DSP";Program.sectMap[".fardata"] = "DSP"; Program.sectMap[".data"] = "DSP"; Program.sectMap[".sysmem"] = "DSP"; Program.sectMap[".far"] = "DSP"; Program.sectMap[".cio"] = "DSP"; Program.sectMap[".systemHeap"] = "DSP"; Program.sectMap[".stack"] = "DSP"; Program.sectMap[".stackMemory"] = "DSP"; Program.sectMap[".far:taskStackSection"] = "DSP"; Program.sectMap[".plt"] = "DSP"; Program.sectMap[".intHeap_0"] = "DSP"; Program.sectMap[".intHeap_1"] = "DSP"; Program.sectMap[".intHeap_2"] = "DSP"; Program.sectMap["aacEncProgram"] = "DSP"; Program.sectMap["My_l2_Buffers"] = "DSP_L2"; }
Now in your source files you can allocate buffers in L2 as follows:
#pragma DATA_SECTION(Y, "My_l2_Buffers")#pragma DATA_ALIGN(My_Buf1,128)unsigned char My_Buf1[WIDTH*HEIGHT];
Thank you for this complete outline! Where did you find how to do this? I'd like to better understand what is going on
It was combination of previous knowledge with TI DSPs and trial and error. I am not sure this is the best\recommended\optimal way, but it worked for me.
From your outline I was able to get the Memory_alloc function to track my memory use at runtime, instead of allocating at compile time using Pragma.
In ~/ezsdk/component-sources/omx_05_02_00_46/examples/ti/omx/demos/dm81xx/DspAppMain.cfg I added:
var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem');var heapMemParams2 = new HeapMem.Params;/* First allocation of memory for L2RAM */heapMemParams2.size = 0x00038000; //Same as MemSegmentDefinition.xs size to use all of your L2 RAMheapMemParams2.sectionName = "My_l2_Buffers";var heap1 = HeapMem.create(heapMemParams2);Program.global.DSP_HEAPINT_MEM = heap1;Memory.Object__heap = heap1;
Then in your dsp code:
#include <xdc/std.h>#include <xdc/runtime/IHeap.h>#include <xdc/runtime/System.h>#include <xdc/runtime/Memory.h>#include <xdc/runtime/Error.h>#include <xdc/cfg/global.h>extern IHeap_Handle DSP_HEAPINT_MEM;
char * MyBuffer = Memory_alloc((IHeap_Handle)DSP_HEAPINT_MEM, size, 128, NULL);
I am facing a problem, when i am working with an OMX chain that doesn't contain VLPB my EDMA driver for A8 is working ok.When i am working with an OMX chain that contains VLPB that uses EDMA on the DSP, my A8 EDMA stop working.Have you encountered and solved such a problem in your work?