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.

CCS/TMS320C6748: NIMU receive function issue

Part Number: TMS320C6748
Other Parts Discussed in Thread: OMAPL138

Tool/software: Code Composer Studio

Hello,

I am using LCDKC6748 and processor_sdk_rtos_omapl138_6_01_00_08.

I run "NIMU_emacExample_lcdkOMAPL138C674xBiosExampleProject", and sending ICMP echo requests continuously from a remote PC.

There is no problem most of the time. However, very rarely errors occur.

When the error occurred, the received data in the memory has been corrupted.
It is occurring in the function "EmacRxPkt()" in the "pdk_omapl138_1_0_10\packages\ti\transport\ndk\nimu\src\v6\nimu_eth.c".

static void
EmacRxPkt
(
    uint32_t              port_num,
    EMAC_PKT_DESC_T*    p_desc
)
{
    uint32_t              dataOffset, protocol;
    uint8_t*              pBuffer;

    (void)port_num;

    PBM_setValidLen((PBM_Handle) p_desc->AppPrivate, p_desc->ValidLen);
    PBM_setIFRx((PBM_Handle) p_desc->AppPrivate, pPDI[NIMU_PORT_NUM_USED]->hEther );

    /* Handle raw frames separately, i.e. check the
    * Ethernet Protocol type in this packet and see
    * if its a well known ether type. If so, this is normal
    * IP stream, enqueue this is in usual Rx queue and let the
    * stack know that a packet has arrived for it. However, if
    * the ethernet type in the packet is not a well known one,
    * this could be a custom raw ethernet packet, enqueue it
    * separately in the Raw Rx queue and notiofy stack. The Raw
    * Ethernet packets when being handed over are given
    * preferential treatment and are serviced before the normal
    * IP traffic. Hence the 2 queues.
    */
    dataOffset = PBM_getDataOffset((PBM_Handle) p_desc->AppPrivate);
    pBuffer = (Uint8 *)Convert_CoreLocal2GlobalAddr((uint32_t)(PBM_getDataBuffer((PBM_Handle) p_desc->AppPrivate))) + dataOffset;

    /* Extract the ethernet type from the packet. */
    protocol = ( pBuffer[12] << 8) | pBuffer[13] ;
    protocol = (protocol & 0xFFFFu);

    /* Is it a standard ethernet type? */
    if (protocol != ETHERTYPE_IP && protocol != ETHERTYPE_IPv6 && protocol != ETHERTYPE_VLAN
        && protocol != ETHERTYPE_PPPOECTL && protocol != ETHERTYPE_PPPOEDATA )
    {
        /* This is a raw packet, enqueue in Raw Rx Queue */
        PBMQ_enq( &pPDI[NIMU_PORT_NUM_USED]->PBMQ_rawrx, (PBM_Handle) p_desc->AppPrivate );
    }
    else
    {            /* This is a normal IP packet. Enqueue in Rx Queue */
        PBMQ_enq( &pPDI[NIMU_PORT_NUM_USED]->PBMQ_rx, (PBM_Handle) p_desc->AppPrivate );
    }

    /* Notify NDK stack of pending Rx Ethernet packet */
    STKEVENT_signal( pPDI[NIMU_PORT_NUM_USED]->hEvent, STKEVENT_ETHERNET, 1 );

    /* Clean the cache for external addesses */
    if( ((uint32_t)(PBM_getDataBuffer(p_desc->AppPrivate)) & EMAC_EXTMEM) || (((uint32_t)(PBM_getDataBuffer(p_desc->AppPrivate)) & EMAC_MSMCMEM) == EMAC_MSMCMEM) )
    {
        CacheP_wbInv( (void *)(PBM_getDataBuffer(p_desc->AppPrivate)), PBM_getBufferLen(p_desc->AppPrivate) );
    }
}

"CacheP_wbInv()" overwrites the received data in the external memory with data in the cache.
If the latest received data is not in the cache, the latest received data in the external memory is corrupted.

Is there any problem if I use "CacheP_Inv()" instead of "CacheP_wbInv()" ?

