足 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一起去掉了,导致侦听不到数据
/**
* @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;
}
一周热门 更多>