LWIP移植成功了

2020-01-01 17:34发布

成功移植lwip1.3.1 1.3.2 1.4.1,裸机能跑tcp客户端和服务器。
开心之余,又有些问题需要请教了,lwip里面如何处理断线重连的问题?

下面是我实验的现象:
我在裸机上使用lwip,tcp做了服务器和客户端,在连接后把网线拔掉,tcp_poll函数还是会被执行的,这时候把网线插上(还没出现abort错误),需要重新连接(端口没变,原连接已经没反应了),连接后上一次连接的pcb仍然存在,这时候会发现轮询时候有两个pcb连接在运行。等了好几分钟后(关闭了保活设置)第一个pcb连接出现连接错误,自动断开。。。
这两个pcb占用同一个端口不会产生冲突吗?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
99条回答
xhyzjiji
1楼-- · 2020-01-04 07:58
flyleaf 发表于 2013-8-5 11:06
野火的板子也有lwip的程序呀,教程也有

野火是有,奋斗也有,但是对于我们新手还是有些太过于简陋了,这个笔记只是想记录移植需要注意的地方和一些使用心得,希望可以方便后面需要使用的同学快速上手。
xhyzjiji
2楼-- · 2020-01-04 10:10
 精彩回答 2  元偷偷看……
ersha4877
3楼-- · 2020-01-04 15:59
加油 ,看完希望自己可以搞定了,谢谢
xhyzjiji
4楼-- · 2020-01-04 16:37
本帖最后由 xhyzjiji 于 2013-8-17 23:25 编辑

继续写笔记咯。。。

接下来是low_level_input(还是把代码贴上来吧)红 {MOD}是源码空缺部分,绿 {MOD}为修改后的代码,后面也是如此
static struct pbuf *
low_level_input(struct netif *netif)
{
  struct ethernetif *ethernetif = netif->state;
  struct pbuf *p, *q;
  u16_t len;
  uint8_t* buffer;

  /* Obtain the size of the packet and put it into the "len"
     variable. */
  len = ;接收到的数据包总长度(包括以太网帧头和协议报头)
  len = enc28j60PacketReceive(1500, eth_rx_buf); //这里使用的是网络接口的接收驱动enc28j60PacketReceive,在接收一个数据包的同时将其存储于缓存eth_rx_buf中
  buffer = eth_rx_buf;


#if ETH_PAD_SIZE
  len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
#endif

  /* We allocate a pbuf chain of pbufs from the pool. */
  p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);  //为lwip协议栈的接收缓存开辟内存
  
  if (p != NULL) {

#if ETH_PAD_SIZE
    pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif

    /* We iterate over the pbuf chain until we have read the entire
     * packet into the pbuf. */
    for(q = p; q != NULL; q = q->next) {
      /* Read enough bytes to fill this pbuf in the chain. The
       * available data in the pbuf is given by the q->len
       * variable.
       * This does not necessarily have to be a memcpy, you can also preallocate
       * pbufs for a DMA-enabled MAC and after receiving truncate it to the
       * actually received size. In this case, ensure the tot_len member of the
       * pbuf is the sum of the chained pbuf len members.
       */
      read data into(q->payload, q->len); //请仔细阅读英文注释,这个语句提醒我们,将读到接收缓存的数据转移到lwip内核中去,由于lwip对于内存处理比较强大,考虑到零碎内存的存在,在分配内存时,对于len长度的数据,内存并非是连续的,而是分散的,如果是分散的,那将也是一个链表形式,因此这里出现了for循环体,注释也提到memcpy函数,则希望我们将数据复制到每个零碎的内存空间里。
             memcpy((uint8_t*)q->payload, (uint8_t*)&buffer, q->len);  //赋值接收缓冲区的数据到lwip内存池中
     i += q->len; //记录复制数据的位置

    }
    acknowledge that packet has been read(); //这里可以填上包接收完毕的一些消息或者指令,如果没有需要,可以注释掉该语句

#if ETH_PAD_SIZE
    pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif

    LINK_STATS_INC(link.recv);
  } else {
    drop packet();
    LINK_STATS_INC(link.memerr);
    LINK_STATS_INC(link.drop);
  }
  //记录接收数据数或者对链路状态异常情况的处理,如有需要请自行添加,否则注释掉即可

  return p;  
}

忘了个很重要的图没上传。。。
我们可以利用这个图顺藤摸瓜来了解lwip的工作流程。
xhyzjiji
5楼-- · 2020-01-04 16:54
本帖最后由 xhyzjiji 于 2013-8-17 23:29 编辑

static err_t
low_level_output(struct netif *netif, struct pbuf *p)  //
{
  struct ethernetif *ethernetif = netif->state;
  struct pbuf *q;

  uint16_t offset = 0;

  initiate transfer(); //初始化传输设备,无需要则注释掉
  
#if ETH_PAD_SIZE
  pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif

  for(q = p; q != NULL; q = q->next) {
    /* Send the data from the pbuf to the interface, one pbuf at a
       time. The size of the data in each pbuf is kept in the ->len
       variable. */
    send data from(q->payload, q->len); //对比input,output也是如此,不过是个反过程,将lwip发送队列的内存池数据塞进我们网卡的发送缓存区中,准备发送
    memcpy((uint8_t*)&eth_tx_buf[offset], (uint8_t*)q->payload, q->len);
    offset += q->len;  //记录复制数据的位置

  }

  signal that packet should be sent();  //提示我们需要发送数据了,注释掉
  enc28j60PacketSend(offset, eth_tx_buf);  //调用底层驱动发送数据咯

#if ETH_PAD_SIZE
  pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
  
  LINK_STATS_INC(link.xmit); //记录发送数据个数,不记录就注释可以了

  return ERR_OK;
}

至此,底层驱动已经于lwip关联起来,lwip可以自由调用底层驱动了。这告诉我们,底层驱动只需要两个函数,一个是接收数据包存储起来,并且可以返回数据包大小的函数;一个是发送指定缓冲区的数据,对于其他的网络芯片也是如此。

对于lwip的内存池和一些重要的数据结构,可能在后面的应用提及会比较好吧?
Name_006
6楼-- · 2020-01-04 19:48
多谢楼主  最近研究下这方面的                                                                     

一周热门 更多>