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:TMDSCNCD28379D 上的 TCP 软件包处理速度慢

Guru**** 2509565 points
Other Parts Discussed in Thread: TMDSCNCD28379D

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1062277/tmdscncd28379d-slow-tcp-package-processing-on-tmdscncd28379d

器件型号:TMDSCNCD28379D

大家好

我 需要 使用微控制器通信管理器上运行的 lwIP 堆栈从 Linux 进程与 TMDSCNCD28379D 控制卡进行通信。

我计划以大约50Hz 的速率向微控制器发送包含控制信息的 TCP 数据包、但似乎上述数据包的处理速度非常缓慢、并且在发送了几十个数据包后、 微控制器似乎不再回复任何传入的 TCP 数据包。

我从 Linux 计算机上制作了一段简短的视频、以展示流量在 Wireshark 中的样子(控制卡为192.168.0.4、Linux PC 为192.168.0.1):

e2e.ti.com/.../wireshark.mp4

我使用以下代码创建侦听 TCP 套接字:

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);
}

我使用以下代码接受传入的 TCP 连接:

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
        }
    }
}

我使用以下代码处理 TCP 包:

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);
        }
    }
}

除了基于中断的软件包处理之外、通信管理器不执行任何操作。 我以与 http 服务器示例相同的方式设置 CM、以下代码显示了主例程以及启动:

//*****************************************************************************
//
// 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;
        }

    }
}

是否有人知道我可以如何解决这个问题?

非常感谢!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!  

    我们将查看它并在几天内返回、

    此致

    Siddharth

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    与此同时,我解决了这个问题。 我必须将`systickPeriodValue`调整为较低的代码值,以实现更快的 TCP 数据包处理。 此外,我忘记了通过调用`pbuf_free`来释放数据包缓冲区数据结构。 通过这些更改、我能够轻松地每10ms 处理一次封装。