2. 检查 EMAC 接收和发送是否存在溢出和错误
A. 对于接收,检查是否有接收溢出:检查 EMAC_DMASTS 如下寄存器位是否置起:
如果发生 OVF 位置起,表示软件的处理速度太慢,不能及时读出缓冲区的数据,导致数据溢出。出现此
种情况的处理方法:
增加接收缓冲区个数,此处会增加内存使用
#define EMAC_RXBUFNB 10 //收缓冲区个数
#define EMAC_TXBUFNB 10 //发送缓冲区个数
提高软件处理速度
此部分可以使用提高主频(在规格范围内),优化软件加快处理流程。
B.对于发送,检查是否有发送错误,如下图是否会返回 ERROR
如果此处返回错误,是因为软件写发送缓冲区的速度太快,EMAC 来不及发送完发送缓冲区的数据,出
现此种情况时的处理方法:
增加发送缓冲区个数,此处会增加内存使用
#define EMAC_RXBUFNB 10 //收缓冲区个数
#define EMAC_TXBUFNB 10 //发送缓冲区个数
减慢软件写发送缓冲区的速度
如果使用 EMAC 速度是 100Mbps,理论上总线速度可以到 12.5MB/s,建议软件写缓冲区的速度不
要超过此速度,因为总线上还有其它协议开销,实际的速度会比 12.5MB/s 要低。
发送时增加发送完成判断,以保证有足够缓冲区存放数据
如下图,每次发送完成之后判断下一个缓冲区是否发送完成,此处 timeout 可根据实际发送数据的
多少进行修改
error_status emac_txpkt_chainmode(u16 FrameLength)
{
uint32_t timeout = 0xFFFF;
/* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
if((dma_tx_desc_to_set->status & EMAC_DMATXDESC_OWN) != (u32)RESET)
{
/* Return ERROR: OWN bit set */
return ERROR;
}
/* Setting the Frame Length: bits[12:0] */
dma_tx_desc_to_set->controlsize = (FrameLength & EMAC_DMATXDESC_TBS1);
/* Setting the last segment and first segment bits (in this case a frame is transmitted in one descriptor) */
dma_tx_desc_to_set->status |= EMAC_DMATXDESC_LS | EMAC_DMATXDESC_FS;
/* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
dma_tx_desc_to_set->status |= EMAC_DMATXDESC_OWN;
/* When Tx Buffer unavailable flag is set: clear it and resume transmission */
if(emac_dma_flag_get(EMAC_DMA_TBU_FLAG))
{
/* Clear TBUS ETHERNET DMA flag */
emac_dma_flag_clear(EMAC_DMA_TBU_FLAG);
/* Resume DMA transmission*/
EMAC_DMA->tpd_bit.tpd = 0;
}
/* Update the ETHERNET DMA global Tx descriptor with next Tx decriptor */
/* Chained Mode */
/* Selects the next DMA Tx descriptor list for next buffer to send */
dma_tx_desc_to_set=(emac_dma_desc_type*) (dma_tx_desc_to_set->buf2nextdescaddr);
while((dma_tx_desc_to_set->status & EMAC_DMATXDESC_OWN) != (u32)RESET)
{
if((timeout --) == 0)
{
break;
}
}
/* Return SUCCESS */
return SUCCESS;
}
|