Vivado 2019.1
FPGA: Artix7 XC7A100T
DDR3: MT41K256M16TW-107
PHY: RTL8211F(商業(yè)級)
為加快進(jìn)入application,設(shè)置如下:
1.禁用autodetect, phy_link_speed設(shè)為100Mbps(此時autonegotiation被禁止,大大加快進(jìn)入程序)
2.禁用dhcp, 使用默認(rèn)IP地址設(shè)置(不用等待dhcp配置,加快速度)
先對SDK作簡單的調(diào)整:
1.關(guān)閉保存自動編譯
2.顯示行數(shù)
?
?
Vivado新建lwip例程所必須的工程,BD如下:
1. AXI 1G/2.5G Ethernet Subsystem
?只需要設(shè)置首頁,其他默認(rèn)
2. AXI Direct Memory Access (此IP在自動連線時軟件會自動添加!)
?3.Concat (一共5個中斷通過AXI Interrupt Controller接入Microblaze,一定要全部接入MB中,否則例程不能正常工作)
?4.AXI Interrupt Controller
?
?
?5. AXI Timer (Timer為例程提供節(jié)拍)
由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.
進(jìn)入SDK后,新建Application Project:
選擇lwIP TCP Perf Server:
例程src目錄下默認(rèn)生產(chǎn)不同平臺文件,我們可以將沒有用的文件刪除,最后如下:
?platform_mb.c 表示我們使用Microblaze平臺
?lwiptcp_bsp: 例程的板級支持包。
我們先對支持包進(jìn)行設(shè)置,右鍵lwiptcp_bsp
?黃色部分為需要修改的,即禁用dhcp,phy_link_speed = 100Mbps
?因為例程編譯后很大,需要加載到DDR3中運行,此時需要設(shè)置,右鍵lwiptcp:
?確保例程代碼在ddr中,Heap Size和Stack Size需設(shè)置大一些,不然最后程序有可能不斷重啟
?點擊Generate代替之前的Linker Script
?保存,編譯生成lwiptcp.elf
重點: 因為為了調(diào)試方便,我們指定了100Mbps 網(wǎng)口速度而非默認(rèn)的autodetect, 所以SDK提供的例程我們不需要作修改即可用在RTL8211F芯片。 當(dāng)phy_link_speed設(shè)置為Autodetect時,
此時我們需要修改lwip211_v1_0源碼下的xaxiemacif_physpeed.c文件,添加RTL8211F的配置代碼:
?代碼如下:
1. 先添加定義,因為RTL8211F的idenifier ID固定為0x1c
?2. 找到unsigned get_IEEE_phy_speed(XAxiEthernet *xaxiemacp) 函數(shù),添加RTL8211F配置代碼, 代碼實質(zhì)工作就是配置8211的相關(guān)寄存器。最后這個函數(shù)返回autodetect后的Linkspeed. 當(dāng)我們指定速度時,這個函數(shù)時跳過沒有執(zhí)行的。
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");
/* 網(wǎng)線插拔檢測 */
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后,進(jìn)入configure_IEEE_phy_speed(XAxiEthernet *xaxiemacp, unsigned speed)函數(shù),我們在這個函數(shù)添加了配置8211 LED的代碼:
#define GREEN_LED 2 // 綠燈是LED2
#define YELLOW_LED 1 // 黃燈是LED1
//配置網(wǎng)口LED燈狀態(tài)
XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, 31, 0xd04);
temp = 0x0b << (5 * GREEN_LED); // 綠燈表示連接狀態(tài)
temp |= 0x1b << (5 * YELLOW_LED); // 黃燈表示數(shù)據(jù)包收發(fā)狀態(tài)
XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, 0x10, temp);
temp = 1 << (YELLOW_LED + 1); // 綠燈不指示EEE節(jié)能狀態(tài), 插了網(wǎng)線后燈要常亮 // 但黃燈要指示EEE節(jié)能狀態(tài), 沒有數(shù)據(jù)包時燈要熄滅
XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, 0x11, temp);
XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, 31, 0);
// 插上網(wǎng)線后, 綠燈常亮; 拔掉網(wǎng)線后, 綠燈熄滅
// 鏈路支持EEE節(jié)能: 有數(shù)據(jù)傳輸, 黃燈閃爍, 否則熄滅
// 鏈路不支持EEE節(jié)能: 有數(shù)據(jù)傳輸, 黃燈閃爍, 否則常亮
回到之前最終生產(chǎn)了lwiptcp.elf,下面進(jìn)行下載驗證:
1. Xilinx - Program FPGA (作用1:將top_wrapper.bit 硬件流文件加載到FPGA中,并把bootloop.elf加載到BRAM用于引導(dǎo)后面的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中,看之前設(shè)置)
?因為lwiptcp.elf太大,F(xiàn)PGA reset后需要等待十幾秒才能運行。
iperf.exe windows默認(rèn)沒有,需要自己復(fù)制到c:\windows目錄下(注意這里是第一版本的iperf, iperf3 不能用)
命令: iperf -c 192.168.31.55 -i 5 -t 30?-w 2M
文章來源:http://www.zghlxwxcb.cn/news/detail-698573.html
實測100Mbps下,帶寬只有16.7Mbps, 不知道什么原因。文章來源地址http://www.zghlxwxcb.cn/news/detail-698573.html
到了這里,關(guān)于Artix7 Microblaze下調(diào)試SDK官方lwIP RAW Mode TCP Server Application例程(詳細(xì)說明)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!