[AT32F407] AT32F407/437使用网口收发数据丢包问题处理

[复制链接]
 楼主| 问天少年 发表于 2024-10-16 14:10 | 显示全部楼层 |阅读模式
Questions:AT32F407/437 在使用 EMAC 网口进行以太网数据收发时,如果出现数据丢包,应该如何处理? Answer:
1. 检查 Ethernet PHY 的时钟源不能使用通过 PLL 分频 25MHz/50MHz 给 Ethernet PHY 供时钟,通过 PLL 的时钟可能达不到 EthernetPHY 的时钟要求,导致概率出现丢包。如下介绍如何给 Ethernet PHY 供时钟。AT32F407/437 使用 EMAC 时,根据需求需要给 Ethernet PHY 提供 25MHz/50MHz 时钟 当需要给 Ethernet PHY 提供 25MHz 时钟时,有两种方法,如下图 1 和图 2。 当需要给 Ethernet PHY 提供 50MHz 时钟时,如下方法图 3,建议直接给 Ethernet PHY 挂 50 晶振注意:不能使用通过 PLL 分频 25MHzz/50MHz 给 Ethernet PHY 供时钟选择 25MHz 晶振作为 AT32F407 外置时钟 HEXT,CLKOUT(PA8)时钟源选择 HEXT,CLKOUT 输出25MHz 时钟作为 Ethernet PHY 的时钟源;
图 1 CLKOUT 输出 HEXT


59036670f58b7bdc82.png
选择 25MHz 晶振直接作为 Ethernet PHY 时钟。
图 2 25MHz 晶振给 PHY 时钟
33195670f58cf70c45.png
选择 50MHz 晶振直接作为 Ethernet PHY 时钟
图 3 50MHz 晶振给 PHY 时钟
26568670f58ecdbf29.png


 楼主| 问天少年 发表于 2024-10-16 14:13 | 显示全部楼层
2. 检查 EMAC 接收和发送是否存在溢出和错误
A. 对于接收,检查是否有接收溢出:检查 EMAC_DMASTS 如下寄存器位是否置起:
62410670f590b06d30.png
如果发生 OVF 位置起,表示软件的处理速度太慢,不能及时读出缓冲区的数据,导致数据溢出。出现此
种情况的处理方法:
 增加接收缓冲区个数,此处会增加内存使用
  1. #define EMAC_RXBUFNB 10 //收缓冲区个数
  2. #define EMAC_TXBUFNB 10 //发送缓冲区个数

提高软件处理速度
此部分可以使用提高主频(在规格范围内),优化软件加快处理流程。
B.对于发送,检查是否有发送错误,如下图是否会返回 ERROR
62281670f594686fb0.png
如果此处返回错误,是因为软件写发送缓冲区的速度太快,EMAC 来不及发送完发送缓冲区的数据,出
现此种情况时的处理方法:
 增加发送缓冲区个数,此处会增加内存使用
  1. #define EMAC_RXBUFNB 10 //收缓冲区个数
  2. #define EMAC_TXBUFNB 10 //发送缓冲区个数

 减慢软件写发送缓冲区的速度
如果使用 EMAC 速度是 100Mbps,理论上总线速度可以到 12.5MB/s,建议软件写缓冲区的速度不
要超过此速度,因为总线上还有其它协议开销,实际的速度会比 12.5MB/s 要低。
 发送时增加发送完成判断,以保证有足够缓冲区存放数据
如下图,每次发送完成之后判断下一个缓冲区是否发送完成,此处 timeout 可根据实际发送数据的
多少进行修改
  1. error_status emac_txpkt_chainmode(u16 FrameLength)
  2. {
  3. uint32_t timeout = 0xFFFF;
  4. /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
  5. if((dma_tx_desc_to_set->status & EMAC_DMATXDESC_OWN) != (u32)RESET)
  6. {
  7. /* Return ERROR: OWN bit set */
  8. return ERROR;
  9. }
  10. /* Setting the Frame Length: bits[12:0] */
  11. dma_tx_desc_to_set->controlsize = (FrameLength & EMAC_DMATXDESC_TBS1);
  12. /* Setting the last segment and first segment bits (in this case a frame is transmitted in one descriptor) */
  13. dma_tx_desc_to_set->status |= EMAC_DMATXDESC_LS | EMAC_DMATXDESC_FS;
  14. /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
  15. dma_tx_desc_to_set->status |= EMAC_DMATXDESC_OWN;
  16. /* When Tx Buffer unavailable flag is set: clear it and resume transmission */
  17. if(emac_dma_flag_get(EMAC_DMA_TBU_FLAG))
  18. {
  19. /* Clear TBUS ETHERNET DMA flag */
  20. emac_dma_flag_clear(EMAC_DMA_TBU_FLAG);
  21. /* Resume DMA transmission*/
  22. EMAC_DMA->tpd_bit.tpd = 0;
  23. }
  24. /* Update the ETHERNET DMA global Tx descriptor with next Tx decriptor */
  25. /* Chained Mode */
  26. /* Selects the next DMA Tx descriptor list for next buffer to send */
  27. dma_tx_desc_to_set=(emac_dma_desc_type*) (dma_tx_desc_to_set->buf2nextdescaddr);
  28. while((dma_tx_desc_to_set->status & EMAC_DMATXDESC_OWN) != (u32)RESET)
  29. {
  30. if((timeout --) == 0)
  31. {
  32. break;
  33. }
  34. }
  35. /* Return SUCCESS */
  36. return SUCCESS;
  37. }
您需要登录后才可以回帖 登录 | 注册

本版积分规则

79

主题

564

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部

79

主题

564

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部