Vivado 2019.1
FPGA: Artix7 XC7A100T
DDR3: MT41K256M16TW-107
PHY: RTL8211F(商业级)
为加快进入application,设置如下:
1.禁用autodetect, phy_link_speed设为100Mbps(此时autonegotiation被禁止,大大加快进入程序)
2.禁用dhcp, 使用默认IP地址设置(不用等待dhcp配置,加快速度)
先对SDK作简单的调整:
1.关闭保存自动编译
2.显示行数
Vivado新建lwip例程所必须的工程,BD如下:
1. AXI 1G/2.5G Ethernet Subsystem
只需要设置首页,其他默认
2. AXI Direct Memory Access (此IP在自动连线时软件会自动添加!)
3.Concat (一共5个中断通过AXI Interrupt Controller接入Microblaze,一定要全部接入MB中,否则例程不能正常工作)
4.AXI Interrupt Controller
5. AXI Timer (Timer为例程提供节拍)
由AXI 1G/2.5G Ethernet Subsystem IP 引出的引脚连接到RTL8211F芯片
管脚分配约束如下:
#RGMII
set_property IOSTANDARD LVCMOS33 [get_ports reset_rtl_0]
set_property PACKAGE_PIN E21 [get_ports reset_rtl_0]
set_property IOSTANDARD LVCMOS33 [get_ports {rgmii_rtl_0_rd[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {rgmii_rtl_0_rd[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {rgmii_rtl_0_rd[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {rgmii_rtl_0_rd[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports rgmii_rtl_0_rx_ctl]
set_property IOSTANDARD LVCMOS33 [get_ports rgmii_rtl_0_rxc]
set_property PACKAGE_PIN A19 [get_ports {rgmii_rtl_0_rd[3]}]
set_property PACKAGE_PIN A18 [get_ports {rgmii_rtl_0_rd[2]}]
set_property PACKAGE_PIN C20 [get_ports {rgmii_rtl_0_rd[1]}]
set_property PACKAGE_PIN D20 [get_ports {rgmii_rtl_0_rd[0]}]
set_property PACKAGE_PIN C22 [get_ports rgmii_rtl_0_rx_ctl]
set_property PACKAGE_PIN C18 [get_ports rgmii_rtl_0_rxc]
set_property IOSTANDARD LVCMOS33 [get_ports {rgmii_rtl_0_td[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {rgmii_rtl_0_td[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {rgmii_rtl_0_td[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {rgmii_rtl_0_td[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports rgmii_rtl_0_tx_ctl]
set_property IOSTANDARD LVCMOS33 [get_ports rgmii_rtl_0_txc]
set_property PACKAGE_PIN A21 [get_ports {rgmii_rtl_0_td[3]}]
set_property PACKAGE_PIN B21 [get_ports {rgmii_rtl_0_td[2]}]
set_property PACKAGE_PIN A20 [get_ports {rgmii_rtl_0_td[1]}]
set_property PACKAGE_PIN B20 [get_ports {rgmii_rtl_0_td[0]}]
set_property PACKAGE_PIN B22 [get_ports rgmii_rtl_0_tx_ctl]
set_property PACKAGE_PIN C19 [get_ports rgmii_rtl_0_txc]
set_property IOSTANDARD LVCMOS33 [get_ports mdio_rtl_0_mdc]
set_property IOSTANDARD LVCMOS33 [get_ports mdio_rtl_0_mdio_io]
set_property PACKAGE_PIN G21 [get_ports mdio_rtl_0_mdc]
set_property PACKAGE_PIN G22 [get_ports mdio_rtl_0_mdio_io]
BD完成后,Generate Bitstream, 然后File-Export-Export Hardware, File-Launch SDK.
进入SDK后,新建Application Project:
选择lwIP TCP Perf Server:
例程src目录下默认生产不同平台文件,我们可以将没有用的文件删除,最后如下:
platform_mb.c 表示我们使用Microblaze平台
lwiptcp_bsp: 例程的板级支持包。
我们先对支持包进行设置,右键lwiptcp_bsp
黄色部分为需要修改的,即禁用dhcp,phy_link_speed = 100Mbps
因为例程编译后很大,需要加载到DDR3中运行,此时需要设置,右键lwiptcp:
确保例程代码在ddr中,Heap Size和Stack Size需设置大一些,不然最后程序有可能不断重启
点击Generate代替之前的Linker Script
保存,编译生成lwiptcp.elf
重点: 因为为了调试方便,我们指定了100Mbps 网口速度而非默认的autodetect, 所以SDK提供的例程我们不需要作修改即可用在RTL8211F芯片。 当phy_link_speed设置为Autodetect时,
此时我们需要修改lwip211_v1_0源码下的xaxiemacif_physpeed.c文件,添加RTL8211F的配置代码:
代码如下:
1. 先添加定义,因为RTL8211F的idenifier ID固定为0x1c
2. 找到unsigned get_IEEE_phy_speed(XAxiEthernet *xaxiemacp) 函数,添加RTL8211F配置代码, 代码实质工作就是配置8211的相关寄存器。最后这个函数返回autodetect后的Linkspeed. 当我们指定速度时,这个函数时跳过没有执行的。
unsigned get_IEEE_phy_speed(XAxiEthernet *xaxiemacp)
{
u16 phy_identifier;
u16 phy_model;
u8 phytype;
u16 control;
u16 status;
u16 status_speed;
u32 temp_speed;
u16 value;
u32 timeout_counter = 0;
#ifdef XPAR_AXIETHERNET_0_BASEADDR
u32 phy_addr = detect_phy(xaxiemacp);
/* Get the PHY Identifier and Model number */
XAxiEthernet_PhyRead(xaxiemacp, phy_addr, PHY_IDENTIFIER_1_REG, &phy_identifier);
XAxiEthernet_PhyRead(xaxiemacp, phy_addr, PHY_IDENTIFIER_2_REG, &phy_model);
/* Depending upon what manufacturer PHY is connected, a different mask is
* needed to determine the specific model number of the PHY. */
if (phy_identifier == MARVEL_PHY_IDENTIFIER) {
phy_model = phy_model & MARVEL_PHY_MODEL_NUM_MASK;
if (phy_model == MARVEL_PHY_88E1116R_MODEL) {
return get_phy_speed_88E1116R(xaxiemacp, phy_addr);
} else if (phy_model == MARVEL_PHY_88E1111_MODEL) {
return get_phy_speed_88E1111(xaxiemacp, phy_addr);
}
} else if (phy_identifier == TI_PHY_IDENTIFIER) {
phy_model = phy_model & TI_PHY_DP83867_MODEL;
phytype = XAxiEthernet_GetPhysicalInterface(xaxiemacp);
if (phy_model == TI_PHY_DP83867_MODEL && phytype == XAE_PHY_TYPE_SGMII) {
return get_phy_speed_TI_DP83867_SGMII(xaxiemacp, phy_addr);
}
if (phy_model == TI_PHY_DP83867_MODEL) {
return get_phy_speed_TI_DP83867(xaxiemacp, phy_addr);
}
}
else {
if (phy_identifier==PHY_REALTEK_IDENTIFIER){
xil_printf("Start PHY autonegotiation \r\n");
/* 网线插拔检测 */
XAxiEthernet_PhyRead(xaxiemacp, phy_addr, 1, &value); //BMSR register
XAxiEthernet_PhyRead(xaxiemacp, phy_addr, 1, &value); //read twice
if (value & 0x0004) xil_printf("Cable Linked\r\n"); //PHY_LINKED_STATUS
XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);
control |= IEEE_ASYMMETRIC_PAUSE_MASK;
control |= IEEE_PAUSE_MASK;
control |= ADVERTISE_100; //support 100Base FUll and Half
control |= ADVERTISE_10; //support 10Base FUll and Half
XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);
XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,&control);
control |= ADVERTISE_1000;
XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,control);
XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
control |= IEEE_CTRL_AUTONEGOTIATE_ENABLE;
control |= IEEE_STAT_AUTONEGOTIATE_RESTART;
XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
control |= IEEE_CTRL_RESET_MASK;
XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
while (1) {
XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
if (control & IEEE_CTRL_RESET_MASK)
continue;
else
break;
}
XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
xil_printf("Waiting for PHY to complete autonegotiation.\r\n");
while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
//sleep(1);
usleep(500000);
timeout_counter++;
if (timeout_counter == 30) {
xil_printf("Auto negotiation error \r\n");
return 0;
}
XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
}
xil_printf("autonegotiation complete \r\n");
XAxiEthernet_PhyRead(xaxiemacp, phy_addr,0x1A, &status_speed); /* Commercial RTL8211*/
/* if (status_speed & 0x400) { //link ok
temp_speed = status_speed & 0xc000;
if (temp_speed == 0x8000)
return 1000;
else if(temp_speed == 0x4000)
return 100;
else
return 10; */
if (status_speed & 0x04) { //link ok
temp_speed = status_speed & 0x30;
if (temp_speed == 0x20)
return 1000;
else if(temp_speed == 0x10)
return 100;
else
return 10;
}
}
return XST_SUCCESS;
// else {
LWIP_DEBUGF(NETIF_DEBUG, ("XAxiEthernet get_IEEE_phy_speed: Detected PHY with unknown identifier/model.\r\n"));
}
#endif
#ifdef PCM_PMA_CORE_PRESENT
return get_phy_negotiated_speed(xaxiemacp, phy_addr);
#endif
}
返回link speed后,进入configure_IEEE_phy_speed(XAxiEthernet *xaxiemacp, unsigned speed)函数,我们在这个函数添加了配置8211 LED的代码:
#define GREEN_LED 2 // 绿灯是LED2
#define YELLOW_LED 1 // 黄灯是LED1
//配置网口LED灯状态
XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, 31, 0xd04);
temp = 0x0b << (5 * GREEN_LED); // 绿灯表示连接状态
temp |= 0x1b << (5 * YELLOW_LED); // 黄灯表示数据包收发状态
XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, 0x10, temp);
temp = 1 << (YELLOW_LED + 1); // 绿灯不指示EEE节能状态, 插了网线后灯要常亮 // 但黄灯要指示EEE节能状态, 没有数据包时灯要熄灭
XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, 0x11, temp);
XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, 31, 0);
// 插上网线后, 绿灯常亮; 拔掉网线后, 绿灯熄灭
// 链路支持EEE节能: 有数据传输, 黄灯闪烁, 否则熄灭
// 链路不支持EEE节能: 有数据传输, 黄灯闪烁, 否则常亮
回到之前最终生产了lwiptcp.elf,下面进行下载验证:
1. Xilinx - Program FPGA (作用1:将top_wrapper.bit 硬件流文件加载到FPGA中,并把bootloop.elf加载到BRAM用于引导后面的lwiptcp.elf。 所用2:并把两个文件合并生成一个download.bit文件,用于后面的程序固化到外部SPI FLASH中)
2. 右键工程lwiptcp - Run as - Run Configurations
点击Run后,SDK将lwiptcp.el加载到DDR3中并reset FPGA。(因为lwiptcp.elf编译后大小有30.28M,只能加载到DDR中,看之前设置)
因为lwiptcp.elf太大,FPGA reset后需要等待十几秒才能运行。
iperf.exe windows默认没有,需要自己复制到c:\windows目录下(注意这里是第一版本的iperf, iperf3 不能用)
命令: iperf -c 192.168.31.55 -i 5 -t 30 -w 2M
文章来源:https://www.toymoban.com/news/detail-698573.html
实测100Mbps下,带宽只有16.7Mbps, 不知道什么原因。文章来源地址https://www.toymoban.com/news/detail-698573.html
到了这里,关于Artix7 Microblaze下调试SDK官方lwIP RAW Mode TCP Server Application例程(详细说明)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!