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.

TMDSCNCD28379D: Slow TCP package processing on TMDSCNCD28379D

Part Number: TMDSCNCD28379D

Hello everyone

I need to communicate to a TMDSCNCD28379D control card from a Linux process using the lwIP stack running on the communication manager of the microcontroller.

I am planning on sending TCP packages containing control information at a rate of around 50Hz to the microcontroller but it seems like the the processing of said packages is happening really slowly and after a couple dozen packages have been sent, it seems like the microcontroller does not reply to any incoming TCP packages anymore.

I made a short video from my Linux machine to show what the traffic looks like in wireshark (the control card is 192.168.0.4 and the Linux PC is 192.168.0.1):

I create a LISTEN TCP socket using the following code:

void setupCommInterface(void){
    //create a new tcp pcb
    struct tcp_pcb* connection_pcb = tcp_new();
    //bind the pcb to the port comm_port
    err_t err=tcp_bind(connection_pcb,IP_ANY_TYPE,COMM_PORT);
    if(err!=ERR_OK){
        if(err==ERR_USE){
            while(1){}
        }
        else if(err==ERR_VAL){
            while(1){}
        }
        while(1){}
    }

    welcoming_socket_pcb=tcp_listen(connection_pcb);
    //start accepting connections on port COMM_PORT
    tcp_accept(welcoming_socket_pcb,accept_cb);
}

I accept an incoming TCP connection using the following code:

err_t accept_cb(void * arg, struct tcp_pcb* new_pcb, err_t err){
    if(err==ERR_OK){
        //set the connection active flag
        connection_active=true;
        //register callback for received data
        tcp_recv(new_pcb, tcp_recvd_cb);
        return ERR_OK;
    }
    else{
        while(1){
            //wait forever to preserve debug state
        }
    }
}

I process TCP packages using the following code:

err_t tcp_recvd_cb(void* arg, struct tcp_pcb* tcppcb, struct pbuf* p,err_t err){
    //payload being NULL indicated that the TCP connection has been terminated
    if(p==NULL){
        tcp_connection_reset_counter++;
        connection_active=false;
        // close the pcb
        if(tcp_close(tcppcb)!=ERR_OK){
            while(1){}
        }
        // listen to new connections again
        //tcp_accept(welcoming_socket_pcb,accept_cb);
        return ERR_OK;
    }
    else{
        if(err==ERR_OK){
            // -- process the data in p , p is NULL if the remote host terminated the connection --
            memcpy(buffer,p->payload,p->len);
            u16_t bytes_read=p->len;
            //indicate that a new command is available for processing in the buffer
            command_available=true;
            // -- indicate that bytes were read and we are ready to receive more data --
            tcp_recved(tcppcb,bytes_read);   //indicate that no_bytes_read were read and we are ready to receive more data
            // -- echo the received data back
            //tcp_write(tcppcb,buffer,bytes_read,TCP_WRITE_FLAG_COPY);
            return ERR_OK;
        }
        else{
            //wait forever and preserve debug state
            while(1);
        }
    }
}

Other than the interrupt based package processing, the communication manager doesn't do any work. I set up the CM in the same way as the http server example, the following code shows the main routine as well as the startup:

//*****************************************************************************
//
// This example demonstrates the use of the Ethernet Controller.
//
//*****************************************************************************
int
main(void)
{
    unsigned long ulUser0, ulUser1;
    unsigned char pucMACArray[8];

    //
    // User specific IP Address Configuration.
    // Current implementation works with Static IP address only.
    //
    unsigned long IPAddr = 0xC0A80004;
    unsigned long NetMask = 0xFFFFFF00;
    unsigned long GWAddr = 0x00000000;

    //
    // Initializing the CM. Loading the required functions to SRAM.
    //
    CM_init();
    //clear all ipc flags
    IPC_clearFlagLtoR(IPC_CM_L_CPU1_R, IPC_FLAG_ALL);
    //synchronize both core using ipc flag31
    IPC_sync(IPC_CM_L_CPU1_R, IPC_FLAG31);
    //initial test ipc
    int i;
    for(i=0; i<10; i++){readData[i] = i;}
    IPC_sendCommand(IPC_CM_L_CPU1_R, IPC_FLAG0, IPC_ADDR_CORRECTION_ENABLE,
                    IPC_CMD_READ_MEM, (uint32_t)readData, 10);
    IPC_waitForAck(IPC_CM_L_CPU1_R, IPC_FLAG0);
    if(IPC_getResponse(IPC_CM_L_CPU1_R) == TEST_PASS){pass = 1;}
    else{pass = 0;}

    //
    // IPC Initialization for Communication with CPU1
    //


    SYSTICK_setPeriod(systickPeriodValue);
    SYSTICK_enableCounter();
    SYSTICK_registerInterruptHandler(SysTickIntHandler);
    SYSTICK_enableInterrupt();

    //
    // Enable processor interrupts.
    //
    Interrupt_enableInProcessor();
        
    // Set user/company specific MAC octets
    // (for this code we are using A8-63-F2-00-00-80)
    // 0x00 MACOCT3 MACOCT2 MACOCT1
    ulUser0 = 0x00F263A8;

    // 0x00 MACOCT6 MACOCT5 MACOCT4
    ulUser1 = 0x00800000;

    //
    // Convert the 24/24 split MAC address from NV ram into a 32/16 split MAC
    // address needed to program the hardware registers, then program the MAC
    // address into the Ethernet Controller registers.
    //
    pucMACArray[0] = ((ulUser0 >>  0) & 0xff);
    pucMACArray[1] = ((ulUser0 >>  8) & 0xff);
    pucMACArray[2] = ((ulUser0 >> 16) & 0xff);
    pucMACArray[3] = ((ulUser1 >>  0) & 0xff);
    pucMACArray[4] = ((ulUser1 >>  8) & 0xff);
    pucMACArray[5] = ((ulUser1 >> 16) & 0xff);

    //
    // Initialize ethernet module.
    //
    Ethernet_init(pucMACArray);

    //
    // Initialze the lwIP library, using DHCP.
    //
    lwIPInit(0, pucMACArray, IPAddr, NetMask, GWAddr, IPADDR_USE_STATIC);

    //
    // Initialize the HTTP webserver daemon.
    //
    //httpd_init();

    //
    // Initialize the ccard communication interface
    //
    setupCommInterface();

    //
    // Loop forever. All the work is done in interrupt handlers.
    //
    while(1){
        if(reset_connection){
            reset_connection=false;
            tcp_recvd_cb(NULL,NULL,NULL,NULL);
        }
        if(command_available){
            //processCommand();
            command_available=false;
        }

    }
}

Does anyone have an idea how I could go about this issue?

Thanks very much!