ZYNQ EMIO 千兆以太网调试教程
基于ZYNQ EMIO的千兆网卡调试
重要的参考链接https://blog.csdn.net/weixin_43969075/article/details/119872875
ZYNQ硬件端设计
-
ZYNQ配置
为了满足测试需求,ZYNQ至少需要配置EMAC,TIMER,UART
-
GMII TO RGMII IP配置
需要注意的是这里的PHY地址并不是真正的外部PHY芯片的地址,而是一个虚拟地址,需要跟外部PHY的真实地址不一样,才能正常工作,外部PHY的地址是通过3个IO在上电时根据状态来配置的。这个虚拟地址在配置PLATFORM的时候会用到
软件端设计
-
生成Platform
以导出的硬件,生成带FREERTOS的平台。
配置BSP,包含LWIP
配置LWIP,把API接口从RAW_API切换到SOCKET_API,使能DHCP,将TCP_WND设置到20480
修改platform_network/ps7_cortexa9_0/freertos_ps7_cortexa9_0/bsp/libsrc/lwip220/src/lwip-2.2.0/contrib/ports/xilinx/netif/xemacpsif_physpeed.c
- 增加分支,我使用的PHY芯片是YT8521,标识是0 无厂商标识
static u32_t get_IEEE_phy_speed(XEmacPs *xemacpsp, u32_t phy_addr)
{
u16_t phy_identity;
u32_t RetStatus;
XEmacPs_PhyRead(xemacpsp, phy_addr, PHY_IDENTIFIER_1_REG,
&phy_identity);
if (phy_identity == PHY_TI_IDENTIFIER) {
RetStatus = get_TI_phy_speed(xemacpsp, phy_addr);
} else if (phy_identity == PHY_REALTEK_IDENTIFIER) {
RetStatus = get_Realtek_phy_speed(xemacpsp, phy_addr);
} else if (phy_identity == PHY_XILINX_PCS_PMA_ID1) {
RetStatus = get_Xilinx_pcs_pma_phy_speed(xemacpsp, phy_addr);
} else if (phy_identity == PHY_ADI_IDENTIFIER) {
RetStatus = get_Adi_phy_speed(xemacpsp, phy_addr);
} else if (phy_identity == 0) {
RetStatus = get_Yt8521_phy_speed(xemacpsp, phy_addr);
} else {
RetStatus = get_Marvell_phy_speed(xemacpsp, phy_addr);
}
return RetStatus;
}2.增加代码获取自己协商到的速度
static u32_t get_Yt8521_phy_speed(XEmacPs *xemacpsp, u32_t phy_addr)
{
u16_t temp;
u16_t control;
u16_t status;
xil_printf("Yt8521 Start PHY autonegotiation \r\n");
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
control |= IEEE_CTRL_AUTONEGOTIATE_ENABLE;
control |= IEEE_STAT_AUTONEGOTIATE_RESTART;
control &= IEEE_CTRL_ISOLATE_DISABLE;
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
xil_printf("Waiting for PHY to complete autonegotiation.\r\n");
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
sleep(1);
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
&status);
}
xil_printf("autonegotiation complete \r\n");
xil_printf("Waiting for Link to be up \r\n");
XEmacPs_PhyRead(xemacpsp, phy_addr, 0x11, &temp);
while(!(temp & (1<<10))) {
XEmacPs_PhyRead(xemacpsp, phy_addr, 0x11, &temp);
}
xil_printf("temp:0x%x\n", temp);
if((temp & 0xc000) == 0x8000) {
return 1000;
}
else if((temp & 0xc000) == 0x4000) {
return 100;
}
else if((temp & 0xc000) == 0x0000) {
return 10;
} else {
xil_printf("get_IEEE_phy_speed(): Invalid speed bit value, Defaulting to Speed = 10 Mbps\r\n");
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &temp);
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, 0x0100);
return 10;
}
return 0;
} -
应用程序
直接添加基于FREERTOS的PERF SERVER应用
-
测试
到另一台机器使用perf测试,可以达到940Mb/s的带宽
其 它
-
怎么确定PHY地址
使用了三个复用的IO上电时来确定地址,PHYAD[2:0],当前电路被配置为7
XILINX检测哪个地址可用的方法是向所有的地址发送信息,检测哪个地址响应不是0XFFFF作为判断依据
-
PHY标识
PHY中有两个存器用来保存标识信息
PHY Identification Register1 (0x02), 组织标识
默认值0x0
PHY Identification Register2 (0x03),组织,类型,版本
默认值0x11a
-
与外部PHY芯片的接口电平
因为使用了BANK34的EMIO接口,当前BANK被设置为了3.3V,所以接口电平需要使用3.3V
在PHY端,需要硬件IO端口来配置接口电平为3.3V,此时的PHY内部的LDO被禁用,需要在硬件上给接口提供3.3V电源,这些都需要硬件支持
-
碰到的问题和最终解决办法
1、DHCP 超时, 解决办法,需要在PLATFORM中xemacpsif_physpeed.c文件中定义宏#define XPAR_GMII2RGMIICON_0N_ETH0_ADDR 8
2、速度达不到千兆,解决办法,需要配置lwip,将TCP_WND扩大,测试发现,配置到20480时已经可以达到900M/s以上的速度