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.

RTOS/AM5728: DSP EMAC driver not working with Linux running

Part Number: AM5728

Tool/software: TI-RTOS

Hi,

I'm currently trying to integrate Linux IPC into the NIMU_BasicExample_evmAM572x_c66xExampleProject. Most part seems to be working, but the EMAC driver has some strange behaviour. I am able to send raw ethernet packages with the right length, but the sent data is just random garbage. As the data is passed by pointer my first assumption was that it's probably some "address resolution" problem. As the default data section of an application loaded by remoteproc seems to be in the Default CMA memory section and has on the DSP a virtual address.

So I tried different things:

1. I found a generated function that seemed like it could translate the address (_GateMP_virtToPhys), but the program just crashed after calling it without any debug information.

2. I tried to place my data I want to send in a place where physical and virtual address are the same. My first try was to place it in OCMC_RAM1 with various ways, but didn't succed.

3. My second try for a static data region was that I tried to put it in the EXC_DATA section. I could place it there, but the effect was still the same.

I use Linux / RTOS SDK version 05.02.00.10

I use the Linux image that came with the Linux SDK and modified the device tree to exclude the mac.

I would appreciate any help, as I am running out of ideas

  • Hi,

    First make sure the NIMU_BasicExample_evmAM572x_c66xExampleProject worked properly on DSP, without running Linux on A15.

    >>>>I am able to send raw ethernet packages with the right length, but the sent data is just random garbage. >>>> Not sure if you change this NIMU example or not. If you changed it, also make sure it worked standalone (without Linux on A15)

    Then, you can add a pdk_am57xx_1_0_xx\packages\ti\transport\ndk\nimu\src\v4\cpsw_nimu_eth.c into the NIMU_BasicExample_evmAM572x_c66xExampleProject and rebuilt it. The purpose is for you to easier set break point or change the driver code in the application (instead of change the cpsw_nimu_eth.c, rebuild the NIMU driver, finally linked with your application).

    If you load the DSP application via Linux + IPC, you need find a way to halt the DSP core, then load the symbol. And set break point at NIMU_send() function to see what data pointer passed in and how the data was corrupted.

    Regards, Eric
  • Hi,

    The example worked properly without running Linux on A15. I did some changes to the code (the basic example doesn't send any Ethernet frames), but all changes that I did worked fine without running Linux.

    Why the pdk_am57xx_1_0_xx\packages\ti\transport\ndk\nimu\src\v4\cpsw_nimu_eth.c? I stepped through the code and it seemed more like it would call the ndk_3_40_01_01\packages\ti\ndk\stack\nimu\nimu.c with the NIMUSendPacket() function.

    I have at the beginning of the example a debug hook with a while loop that never ends until I manually set a variable. Without that I wouldn't have found the issue that the DSP uses the same UART as the Linux. I did debug it until EMAC_sendPacket() in EMAC_send_v4() and couldn't detect any corruption of the data I sent. Thus my assumption that the Problem is more about the pointer, because in the EMAC_PKT_DESC_T that is passed in EMAC_sendPacket() it just points to the data to send. Also the data sent is complete garbage and looks a lot like uninitialized data / some random memory location and not just like the data was corrupted.
  • Hi,

    The Tx call path is: NIMUSendPacket (this is from NDK)====>NIMU_send (this is from NIMU driver) =====>EMAC_sendPacket(this is from EMAC driver). So if you already trace to the end of the call EMAC_sendPacket(), you can look at the EMAC_PKT_DESC_T where the Tx buffer is, there should be structure with:

    pkt_desc.pDataBuffer = (Uint8 *)Convert_CoreLocal2GlobalAddr((uint32_t)(PBM_getDataBuffer(hPkt)));
    pkt_desc.BufferLen = PBM_getBufferLen(hPkt);

    You can look at the pDataBuffer from CCS memory window and if data corrupted or not.

    Regards, Eric
  • Hi,

    Ah yeah, did oversee that. I just couldn't find the code you posted. In my implementation it is in the function CpswHwPktTxNext() and the two lines are like these:

    csl_send_pkt.pDataBuffer = PBM_getDataBuffer(hPkt);
    csl_send_pkt.BufferLen = PBM_getBufferLen(hPkt);

    I also checked if there is a Convert_CoreLocal2GlobalAddr() function, there isn't one.

    Regards, Andri
  • Ok, I created now an example based on the EMAC_BasicExample_evmAM572x_c66xExampleProject. I did two adaption steps.

    First was to update the project so it would send some data over Ethernet. That worked fine. See source code below

    56422.EMAC_BasicExample_evmAM572x_first_step.tar.gz

    Second step was introducing IPC (It needs a small change in <pdk_install_dir>/packages/ti/board/src/evmAM572x/device/enet_phy.c -----> uncomment "#define IO_CONSOLE"). As for the rest of the source code see below

    0334.EMAC_BasicExample_evmAM572x_second_step.tar.gz

    From the debugger I got this right before sending:

    As for the captured wireshark frames:

    EMAC_Received.zip

    I also tried to put the data buffer into memory that has a 1:1 mapping virtual / physical (uncomment line 248/249 in evm_AM572x.cfg and uncomment line 73 in test_utils.c). Result was that nothing got sent anymore

  • Hi,

    I saw the pDataBuffer address and contents. This includes the MAC header correct? In the wireshark, there are several packets and I didn't see any of them matched this buffer. In the working case without using IPC, you have the packet capture match this buffer. 

    In the emac_send(), it calls into emac_send====>emac_send_v4=====>EMAC_sendpacket. Are you able to trace further what data buffer is passed down? I also asked our IPC expert in the thread for help!.

    Regards, Eric

  • Hello Andri,

    Are you using the default resource table? And have you made any changes to the CMA/CMEM regions defined in the Linux device tree?

    Have you already referred to this IPC document that talks about integrating IPC + PDK drivers?

    Regards,
    Sahin

  • Iding said:

    This includes the MAC header correct?

    yes

    Iding said:

    In the wireshark, there are several packets and I didn't see any of them matched this buffer. In the working case without using IPC, you have the packet capture match this buffer.

    yes, see also:

    EMAC_Received_first_example.zip

    Iding said:

    In the emac_send(), it calls into emac_send====>emac_send_v4=====>EMAC_sendpacket. Are you able to trace further what data buffer is passed down?

    I tried, but there are random jumps in the debugging session and it's kind of hard to keep track what happens. Probably because the libraries weren't compiled with debugging options.

    Iding said:

    I also asked our IPC expert in the thread for help!

    Thanks a lot!

    Sahin Okur said:

    Are you using the default resource table? And have you made any changes to the CMA/CMEM regions defined in the Linux device tree?

    I'm using the "rsc_table_vayu_dsp.c" / "config.bld" from the tutorial on how to add IPC to an existing application. I needed to increase the EXT_CODE, EXT_DATA and EXT_HEAP a bit as the executable didn't fit, but as I understood this is allocated from the Default CMA pool that should be big enough. I didn't do any changes to the CMA/CMEM memory regions and have them as they were in the ti linux image that came with the sdk. The only change I did in the device tree was disabling the mac so it wouldn't give a resource conflict with the DSP.

    Sahin Okur said:

    10. How to Guides — Processor SDK RTOS Documentation

    software-dl.ti.com
    This document describes the procedure to bring the C66x core out of reset after booting Linux, or at the u-boot prompt.These steps are necessary in to order to load an application on the C66x core, without interfering with the operation of Linux running on the A15.

    Yes, I followed that guide especially the part "Adding IPC to an existing TI RTOS application on the DSP". I had to make slight changes as stated above, but for the rest I followed it. I load / run the generated .elf file with a symbolic link named "dra7-dsp1-fw.xe66" in "/lib/firmware/" that points to my generated .elf file. I do the debugging by connecting to the core once everything is running (all other cores than the DSPs are bypassed and I run the "AM5728_RevA" Target configuration without GEL files). Then I terminate my startup endless loop and debug my code.

  • Hello Andri,

    Thank you for the information. I think it is an address translation issue as you suspected. When using "TYPE_CARVEOUT" the physical memory backing the entry is allocated from the CMA pool and the actual physical location is unknown. Since you need a fixed MMU mapping, I recommend using TYPE_DEVMEM so that the virtual and physical addresses are at fixed, known locations. You will need to reserve the physical area using CMEM in the Linux device tree inside the file am57xx-evm-cmem.dtsi.

    The following app note provides some additional guidance on this:
    www.ti.com/.../sprac60.pdf

    You can also take a look at big data example under linux-sdk/example-applications/big-data-ipc-demo to see how DEVMEM is defined in the resource table.

    Regards,
    Sahin