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.

Linux/TMDSICE3359: ICSS-EMAC issue

Part Number: TMDSICE3359

Tool/software: Linux

Hi,

I was trying to run ICSS-EMAC after doing some modification. The modification I did was instead of having a loop-back mechanism, I wanted to capture the packets on wireshark.So every time a packet was received a packet was  made to send from the application. To make the performance better , I removed all the print commands in the application.But then my application was not responding as expected instead the following error occurred :-

[   36.050564] sched: RT throttling activated                                  

[   37.071561] NOHZ: local_softirq_pending 102                                

[   37.080611] NOHZ: local_softirq_pending 102                                

[   37.090563] NOHZ: local_softirq_pending 102                                

[   38.050568] NOHZ: local_softirq_pending 102                                

[   38.051798] NOHZ: local_softirq_pending 102                                

[   38.051915] NOHZ: local_softirq_pending 102                                

[   38.054264] NOHZ: local_softirq_pending 102                                

[   38.060568] NOHZ: local_softirq_pending 102                                

[   38.070561] NOHZ: local_softirq_pending 102                                

[   38.080559] NOHZ: local_softirq_pending 102                                

But when I gave a sleep(1) before sending the response packet , I was getting my expected behavior. I am using ICEv2AM335x and Linux RT. My PC is Ubuntu 16.04LTS.
My concern is , What does this message log signify ? What is the reason for this event to occur ? How can it be rectified ?


Looking forward to your support.

Regards