Thank you,

  • Hello,

    This issue was also brought up in another thread: https://e2e.ti.com/support/processors/f/791/t/355647

    One option is to only invalidate the cache and not write back as you suggested. The other option is to disable cache for the memory section ".far:NDK_PACKETMEM."

    Regards,
    Sahin

  • Hi,

    >This issue was also brought up in another thread: https://e2e.ti.com/support/processors/f/791/t/355647

    Thank you for the information. I also used C6657, but NDK_PACKETMEM was allocated to the L2SRAM, the problem did not occur.

    In C6748,  I have modified "EmacRxPkt" as follows

    static void
    EmacRxPkt
    (
        uint32_t              port_num,
        EMAC_PKT_DESC_T*    p_desc
    )
    {
        uint32_t              dataOffset, protocol;
        uint8_t*              pBuffer;
    
        (void)port_num;
    
        PBM_setValidLen((PBM_Handle) p_desc->AppPrivate, p_desc->ValidLen);
        PBM_setIFRx((PBM_Handle) p_desc->AppPrivate, pPDI[NIMU_PORT_NUM_USED]->hEther );
    
        /* Handle raw frames separately, i.e. check the
        * Ethernet Protocol type in this packet and see
        * if its a well known ether type. If so, this is normal
        * IP stream, enqueue this is in usual Rx queue and let the
        * stack know that a packet has arrived for it. However, if
        * the ethernet type in the packet is not a well known one,
        * this could be a custom raw ethernet packet, enqueue it
        * separately in the Raw Rx queue and notiofy stack. The Raw
        * Ethernet packets when being handed over are given
        * preferential treatment and are serviced before the normal
        * IP traffic. Hence the 2 queues.
        */
        dataOffset = PBM_getDataOffset((PBM_Handle) p_desc->AppPrivate);
        pBuffer = (Uint8 *)Convert_CoreLocal2GlobalAddr((uint32_t)(PBM_getDataBuffer((PBM_Handle) p_desc->AppPrivate))) + dataOffset;
    
    	//// ->
        if( ((uint32_t)(PBM_getDataBuffer(p_desc->AppPrivate)) & EMAC_EXTMEM) || (((uint32_t)(PBM_getDataBuffer(p_desc->AppPrivate)) & EMAC_MSMCMEM) == EMAC_MSMCMEM) )
        {
    		CacheP_Inv( (void *)(PBM_getDataBuffer(p_desc->AppPrivate)), PBM_getBufferLen(p_desc->AppPrivate) );
        }
    	//// <-
    	
        /* Extract the ethernet type from the packet. */
        protocol = ( pBuffer[12] << 8) | pBuffer[13] ;
        protocol = (protocol & 0xFFFFu);
    
        /* Is it a standard ethernet type? */
        if (protocol != ETHERTYPE_IP && protocol != ETHERTYPE_IPv6 && protocol != ETHERTYPE_VLAN
            && protocol != ETHERTYPE_PPPOECTL && protocol != ETHERTYPE_PPPOEDATA )
        {
            /* This is a raw packet, enqueue in Raw Rx Queue */
            PBMQ_enq( &pPDI[NIMU_PORT_NUM_USED]->PBMQ_rawrx, (PBM_Handle) p_desc->AppPrivate );
        }
        else
        {            /* This is a normal IP packet. Enqueue in Rx Queue */
            PBMQ_enq( &pPDI[NIMU_PORT_NUM_USED]->PBMQ_rx, (PBM_Handle) p_desc->AppPrivate );
        }
    
        /* Notify NDK stack of pending Rx Ethernet packet */
        STKEVENT_signal( pPDI[NIMU_PORT_NUM_USED]->hEvent, STKEVENT_ETHERNET, 1 );
    
        /* Clean the cache for external addesses */
    //    if( ((uint32_t)(PBM_getDataBuffer(p_desc->AppPrivate)) & EMAC_EXTMEM) || (((uint32_t)(PBM_getDataBuffer(p_desc->AppPrivate)) & EMAC_MSMCMEM) == EMAC_MSMCMEM) )
    //    {
    //        CacheP_wbInv( (void *)(PBM_getDataBuffer(p_desc->AppPrivate)), PBM_getBufferLen(p_desc->AppPrivate) );
    //    }
    }

    The Ethernet type is read directly from the buffer, so I put "CacheP_Inv" just before that.
    This code works for me.
    Regards,
    Kikuya