如何设置STM32F4以太网最小帧长度

2019-12-11 18:14发布

足 IEEE 802.3 中规定最小帧长度为46或者64字节,ST提供的驱动默认情况下不足64字节的会补0x00,填满64字节再发送出去,现在发现一些路由器对于64字节的ARP广播包不应答,该如何设置不自动补0呢?

电脑的IP为192.168.1.3,路由器的IP为192.168.1.1,电脑发送42字节长度(wiresharp不显示4字节CRC)的ARP广播包很快得到路由器的回复。
arp4.png (137.4 KB, 下载次数: 0) 下载附件 数据手册中描述 disable PAD 2019-10-20 16:27 上传

按照手册的描述,修改HAL提供的驱动,HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameLength) 函数中的一句
heth->TxDesc->Status |=ETH_DMATXDESC_FS|ETH_DMATXDESC_LS|ETH_DMATXDESC_DP;//有修改,帧小于64byte时,自带补齐64B数据,原来为:heth->TxDesc->Status |=ETH_DMATXDESC_FS|ETH_DMATXDESC_LS;
也就是发送时将DP为置1,这样修改过后,wiresharp完全侦听不到设备发出数据了,怀疑是disable PAD置位后,补位项和CRC一起去掉了,导致侦听不到数据








友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
6条回答
ljq77402
1楼-- · 2019-12-11 23:23
修改驱动中的发送函数:


/**
  * @brief  Sends an Ethernet frame.
  * @param  heth pointer to a ETH_HandleTypeDef structure that contains
  *         the configuration information for ETHERNET module
  * @param  FrameLength Amount of data to be sent
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameLength)
{
  uint32_t bufcount = 0U, size = 0U, i = 0U;
  
  /* Process Locked */
  __HAL_LOCK(heth);
  
  /* Set the ETH peripheral state to BUSY */
  heth->State = HAL_ETH_STATE_BUSY;
  
  if (FrameLength == 0U)
  {
    /* Set ETH HAL state to READY */
    heth->State = HAL_ETH_STATE_READY;
   
    /* Process Unlocked */
    __HAL_UNLOCK(heth);
   
    return  HAL_ERROR;                                    
  }  
  
  /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
  if(((heth->TxDesc)->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
  {  
    /* OWN bit set */
    heth->State = HAL_ETH_STATE_BUSY_TX;
   
    /* Process Unlocked */
    __HAL_UNLOCK(heth);
   
    return HAL_ERROR;
  }
  
  /* Get the number of needed Tx buffers for the current frame */
  if (FrameLength > ETH_TX_BUF_SIZE)
  {
    bufcount = FrameLength/ETH_TX_BUF_SIZE;
    if (FrameLength % ETH_TX_BUF_SIZE)
    {
      bufcount++;
    }
  }
  else
  {  
    bufcount = 1U;
  }
  if (bufcount == 1U)
  {
    /* Set LAST and FIRST segment */
    heth->TxDesc->Status |=ETH_DMATXDESC_FS|ETH_DMATXDESC_LS|ETH_DMATXDESC_DP;//有修改,帧小于64byte时,自带补齐64B数据,原来为:heth->TxDesc->Status |=ETH_DMATXDESC_FS|ETH_DMATXDESC_LS;
    /* Set frame size */
    heth->TxDesc->ControlBufferSize = (FrameLength & ETH_DMATXDESC_TBS1);
    /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
    heth->TxDesc->Status |= ETH_DMATXDESC_OWN;
    /* Point to next descriptor */
    heth->TxDesc= (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr);
  }
  else
  {
    for (i=0U; i< bufcount; i++)
    {
      /* Clear FIRST and LAST segment bits */
      heth->TxDesc->Status &= ~(ETH_DMATXDESC_FS | ETH_DMATXDESC_LS);
      
      if (i == 0U)
      {
        /* Setting the first segment bit */
        heth->TxDesc->Status |= ETH_DMATXDESC_FS;  
      }
      
      /* Program size */
      heth->TxDesc->ControlBufferSize = (ETH_TX_BUF_SIZE & ETH_DMATXDESC_TBS1);
      
      if (i == (bufcount-1U))
      {
        /* Setting the last segment bit */
        heth->TxDesc->Status |= ETH_DMATXDESC_LS;
        size = FrameLength - (bufcount-1U)*ETH_TX_BUF_SIZE;
        heth->TxDesc->ControlBufferSize = (size & ETH_DMATXDESC_TBS1);
      }
      
      /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
      heth->TxDesc->Status |= ETH_DMATXDESC_OWN;
      /* point to next descriptor */
      heth->TxDesc = (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr);
    }
  }
  
  /* When Tx Buffer unavailable flag is set: clear it and resume transmission */
  if (((heth->Instance)->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET)
  {
    /* Clear TBUS ETHERNET DMA flag */
    (heth->Instance)->DMASR = ETH_DMASR_TBUS;
    /* Resume DMA transmission*/
    (heth->Instance)->DMATPDR = 0U;
  }
  
  /* Set ETH HAL State to Ready */
  heth->State = HAL_ETH_STATE_READY;
  
  /* Process Unlocked */
  __HAL_UNLOCK(heth);
  
  /* Return function status */
  return HAL_OK;
}
ljq77402
2楼-- · 2019-12-12 05:15
自己顶下
ljq77402
3楼-- · 2019-12-12 06:43
有没人帮忙用wiresharp侦听下,LWIP入网时,发送的arp广播包长度是多少?
lingdianhao
4楼-- · 2019-12-12 07:04
MAC有帧自动填充功能吧,看下开启了没有。
ljq77402
5楼-- · 2019-12-12 11:41
 精彩回答 2  元偷偷看……
ljq77402
6楼-- · 2019-12-12 15:22
结贴,原来是mac设置成了组播地址,开启自动帧填充,最小长度为64BYTE的报文,路由器也会解析!

一周热门 更多>