Paramesh

  • The software team have been notified. They will respond here.
  • Hi,

    Looking forward for your response at the earliest.

    Thanks

    Paramesh

  • Hi Paramesh,

    Which TI SDK version are you using?
    The two messages that you are highlighting are indicating that the kernel is detecting a PID or PIDs are taking too much time in the system.

    Could you summarize the application that you are working with and what the expected behaviour is?

    If I understand correctly what you mentioned in the post is that the messages go away after you put a sleep in the application, is this correct? If so a sleep allows the application to yield and the other tasks to run.

    Best Regards,
    Schuyler
  • Hi,

    My SDK version is ti-processor-sdk-linux-rt-am335x-evm-04.00.00.04.

    The ICSS-EMAC was having a loop-back mechanism,in which the packets are send from and received to the same port. If I understand correctly,there was a variable  ICSS_EMAC_testPacketRcvdPort0 which was used as a flag to indicate that a packet was received and hence a packet would be send from the same port and this process would continue for 10 packets.

    On the other hand , my requirement was to capture the packets send and received on Wireshark(network analyzer tool). So I modified the flow such that the loop-back mechanism was not there , rather it would send a packet in response to a packet received and I was able to capture it on Wireshark.After my code modification I was successful in capturing the packets on Wireshark, which I assume shows that my application is working fine in the way I wanted it to work.

    My concern is that when I removed print commands from the application I was not able to get any response and I found the log (mentioned in the above post). So, I tried adding a delay, SLEEP(1) , I was able to get the packets on Wireshark and my application was working fine.

    My concern is what does that log signify ? How can I solve this issue ?

    Looking forward for your support at the earliest.

    OS - Ubuntu 16.04 LTS

    Regards

    Paramesh

  • Hi,

    The variable you mention I am not familiar with and I think maybe internal to the PRU firmware. Are you writing code that runs on the PRU or the ARM? Are you planning to use the ICSS-EMAC through the Linux network interface from the ARM?

    Best Regards,
    Schuyler
  • Hi,

    I am writing the code that runs on the ARM. I am attaching the icss-emac code so that variable I mentioned in the previous post is clear.

    Regards

    Parameshicss-emac.tar.gz

  • Hi,

    Another observation that I saw was there is a delay in the packet received in wireshark.

    I have made the code such that everytime a ARP packet is received it sends a packet in response with source 01:bb:cc:dd:ee:ff .

    I observed that there is almost a delay in the range of a  few milliseconds.(0.9 ms) in the wireshark capture. What is the reason for this delay ?

    I took timestamp in ICSS_EMAC_testCallbackRxPacket() and ICSS_EmacTxPacketEnqueue ( ) to find the time taken to process the packet in application. I am attaching my findings with this post.

    Is the delay due to processing time taken for UIO mapping ?

    Regards

    Parameshicssemac.tar.gz

  • In the findings I got there is almost 0.2 ms time difference between the time spent in application and the time wireshark. According to my understanding , there should not be this 0.2ms time difference. Is my understanding correct ?

    Regards

    Paramesh

  • Hello Paramesh,

    Your delay findings are close to the Programmed Cycle Period shown in the "Sample Log from AM572x IDK" of the ICSS-EMAC wiki, so the delay between ICSS_EMAC_testCallbackRxPacket() and ICSS_EmacTxPacketEnqueue ( ) looks like it is in the expected ballpark. I cannot comment on the wireshark delay, but I would not expect wireshark to have completely perfect timing since it's a separate program running on a separate machine from the device under test.

    I am still looking into the issue where the program stops responding when there are no prints or delays inserted into your code.

    Regards, 

    Nick

  • Hello Paramesh,

    1) Could you tell me which files you modified to run your tests?
    2) How are you timestamping ICSS_EMAC_testCallbackRxPacket() and ICSS_EmacTxPacketEnqueue ( )? (Linux timer, prussIepRegs, etc)

    Regards,
    Nick
  • Hi,

    1) I had modified the main_a8.c and test_common_utils.c files.

    2) I have used the get clock_gettime(CLOCK_REALTIME, &variable) api to get the time stamp at recieve and send and then subtracting to get the time spent for processing the data. 

    Looking forward for your support and guidance.

    6675.main_a8.c
    /*
     * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/
     * 
     * 
     *  Redistribution and use in source and binary forms, with or without 
     *  modification, are permitted provided that the following conditions 
     *  are met:
     *
     *    Redistributions of source code must retain the above copyright 
     *    notice, this list of conditions and the following disclaimer.
     *
     *    Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the 
     *    documentation and/or other materials provided with the   
     *    distribution.
     *
     *    Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
     *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
     *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
     *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
     *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
     *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
     *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
     *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
    */
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <assert.h>
    
    pthread_t time_th;
    void gettimestamp();
    
    #ifdef __LINUX_USER_SPACE
    #include <sys/mman.h>
    #include <unistd.h>
    #include "mmap_helper.h"
    #else
    #include <xdc/std.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/knl/Cache.h>
    #include <xdc/runtime/Types.h>
    
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/hal/Core.h>
    #endif
    
    #include <ti/csl/soc.h>
    
    #include <ti/drv/pruss/pruicss.h>
    #include <ti/drv/pruss/soc/pruicss_v1.h>
    
    #include <ti/drv/icss_emac/icss_emacDrv.h>
    #include <ti/drv/icss_emac/test/src/test_common_utils.h>
    
    #include <ti/drv/icss_emac/test/src/tiemac_pruss_intc_mapping.h>
    
    #ifdef __LINUX_USER_SPACE
    #include <ti/drv/icss_emac/firmware/am335x/icss_emac_pru0_bin.h>
    #include <ti/drv/icss_emac/firmware/am335x/icss_emac_pru1_bin.h>
    #define PRU0_FIRMWARE_NAME      PRU0_FIRMWARE        // name of the C struct in PRU header file
    #define PRU1_FIRMWARE_NAME      PRU1_FIRMWARE        // name of the C struct in PRU header file
    #else
    #include <ti/drv/icss_emac/test/src/fw_mem_section.h>
    #endif
    
    #ifdef __LINUX_USER_SPACE
    /* ICSS EMAC  PHY address definitions */
    #define BOARD_ICSS_EMAC_PORT0_PHY_ADDR       (1U)
    #define BOARD_ICSS_EMAC_PORT1_PHY_ADDR       (3U)
    #else
    #include <ti/drv/uart/UART.h>
    #include <ti/drv/uart/UART_stdio.h>
    #include <ti/board/board.h>
    #endif
    
    #include <ti/starterware/include/hw/soc_am335x.h>
    
    extern uint8_t ICSS_EMAC_testPkt[];
    
    
    extern uint8_t    ICSS_EMAC_testTtsModePort1;
    extern uint8_t    ICSS_EMAC_testTtsModePort2;
    
    
    extern ICSS_EmacHandle ICSS_EMAC_testHandle;
    extern ICSS_EmacHandle ICSS_EMAC_testHandle1;
    
    extern uint32_t ICSS_EMAC_testPacketRcvdPort0;
    extern uint32_t ICSS_EMAC_testPacketRcvdPort1;
    
    extern uint8_t ICSS_EMAC_testLclMac[];
    extern uint8_t ICSS_EMAC_testLclMac1[];
    
    
    uint8_t ICSS_EMAC_testEvmType = ICSS_EMAC_TEST_BOARD_ICEV2AM335x;
    
    PRUICSS_Handle ICSS_EMAC_testPruIcssHandle = NULL;
    
    #ifdef __LINUX_USER_SPACE
    static inline void linux_sleep_ms(unsigned long ms) {
        struct timespec ts;
        ts.tv_sec = (ms)/1000;
        ms = ms - ts.tv_sec*1000;
        ts.tv_nsec = (ms*1000000);
        nanosleep(&ts, NULL);
    }
    #define SLEEP(t) linux_sleep_ms(t)
    #define PRINT printf
    #else
    #define SLEEP Task_sleep
    #define PRINT UART_printf
    #endif
    
    
    #ifdef __LINUX_USER_SPACE
    extern tprussdrv *pruss_drv_handle;
    extern PRUICSS_HwAttrs linux_prussHwAttrs[PRUICCSS_INSTANCE_MAX-1];
    extern PRUICSS_V1_Object linux_prussObjects[PRUICCSS_INSTANCE_MAX-1];
    extern PRUICSS_Config linux_pruss_config[PRUICCSS_INSTANCE_MAX];
    
    pthread_t port0_rxTask_th, port0_txTask_th, port0_ttsCycTask_th, port0_linkTask_th,
              port1_rxTask_th, port1_txTask_th, port1_ttsCycTask_th, port1_linkTask_th;
    
    int eth0_rxIntNum = 0,
        eth0_txIntNum = 2,
        eth0_linkIntNum = 6,
        eth1_rxIntNum = 1,
        eth1_txIntNum = 3,
        eth1_linkIntNum = 7;
    #endif
    
    /***********************************************************************/
    /* function definitions                                                */
    /***********************************************************************/
    
    /*
     *    ---task to initialize PRU---
     */
    #ifdef __LINUX_USER_SPACE
    void ICSS_EMAC_testTaskPruss(void *a0)
    #else
    Void ICSS_EMAC_testTaskPruss(UArg a0, UArg a1)
    #endif
    {
        Uint8 firmwareLoad_done = FALSE;
        Uint8 count = 0;
    
    
        int8_t ret = 0;
        ICSS_EmacTxArgument txArgs;
    
        PRUICSS_pruDisable(ICSS_EMAC_testPruIcssHandle, ICSS_EMAC_PORT_1-1);
        PRUICSS_pruDisable(ICSS_EMAC_testPruIcssHandle, ICSS_EMAC_PORT_2-1);
        if(PRUICSS_pruWriteMemory(ICSS_EMAC_testPruIcssHandle,PRU_ICSS_IRAM(0) ,0,
    #ifdef __LINUX_USER_SPACE
                              (uint32_t *) PRU0_FIRMWARE_NAME,
                              sizeof(PRU0_FIRMWARE_NAME)))
    #else
                              (uint32_t *) &pru_imem0_rev1_start,
                              &pru_imem0_rev1_end - &pru_imem0_rev1_start))
    #endif
        {
            if(PRUICSS_pruWriteMemory(ICSS_EMAC_testPruIcssHandle,PRU_ICSS_IRAM(1) ,0,
    #ifdef __LINUX_USER_SPACE
                                  (uint32_t *) PRU1_FIRMWARE_NAME,
                                  sizeof(PRU1_FIRMWARE_NAME)))
    #else
                                  (uint32_t *) &pru_imem1_rev1_start,
                                  &pru_imem1_rev1_end - &pru_imem1_rev1_start))
    #endif
            {
                firmwareLoad_done = TRUE;
            }
        }
    
        if( firmwareLoad_done)
        {
            PRUICSS_pruEnable(ICSS_EMAC_testPruIcssHandle, ICSS_EMAC_PORT_1-1);
            PRUICSS_pruEnable(ICSS_EMAC_testPruIcssHandle, ICSS_EMAC_PORT_2-1);
        }
    
    
                
        while (!(((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->linkStatus[0] || ((ICSS_EmacObject*)ICSS_EMAC_testHandle1->object)->linkStatus[0]))
        {
            SLEEP(100);
            PRINT("link is down: link0 status: 0x%x, link1 status: 0x%x\n",
                    ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->linkStatus[0],
                    ((ICSS_EmacObject*)ICSS_EMAC_testHandle1->object)->linkStatus[0]);
        }
     //  ICSS_EMAC_testPacketRcvdPort0 = 1;		//Commenetd by Paramesh
    
         ICSS_EMAC_testPacketRcvdPort0 =0;			//Added by Paramesh
        ICSS_EMAC_testPacketRcvdPort1 = 1;
    
    
        txArgs.icssEmacHandle = ICSS_EMAC_testHandle;
        txArgs.lengthOfPacket = ICSS_EMAC_TEST_PKT_SIZE;
        txArgs.portNumber = 1;
        txArgs.queuePriority = 3;
        txArgs.srcAddress = &ICSS_EMAC_testPkt[0];
    
    
        for (count=0;count < ICSS_EMAC_TEST_PKT_TX_COUNT;count++)
        {
            if(((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->linkStatus[0] )
            {
                txArgs.icssEmacHandle = ICSS_EMAC_testHandle;
                txArgs.lengthOfPacket = ICSS_EMAC_TEST_PKT_SIZE;
                txArgs.portNumber = 1;
                txArgs.queuePriority = 3;
                txArgs.srcAddress = &ICSS_EMAC_testPkt[0];
    /************************************************************* MODIFED CODE **********************************************************/
    	  while(1)
    	    {
    		//printf("\n waiting \n");
    		SLEEP(1);
    	        //printf("\n sleep called \n");
    		if(ICSS_EMAC_testPacketRcvdPort0)
    		{
    		  		
    		  ICSS_EMAC_testPacketRcvdPort0=0;
    		  //printf("\n ICSS_EmacTxPacket in main 1\n");
                      ICSS_EmacTxPacket(&txArgs, NULL);
    		  
    		}
    	    }
    #if 0
                if(ICSS_EMAC_testPacketRcvdPort0 ) {
                    ICSS_EMAC_testPacketRcvdPort0 = 0;
    		printf("\n ICSS_EmacTxPacket in main 1\n");
                    ICSS_EmacTxPacket(&txArgs, NULL);
                    while(!ICSS_EMAC_testPacketRcvdPort0) {
                        SLEEP(100);
                    }
                }
    #endif
            }
    
    /************************************************************* MODIFED CODE ************************************************************/
            if(((ICSS_EmacObject*)ICSS_EMAC_testHandle1->object)->linkStatus[0])
                {
                    txArgs.icssEmacHandle = ICSS_EMAC_testHandle1;
                    txArgs.lengthOfPacket = ICSS_EMAC_TEST_PKT_SIZE;
                    txArgs.portNumber = 2;
                    txArgs.queuePriority = 3;
                    txArgs.srcAddress = &ICSS_EMAC_testPkt[0];
                
                    if(ICSS_EMAC_testPacketRcvdPort1 )
                    {
                        ICSS_EMAC_testPacketRcvdPort1 = 0;
    		    printf("\n ICSS_EmacTxPacket in main 2\n");
                        ICSS_EmacTxPacket(&txArgs, NULL);
                    }
                    while(!ICSS_EMAC_testPacketRcvdPort1) 
                    {
                        SLEEP(100);
                    }
            }
        }
    
        while(!(((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->linkStatus[0] || ((ICSS_EmacObject*)ICSS_EMAC_testHandle1->object)->linkStatus[0]))
        {
            PRINT("link is down, pluggin loopback cable for both ports: link0 status: 0x%x, link1 status: 0x%x\n",
                            ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->linkStatus[0],
                            ((ICSS_EmacObject*)ICSS_EMAC_testHandle1->object)->linkStatus[0]);
        }
    
        PRINT("\n============================================================");
        PRINT("\nInitiating TTS tests on PORT1 and PORT2");
    
        /*	Create TTS related semaphores	*/
        ret = ICSS_EMAC_testTtsSemCreate();
        assert(ret == 0);
    
        ICSS_EMAC_testTtsModePort1 = 1;
        ICSS_EMAC_testTtsModePort2 = 1;
    
        /*	Wait for TTS test to complete	*/
        while(ICSS_EMAC_testTtsModePort1 || ICSS_EMAC_testTtsModePort2)
        {
            SLEEP(10);
        }
    
         ICSS_EMAC_testGetPruStats(1, ICSS_EMAC_testHandle);
         ICSS_EMAC_testGetPruStats(1, ICSS_EMAC_testHandle1);
    
        ICSS_EMAC_testInterruptDisable(ICSS_EMAC_testHandle);
        ICSS_EMAC_testInterruptDisable(ICSS_EMAC_testHandle1);
    
        ICSS_EmacDeInit(ICSS_EMAC_testHandle, ICSS_EMAC_MODE_MAC1|ICSS_EMAC_MODE_DUALMAC);
        ICSS_EmacDeInit(ICSS_EMAC_testHandle1, ICSS_EMAC_MODE_MAC2|ICSS_EMAC_MODE_DUALMAC);
        PRINT("\n============================================================");
        PRINT("\nTTS tests finished on PORT1 and PORT2");
        PRINT("\n============================================================");
        PRINT("\nAll tests have passed\n");
    }
    
    int32_t ICSS_EMAC_testPruIcssInstanceSetup(void)
    {
        PRUICSS_Config  *cfg;
        ICSS_EmacInitConfig* icss_emacTestInitCfg0;
        ICSS_EmacInitConfig* icss_emacTestInitCfg1;
    
    #ifdef __LINUX_USER_SPACE
        int status;
        int priority = 20;
        pthread_attr_t pthread_attr;
        struct sched_param sched_param;
    
        linux_init((void**)&pruss_drv_handle, linux_prussHwAttrs, PRUICCSS_INSTANCE_ONE);
        cfg = linux_pruss_config;
    #else
        Task_Params taskParams;
        int32_t ret  = PRUICSS_socGetInitCfg(&cfg);
        if (ret  != PRUICSS_RETURN_SUCCESS)
            return (ret);
    #endif
        ICSS_EMAC_testPruIcssHandle = PRUICSS_create((PRUICSS_Config*) cfg, PRUICCSS_INSTANCE_ONE);
    
        /*Port I initializations*/
        ICSS_EMAC_testHandle = (ICSS_EmacHandle)malloc(sizeof(ICSS_EmacConfig));
    
        icss_emacTestInitCfg0 = (ICSS_EmacInitConfig*)malloc(sizeof(ICSS_EmacInitConfig));
    
        if ((ICSS_EMAC_testHandle == NULL) || (icss_emacTestInitCfg0 == NULL))
        {
            PRINT("main: malloc returned null\n");
            return -1;
        }
        icss_emacTestInitCfg0->phyAddr[0]=BOARD_ICSS_EMAC_PORT0_PHY_ADDR;
        icss_emacTestInitCfg0->portMask = ICSS_EMAC_MODE_MAC1;
        icss_emacTestInitCfg0->ethPrioQueue = ICSS_EMAC_QUEUE1;
    
    
        icss_emacTestInitCfg0->halfDuplexEnable = 1;
        icss_emacTestInitCfg0->enableIntrPacing = ICSS_EMAC_ENABLE_PACING;
        icss_emacTestInitCfg0->ICSS_EmacIntrPacingMode = ICSS_EMAC_INTR_PACING_MODE1;
        icss_emacTestInitCfg0->pacingThreshold = 100;
        icss_emacTestInitCfg0->learningEn = 0;
    
    #ifndef __LINUX_USER_SPACE
        ICSS_EMAC_testSocCtrlGetPortMacAddr(1,ICSS_EMAC_testLclMac);
    #endif
        icss_emacTestInitCfg0->macId = ICSS_EMAC_testLclMac;
    
        ICSS_EMAC_testDrvInit(ICSS_EMAC_testHandle, 1);
    
    #ifdef __LINUX_USER_SPACE
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->linkInt_fd = prussdrv_open(pruss_drv_handle, eth0_linkIntNum);
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->rxInt_fd = prussdrv_open(pruss_drv_handle, eth0_rxIntNum);
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->txInt_fd = prussdrv_open(pruss_drv_handle, eth0_txIntNum);
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->ttsCycInt_fd = prussdrv_open(pruss_drv_handle, eth0_txIntNum);
    #endif
    
        /*  Enable interrupt mode for TTS Cyclic Packet     */
        icss_emacTestInitCfg0->ICSS_EmacTTSEnableCycPktInterrupt = ICSS_EMAC_TTS_CYC_INTERRUPT_ENABLE;
    
    #ifdef __LINUX_USER_SPACE
        icss_emacTestInitCfg0->rxIntNum   = eth0_rxIntNum;
        icss_emacTestInitCfg0->linkIntNum = eth0_linkIntNum;
        icss_emacTestInitCfg0->txIntNum   = eth0_txIntNum;
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->pruss_drv_handle = pruss_drv_handle;
    #else
        icss_emacTestInitCfg0->rxIntNum = 20;
        icss_emacTestInitCfg0->linkIntNum = 26;
        icss_emacTestInitCfg0->txIntNum = 22;
    #endif
    
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->pruIcssHandle = ICSS_EMAC_testPruIcssHandle;
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->emacInitcfg = icss_emacTestInitCfg0;
    
        /*PORT2 Initializations*/
        ICSS_EMAC_testHandle1 = (ICSS_EmacHandle)malloc(sizeof(ICSS_EmacConfig));
    
        icss_emacTestInitCfg1 = (ICSS_EmacInitConfig*)malloc(sizeof(ICSS_EmacInitConfig));
        icss_emacTestInitCfg1->phyAddr[0]= BOARD_ICSS_EMAC_PORT1_PHY_ADDR;
        icss_emacTestInitCfg1->portMask = ICSS_EMAC_MODE_MAC2;
        icss_emacTestInitCfg1->ethPrioQueue = ICSS_EMAC_QUEUE3;
        icss_emacTestInitCfg1->halfDuplexEnable = 1;
        icss_emacTestInitCfg1->enableIntrPacing = ICSS_EMAC_DISABLE_PACING;
        icss_emacTestInitCfg1->pacingThreshold = 100;
        icss_emacTestInitCfg1->learningEn = 0;
    #ifndef __LINUX_USER_SPACE
        ICSS_EMAC_testSocCtrlGetPortMacAddr(2,ICSS_EMAC_testLclMac1);
    #endif
        icss_emacTestInitCfg1->macId = ICSS_EMAC_testLclMac1;
    
        ICSS_EMAC_testDrvInit(ICSS_EMAC_testHandle1,1);     // ICSS_M instance 0
    
    #ifdef __LINUX_USER_SPACE
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle1->object)->linkInt_fd = prussdrv_open(pruss_drv_handle, eth1_linkIntNum);
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle1->object)->rxInt_fd = prussdrv_open(pruss_drv_handle, eth1_rxIntNum);
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle1->object)->txInt_fd = prussdrv_open(pruss_drv_handle, eth1_txIntNum);
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle1->object)->ttsCycInt_fd = prussdrv_open(pruss_drv_handle, eth1_txIntNum);
    #endif
    
        /*  Enable interrupt mode for TTS Cyclic Packet     */
        icss_emacTestInitCfg1->ICSS_EmacTTSEnableCycPktInterrupt = ICSS_EMAC_TTS_CYC_INTERRUPT_ENABLE;
    
    #ifdef __LINUX_USER_SPACE
        icss_emacTestInitCfg1->rxIntNum   = eth1_rxIntNum;
        icss_emacTestInitCfg1->linkIntNum = eth1_linkIntNum;
        icss_emacTestInitCfg1->txIntNum   = eth1_txIntNum;
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle1->object)->pruss_drv_handle = pruss_drv_handle;
    #else
        icss_emacTestInitCfg1->rxIntNum = 21;
        icss_emacTestInitCfg1->linkIntNum = 27;
        icss_emacTestInitCfg1->txIntNum = 23;
    #endif
    
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle1->object)->pruIcssHandle = ICSS_EMAC_testPruIcssHandle;
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle1->object)->emacInitcfg = icss_emacTestInitCfg1;
    
        PRUICSS_IntcInitData pruss_intc_initdata = PRUSS_INTC_INITDATA;
        ICSS_EmacInit(ICSS_EMAC_testHandle,&pruss_intc_initdata,ICSS_EMAC_MODE_MAC1|ICSS_EMAC_MODE_DUALMAC);
        ICSS_EmacInit(ICSS_EMAC_testHandle1,&pruss_intc_initdata,ICSS_EMAC_MODE_MAC2|ICSS_EMAC_MODE_DUALMAC);
        /* Test ICSS_EmacDeInit */
        ICSS_EmacDeInit(ICSS_EMAC_testHandle, ICSS_EMAC_MODE_MAC1|ICSS_EMAC_MODE_DUALMAC);
        ICSS_EmacDeInit(ICSS_EMAC_testHandle1, ICSS_EMAC_MODE_MAC2|ICSS_EMAC_MODE_DUALMAC);
    
        ICSS_EmacInit(ICSS_EMAC_testHandle,&pruss_intc_initdata,ICSS_EMAC_MODE_MAC1|ICSS_EMAC_MODE_DUALMAC);
        ICSS_EmacInit(ICSS_EMAC_testHandle1,&pruss_intc_initdata,ICSS_EMAC_MODE_MAC2|ICSS_EMAC_MODE_DUALMAC);
    
    
        /* Register TTS Callbacks  */
        ICSS_EmacRegisterHwIntTTSCyc(ICSS_EMAC_testHandle, (ICSS_EmacCallBack)ICSS_EMAC_testTtsCycPort1Callback);
        ICSS_EmacRegisterHwIntTTSCyc(ICSS_EMAC_testHandle1, (ICSS_EmacCallBack)ICSS_EMAC_testTtsCycPort2Callback);
    
        /* Register RX Callbacks: Required for TTS Unit Testing    */
        ICSS_EmacRegisterHwIntRx(ICSS_EMAC_testHandle, (ICSS_EmacCallBack)ICSS_EMAC_testCallbackRxPacket);
        ICSS_EmacRegisterHwIntRx(ICSS_EMAC_testHandle1, (ICSS_EmacCallBack)ICSS_EMAC_testCallbackRxPacket1);
    
        /* Register Tx Callbacks */
        ICSS_EmacRegisterHwIntTx(ICSS_EMAC_testHandle, (ICSS_EmacCallBack)ICSS_EMAC_testCallbackTxComplete);
        ICSS_EmacRegisterHwIntTx(ICSS_EMAC_testHandle1, (ICSS_EmacCallBack)ICSS_EMAC_testCallbackTxComplete);
    
    #ifdef __LINUX_USER_SPACE
        pthread_attr_init(&pthread_attr);
        pthread_attr_setinheritsched(&pthread_attr, PTHREAD_EXPLICIT_SCHED);
        pthread_attr_setschedpolicy(&pthread_attr, SCHED_FIFO);
        sched_param.sched_priority = priority;
        pthread_attr_setschedparam(&pthread_attr, &sched_param);
    
        if (status = pthread_create(&port0_linkTask_th,
                    &pthread_attr, ICSS_EMacOsLinkTaskFnc, (void *)ICSS_EMAC_testHandle)) {
            printf("ERROR: \"port0_linkTaskFnc\" task-create failed (%d)\n", status);
            return (-2);
        }
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->rxTaskHandle = &port0_rxTask_th;
        if (status = pthread_create(&port0_rxTask_th,
                    &pthread_attr, ICSS_EMacOsRxTaskFnc, (void *)ICSS_EMAC_testHandle)) {
            printf("ERROR: \"port0_rxTaskFnc\" task-create failed (%d)\n", status);
            return (-2);
        }
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->txTaskHandle = &port0_txTask_th;
        if (status = pthread_create(&port0_txTask_th,
                    &pthread_attr, ICSS_EMacOsTxTaskFnc, (void *)ICSS_EMAC_testHandle)) {
            printf("ERROR: \"port0_txTaskFnc\" task-create failed (%d)\n", status);
            return (-2);
        }
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->ttsCycTaskHandle = &port0_ttsCycTask_th;
        if (status = pthread_create(&port0_ttsCycTask_th,
                    &pthread_attr, ICSS_EMacOsTTSCycTaskFnc, (void *)ICSS_EMAC_testHandle)) {
            printf("ERROR: \"port0_ttsCycTaskFnc\" task-create failed (%d)\n", status);
            return (-2);
        }
    
        if (status = pthread_create(&port1_linkTask_th,
                    &pthread_attr, ICSS_EMacOsLinkTaskFnc, (void *)ICSS_EMAC_testHandle1)) {
            printf("ERROR: \"port1_linkTaskFnc\" task-create failed (%d)\n", status);
            return (-2);
        }
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle1->object)->rxTaskHandle = &port1_rxTask_th;
        if (status = pthread_create(&port1_rxTask_th,
                    &pthread_attr, ICSS_EMacOsRxTaskFnc, (void *)ICSS_EMAC_testHandle1)) {
            printf("ERROR: \"port1_rxTaskFnc\" task-create failed (%d)\n", status);
            return (-2);
        }
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle1->object)->txTaskHandle = &port1_txTask_th;
        if (status = pthread_create(&port1_txTask_th,
                    &pthread_attr, ICSS_EMacOsTxTaskFnc, (void *)ICSS_EMAC_testHandle1)) {
            printf("ERROR: \"port1_txTaskFnc\" task-create failed (%d)\n", status);
            return (-2);
        }
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle1->object)->ttsCycTaskHandle = &port1_ttsCycTask_th;
        if (status = pthread_create(&port1_ttsCycTask_th,
                    &pthread_attr, ICSS_EMacOsTTSCycTaskFnc, (void *)ICSS_EMAC_testHandle1)) {
            printf("ERROR: \"port1_ttsCycTaskFnc\" task-create failed (%d)\n", status);
            return (-2);
        }
        pthread_attr_destroy(&pthread_attr);
    #else
    
        Task_Params_init(&taskParams);
        taskParams.priority = 10;
        taskParams.instance->name = (char*)"port0_rxTaskFnc";
        taskParams.stackSize = 0x1000;
        taskParams.arg0 = (UArg)ICSS_EMAC_testHandle;
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->rxTaskHandle = Task_create((ti_sysbios_knl_Task_FuncPtr)ICSS_EMacOsRxTaskFnc, &taskParams, NULL);
    
        if(((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->rxTaskHandle==NULL)
        {
            PRINT("main: Task_create rturned NULL handle\n");
            return -2;
        }
    
        Task_Params_init(&taskParams);
        taskParams.priority = 15;
        taskParams.instance->name = (char*)"port0_linkTaskFnc";
        taskParams.stackSize = 0x1000;
        taskParams.arg0 = (UArg)ICSS_EMAC_testHandle;
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->linkTaskHandle = Task_create((ti_sysbios_knl_Task_FuncPtr)ICSS_EMacOsLinkTaskFnc, &taskParams, NULL);
    
        if(((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->linkTaskHandle==NULL)
        {
            PRINT("main: Task_create rturned NULL handle\n");
            return -2;
        }
    
        Task_Params_init(&taskParams);
        taskParams.priority = 10;
        taskParams.instance->name = (char*)"port0_ttsCycTaskFnc";
        taskParams.stackSize = 0x1000;
        taskParams.arg0 = (UArg)ICSS_EMAC_testHandle;
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->ttsCycTaskHandle = Task_create((ti_sysbios_knl_Task_FuncPtr)ICSS_EMacOsTTSCycTaskFnc, &taskParams, NULL);
    
        if(((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->ttsCycTaskHandle==NULL)
        {
            return -2;
        }
    
        Task_Params_init(&taskParams);
        taskParams.priority = 10;
        taskParams.instance->name = (char*)"port1_rxTaskFnc";
        taskParams.stackSize = 0x1000;
        taskParams.arg0 = (UArg)ICSS_EMAC_testHandle1;
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle1->object)->rxTaskHandle = Task_create((ti_sysbios_knl_Task_FuncPtr)ICSS_EMacOsRxTaskFnc, &taskParams, NULL);
    
        if(((ICSS_EmacObject*)ICSS_EMAC_testHandle1->object)->rxTaskHandle==NULL)
        {
            return -2;
        }
    
        Task_Params_init(&taskParams);
        taskParams.priority = 15;
        taskParams.instance->name = (char*)"port1_linkTaskFnc";
        taskParams.stackSize = 0x1000;
        taskParams.arg0 = (UArg)ICSS_EMAC_testHandle1;
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle1->object)->linkTaskHandle = Task_create((ti_sysbios_knl_Task_FuncPtr)ICSS_EMacOsLinkTaskFnc, &taskParams, NULL);
    
        if(((ICSS_EmacObject*)ICSS_EMAC_testHandle1->object)->linkTaskHandle==NULL)
        {
            return -2;
        }
    
        Task_Params_init(&taskParams);
        taskParams.priority = 15;
        taskParams.instance->name = (char*)"port1_ttsCycTaskFnc";
        taskParams.stackSize = 0x1000;
        taskParams.arg0 = (UArg)ICSS_EMAC_testHandle1;
        ((ICSS_EmacObject*)ICSS_EMAC_testHandle1->object)->ttsCycTaskHandle = Task_create((ti_sysbios_knl_Task_FuncPtr)ICSS_EMacOsTTSCycTaskFnc, &taskParams, NULL);
    
        if(((ICSS_EmacObject*)ICSS_EMAC_testHandle1->object)->ttsCycTaskHandle==NULL)
        {
            return -2;
        }
    #endif
        ICSS_EMAC_testInterruptInit(ICSS_EMAC_testHandle);
        ICSS_EMAC_testInterruptInit(ICSS_EMAC_testHandle1);
    
        ICSS_EMAC_testInterruptEnable(ICSS_EMAC_testHandle);
        ICSS_EMAC_testInterruptEnable(ICSS_EMAC_testHandle1);
    
        return 0;
    }
    
    /*
     *  ======== main ========
     */
    #ifdef __LINUX_USER_SPACE
    uint32_t num_iteration = 10;
    uint32_t cycle_period_port1 = ICSS_EMAC_TEST_TTS_CYCLE_PERIOD_PORT1;
    uint32_t cycle_period_port2 = ICSS_EMAC_TEST_TTS_CYCLE_PERIOD_PORT2;
    uint32_t config_time =   ICSS_EMAC_TEST_TTS_CONFIG_TIME;
    int main(int argc, char **argv)
    {
        uint32_t numPorts = 2;
        int status;
        int switchTask_priority = 10;
        int ttsTask_priority = 10;
        pthread_t ICSS_EMAC_testTaskPruss_th, ICSS_EMAC_testPort1TxTask_th, ICSS_EMAC_testPort2TxTask_th;
        pthread_attr_t pthread_attr;
        struct sched_param sched_param;
    
        if(argc > 1)
        {
            num_iteration =  atoi(argv[1]);
            cycle_period_port1  = atoi(argv[2]);
            cycle_period_port2  = atoi(argv[3]);
            config_time   = atoi(argv[4]);
        }
    
        ICSS_EMAC_testPruIcssInstanceSetup();
    
        pthread_attr_init(&pthread_attr);
        pthread_attr_setinheritsched(&pthread_attr,PTHREAD_EXPLICIT_SCHED);
        pthread_attr_setschedpolicy(&pthread_attr, SCHED_RR);
        sched_param.sched_priority = switchTask_priority;
        pthread_attr_setschedparam(&pthread_attr, &sched_param);
    
        mlockall(MCL_FUTURE);
    
        if ((status = pthread_create(&ICSS_EMAC_testTaskPruss_th, &pthread_attr, ICSS_EMAC_testTaskPruss, NULL))) {
            printf("ERROR: \"SwitchTask1\" task-create failed (%d)\n", status);
            return (-1);
        }
    
        // Set TTS tasks priority
        pthread_attr_setschedpolicy(&pthread_attr, SCHED_FIFO);
        sched_param.sched_priority = ttsTask_priority;
        pthread_attr_setschedparam(&pthread_attr, &sched_param);
    
        if ((status = pthread_create(&ICSS_EMAC_testPort1TxTask_th, &pthread_attr, ICSS_EMAC_testPort1TxTask, NULL))) {
            printf("ERROR: \"ttsPort1TxTask\" task-create failed (%d)\n", status);
            return (-1);
        }
        if ((status = pthread_create(&ICSS_EMAC_testPort2TxTask_th, &pthread_attr, ICSS_EMAC_testPort2TxTask, NULL))) {
            printf("ERROR: \"ttsPort2TxTask\" task-create failed (%d)\n", status);
            return (-1);
        }
    
    #if 1
     pthread_attr_t pthread_attr7;
        struct sched_param sched_param7;
        pthread_attr_init(&pthread_attr7);
        pthread_attr_setinheritsched(&pthread_attr7,PTHREAD_EXPLICIT_SCHED);
        pthread_attr_setschedpolicy(&pthread_attr7, SCHED_RR);
        sched_param7.sched_priority = 15;
        pthread_attr_setschedparam(&pthread_attr7, &sched_param7);
    
    
        if ((status = pthread_create(&time_th, &pthread_attr7, gettimestamp, NULL))) {
            printf("ERROR: \"SwitchTask1\" task-create failed testTaskPruss(%d)\n", status);
            return (-1);
        }
    #endif
        pthread_join(ICSS_EMAC_testTaskPruss_th, NULL);
        pthread_join(ICSS_EMAC_testPort1TxTask_th, NULL);
        pthread_join(ICSS_EMAC_testPort2TxTask_th, NULL);
         pthread_join(time_th, NULL);
        pthread_attr_destroy(&pthread_attr);
    
        return(0);
    }
    #else
    int main()
    {
        Error_Block eb;
        Task_Params taskParams;
        int32_t ret = -1;
        Error_init(&eb);
    
        Board_initCfg cfg = BOARD_INIT_PLL| BOARD_INIT_MODULE_CLOCK |  BOARD_INIT_DDR | BOARD_INIT_ICSS_PINMUX | BOARD_INIT_UART_STDIO | BOARD_INIT_ICSS_ETH_PHY;
    
        ret = Board_init(cfg);
        if (ret != BOARD_SOK)
        {
            PRINT("main: Board_init returned error code: %d\n", ret);
            return -2;
        }
    
        Task_Params_init(&taskParams);
        taskParams.priority = 15;
        taskParams.instance->name = "SwitchTask";
        Task_create(ICSS_EMAC_testTaskPruss, &taskParams, &eb);
    
        Task_Params_init(&taskParams);
        taskParams.priority = 10;
        taskParams.instance->name = "ttsPort1TxTask";
        Task_create(ICSS_EMAC_testPort1TxTask, &taskParams, &eb);
    
        Task_Params_init(&taskParams);
        taskParams.priority = 10;
        taskParams.instance->name = "ttsPort2TxTask";
        Task_create(ICSS_EMAC_testPort2TxTask, &taskParams, &eb);
    
        ICSS_EMAC_testPruIcssInstanceSetup();
    
        BIOS_start();
        return(0);
    }
    #endif
    
    
    
    
    
    test_common_utils.c

  • Hello Paramesh,
    Thank you for your reply. We are digging into the code.

    Regards,
    Nick
  • Hi,
    I am looking forward for your support. Is there any update on this issue ? You had mentioned that the delay I reported is expected. Is there anything to do to optimize the UIO driver ?


    Regards
    Paramesh
  • Hello Paramesh,

    It looks like the logic for an if statement was modified:
    if (1)//(!(memcmp(&ICSS_EMAC_testPacketArrayInstance1[0], &ICSS_EMAC_testPkt[0],ICSS_EMAC_TEST_PKT_SIZE)))

    Does anything change if you change that back?
    if (!(memcmp(&ICSS_EMAC_testPacketArrayInstance1[0], &ICSS_EMAC_testPkt[0],ICSS_EMAC_TEST_PKT_SIZE)))

    I am still working on the delay question.

    Regards,
    Nick
  • Hi,

    I changed the if condition that you mentioned to the old logic that was already implemented. According to my understanding that was a logic written so that the device responds with the same packet as it received.

    Observations :-

    1) As I already mentioned.If there is no SLEEP(1) , I get the error code

    [   31.050497] sched: RT throttling activated                                   
    [   34.065405] NOHZ: local_softirq_pending 102                                
    [   34.070536] NOHZ: local_softirq_pending 102                                  
    [   34.080494] NOHZ: local_softirq_pending 102                                  
    [   34.090494] NOHZ: local_softirq_pending 102                                  
    [   35.050970] NOHZ: local_softirq_pending 102                                  
    [   35.054519] NOHZ: local_softirq_pending 102                                  
    [   35.054530] NOHZ: local_softirq_pending 102                                  
    [   35.056778] NOHZ: local_softirq_pending 102                                  
    [   35.060516] NOHZ: local_softirq_pending 102                                 
    [   35.070495] NOHZ: local_softirq_pending 102         

    2) When I introduce the delay , SLEEP(1) , it is responding properly. But even then I can see a few milliseconds delay in between the packet received and the response packet send. And according to my understanding , it is not due to the delay I introduced because certain delay values I obtained is less than 1ms (the delay I introduced) , which imply that there is a delay induced from somewhere else.Is it due to the UIO mapping that a delay of around a few milliseconds happening.

    I am attaching the wireshark file with this post.Since the received packet and response packet are identical , to distinguish you can use the packet number. The pattern is every even number packet is the response for the previous odd number packet.

    (for eg:-

    packet no 2 is the response for packet no 1.

    packet no 4 is response of packet no 3.

    If you see the wireshark file

    Time of packet no 3 is 28.239887 secs

    TIme of packet no 4 is 28.240825 secs

    difference = 28.240825-28.2239887 =0.000938 secs = 0.938 milliseconds

    Why is this difference happening ?

    test.tar.gzLooking forward for your support. Also attaching the test_common_utils.c file where I have replaced the if condition with the old logic.

    Regards

    Paramesh

  • Hello Paramesh,

    I want to make sure I understand your use case.

    1) Does your use case involve using TTS to transmit packets at set time intervals? Or do you only want a packet to be transmitted after the ICE board has received an ARP packet?

    2) What is the physical setup? eg, do you have two ethernet ports on the AM335x ICE board connected to two ports on a computer running wireshark, and the computer is sending and receiving data?

    Regards,
    Nick
  • Hi,

    I want a packet to be transmitted after an ARP packet has been received by the ICE board and I am not using TTS. The procedure I followed was as follows:-

    I have an AM335xicev2 board. I wanted the board to send back a packet after having received an ARP packet.

    ARP packet I used was having the following data.

        0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0x01, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
        0x08, 0x06, 0x00, 0x01,
        0x08, 0x00, 0x06, 0x04, 0x00,0x01,
        0x01, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
        0xc0, 0xa8, 0x01, 0x16,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0xc0, 0xa8,0x01, 0x02

    When this packet was received , the board would respond with the same packet. I send this above packet from Colasoft packet builder. I can see that the board responds with the same packet. I had shared my wireshark file in the previous post. One port of my ICE v2 board is connected to one of the ethernet port of the PC. I am only using one port at a time in my PC as well as my board.

    I am attaching a image to show the physical setup I am using.

     I am using the Linux Ubuntu 16.04LTS PC to run the console of my board(minicom) and the windows10 PC to run the wireshark and colasoft packet builder softwares.

    Looking forward for your support.

    Thanks and Regards

    Paramesh

  • Hi,
    I believe that you were able to reproduce the delay between the packets I have reported.
    Looking forward for your support.


    Regards
    Paramesh
  • Hi Paramesh,

    I apologize for the delay. I will have a response for you tomorrow.
    Regards,
    Nick
  • Hello Paramesh,
    I am working on modifying the TI example code to test your use case.
    Regards,
    Nick
  • Hello Paramesh, 

    1) You are getting those outputs because your code is not yielding to allow other threads to run on the ARM core. Note that in test/src/test_common_utils.c in the ICSS-EMAC LLD, they include a SLEEP(100) function within every loop that polls for an incoming ethernet packet.

    2) In general, you can try to speed up your application by changing the priority of the threads or the scheduler. Since we can't control everything the Linux OS does, we can't guarantee that specific programs will take a certain amount of time to run. Check out the Data Path section of the ICSS-EMAC LLD Developer's Guide for a discussion of how packets are transferred from PRU hardware to your application. You could theoretically get rid of the delay of moving information from the PRU to the userspace application by doing everything in PRU firmware, but that would require a lot of development and I do not think TI has any samples that would be useful.

    Regards, 

    Nick