LWIP 关于PADDING

今天本来打算弄组播接收,结果发现了一个有意思的事情。似乎印象里,很久以前也思考过这个问题。那就是如果我发送少于18个字节,那么会自动填充成18个。由于帧头有42个字节,所以就是60个字节。在WIRESHARK上显示是60个字节。

就是我发送1个字节,那么wireshark显示有60个字节。

于是我看代码,一步一步的跟踪,最后跟踪到变量ETH_DMADESCTypeDef  DMATxDscrTab[ETH_TXBUFNB];

ETH_TXBUFNB的宏定义有两处,官网程序现在stm32f4x7_ETH.H里面定义了

 

/* 5 ethernet driver transmit buffers are used (in a chained linked list)*/ 
#ifndef ETH_TXBUFNB
 #define ETH_TXBUFNB             5      /* 5  Tx buffers of size ETH_TX_BUF_SIZE */
#endif

 

 

 

 

 

后来又在stm32f4x7_the_conf.h定义了

 

/*This define allow to customize configuration of the Ethernet driver buffers */
#define CUSTOM_DRIVER_BUFFERS_CONFIG


#ifdef  CUSTOM_DRIVER_BUFFERS_CONFIG
/* Redefinition of the Ethernet driver buffers size and count */
 #define ETH_RX_BUF_SIZE    ETH_MAX_PACKET_SIZE  /* buffer size for receive */
 #define ETH_TX_BUF_SIZE    ETH_MAX_PACKET_SIZE  /* buffer size for transmit */
 #define ETH_RXBUFNB        4                    /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
 #define ETH_TXBUFNB        4                    /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
#endif

这里如果把

ETH_TXBUFNB   宏定义值为1,那么板卡采用接收后发送的话,就会出现接收一帧发送两帧的情况,原因不明。

好,这里似乎有点跑题了。

然后就在网上找LWIP和60这两个关键字没找到。

然后乱找CSDN一般文章“

wireshark抓包怎么54字节也行,不是最少60    http://bbs.csdn.net/topics/390590266

 

 

(转载的)
根据rfc894的说明,以太网封装IP数据包的最大长度是1500字节,也就是说以太网最大帧长应该是以太网首部加上1500,再加上7字节的前导同步码和1字节的帧开始定界符,具体就是:7字节前导同步码 + 1字节帧开始定界符 + 6字节的目的MAC + 6字节的源MAC + 2字节的帧类型 + 1500 + 4字节的FCS。
    按照上述,最大帧应该是1526字节,但是实际上我们抓包得到的最大帧是1514字节,为什么不是1526字节呢?
    原因是当数据帧到达网卡时,在物理层上网卡要先去掉前导同步码和帧开始定界符,然后对帧进行CRC检验,如果帧校验和出错,就丢弃此帧。如果校验和正确,就判断帧的目的硬件地址是否符合自己的接收条件(目的地址是自己的物理硬件地址、广播地址、可接收的多播硬件地址等),如果符合,就将帧交给“设备驱动程序”做进一步处理。这时我们抓包的软件才能抓到数据,因此,抓包软件抓到的是去掉前导同步码、帧开始分界符、FCS之外的数据,其最大值是6 + 6 + 2 + 1500 = 1514。
    以太网规定,以太网帧数据域部分最小为46字节,也就是以太网帧最小是 6 + 6 + 2 + 46 + 4 = 64。除去4个字节的FCS,因此,抓包时就是60字节。当数据字段的长度小于46字节时,MAC子层就会在数据字段的后面填充以满足数据帧长不小于64 字节。由于填充数据是由MAC子层负责,也就是设备驱动程序。不同的抓包程序和设备驱动程序所处的优先层次可能不同,抓包程序的优先级可能比设备驱动程序更高,也就是说,我们的抓包程序可能在设备驱动程序还没有填充不到64字节帧的时候,已经捕获了数据。因此不同的抓包工具抓到的数据帧的大小可能不同。(比如,wireshark抓到的可能没有填充数据段,而sniffer抓到的就有填充数据段),(不过 根据我的观察wireshark不同的版本抓获的最小数据包的大小好像有60字节也有54字节的情况.....)

 


=============================

 

 

于是我就观察wireshark 发现 那个小飞机网络工具发送的帧可以长度可以小于60个字节,而我用STM32发送的最小60个字节。

于是查看wireshark,发现wireshark的echo可以识别发送的字符,就是我只发送一个字符,那么echo 就只是显示1个字符。仔细观察一下,有个关键字padding。

原来是填充的,就是自动补齐的。

然后找找网上的padding的内容。

在STM32的程序里面发现了这个函数

 

/**
  * @brief  Enables or disables the DMA Tx Desc padding for frame shorter than 64 bytes.
  * @param  DMATxDesc: pointer on a DMA Tx descriptor
  * @param  NewState: new state of the specified DMA Tx Desc padding for frame shorter than 64 bytes.
  *   This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void ETH_DMATxDescShortFramePaddingCmd(ETH_DMADESCTypeDef *DMATxDesc, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_FUNCTIONAL_STATE(NewState));
  
  if (NewState != DISABLE)
  {
    /* Enable the selected DMA Tx Desc padding for frame shorter than 64 bytes */
    DMATxDesc->Status &= (~(uint32_t)ETH_DMATxDesc_DP);
  }
  else
  {
    /* Disable the selected DMA Tx Desc padding for frame shorter than 64 bytes*/
    DMATxDesc->Status |= ETH_DMATxDesc_DP; 
  }
}


然后添加这个函数在程序的各个地方来试图禁用PADDING功能,无奈都没有成功。

 

最后在函数low_level_output发现了一个注释:

 

  /* Note: padding and CRC for transmitted frame 
     are automatically inserted by DMA */

 

 

 

 

 

看样子padding真是由硬件决定的。怪不得我用在线断点调试没有弄出来。

那么如何禁用padding? 还是不太清楚。

 

网上关于padding的文章有好多,这篇值得关注一下:

 

搞懂CSMA/CD,你就明白为什么以太网最小帧是64字节。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值