由于内存无法释放,LWIP在一段时间后挂起

时间:2019-03-28 06:33:42

标签: c stm32 freertos lwip

OBS:我正在使用STM32F2微控制器,FreeRTOS和lwIP,并且正在使用原始API

我有一个应用程序,可以在其中监听一台PC并连接到另一台PC。基本上,当我尝试实现高吞吐量时,所有功能都可以正常工作一段时间,但是大约半小时后...收到大约80〜90k数据包后会挂起。实际上它的挂起位置略有变化,但是当tcp_write返回err_mem时,当我开始关闭连接时,它就停止了执行。

有时它会挂在这行:

<androidx.coordinatorlayout.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">

    <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/transparent"
            android:translationZ="2dp"
            android:fitsSystemWindows="true"/>

    <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">


        <!-- Some other layouts -->

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

有时,当我调用tcp_write时,它返回ERR_MEM,并且除了ERR_MEM之后,它什么也没有返回。这是我发送数据的方式,基本上我接受连接,接收数据,存储PCB,做点什么然后回复相同的PCB:

/* useg should point to last segment on unacked queue */

  useg = pcb->unacked;

  if (useg != NULL) {

    for (; useg->next != NULL; useg = useg->next);  <------- here

  }

这是我设置监听套接字的方法:

err_t ret;
ret = tcp_write(g_response[i].pcb, data, len, 1);
if(ret == ERR_OK)
    tcp_output(g_response[i].pcb);
else
    tcp_close(g_response[i].pcb);

这是我对send和rcv的回调

pcb = tcp_new();
tcp_bind(pcb, IP_ADDR_ANY, port);
pcb = tcp_listen(pcb);
pcb->so_options |= SOF_KEEPALIVE; // enable keep-alive
pcb->keep_intvl = 1000; // sends keep-alive every second
tcp_accept(pcb, accept);

在没有ERR_MEM的情况下我关闭pcb时发送数据的方式可能很奇怪,但是现在丢失的数据包更少了,实际上它使我能够交换多达90k的数据包,然后才随机失败。

我实际上需要高吞吐量,这就是为什么我要调用tcp_output而不是让tcpip_thread处理发送数据包的原因。每当我让此线程占用数据包传输的时间时,它就可以工作,但是它太慢了(也许每200〜300 ms一个数据包,通过在函数中调用tcp_output,我到达了将数据发送到10 ms以下的地步) ...我也没有传输大量数据,因此很有帮助。

最近我注意到tcpip_thread调用了输入函数,转到了ipv4_input,转到了memp_free并一直运行,但从未退出(我实际上正在运行一个新测试,所以稍后我将使用在冻结之前将调用栈调用到输入中)。

有人做了类似的事情吗?高吞吐量的小数据包突发?

编辑:如所承诺的,这是我的调用堆栈

  

位于cmsis_os.c的osMutexWait():681 0x800474c位于sys_arch_protect()的

     

sys_arch.c:400 0x80146a6 do_memp_free_pool()at memp.c:415 0x800dca2

     

memp.c:486上的memp_free()0x800dcf8 tcp.c:1.336上的tcp_seg_free()

     

tcp_in.c处的0x800fb0e tcp_receive():c:1.162 0x8011712 tcp_process()处

     

tcp_in.c:877 0x8011048 tcp_input()at tcp_in.c:367 0x8010692

     

在ip4.c处为ip4_input():670 0x800c688在ethernet.c处为ethernet_input():176

     

tcpip.c上的0x80142fe tcpip_thread():c 0x8006836

     

位于port.c的pxPortInitialiseStack():231 0x8004cd0

就像@Lundin所说的,这是一个并发问题。我可能应该尝试更小心地调用函数。我将尝试修改代码以使用netconn或socket而不是tcp_pcb,然后测量速度。我真的需要高吞吐量

0 个答案:

没有答案