OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5180|回复: 0

[XILINX] 【正点原子FPGA连载】第三十一章 基于lwip的echo server实验--摘自【正点原子】领航者ZYNQ之嵌入式开发指南_V1.2

[复制链接]

1107

主题

1118

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
4615
金钱
4615
注册时间
2019-5-8
在线时间
1218 小时
发表于 2020-10-19 18:40:21 | 显示全部楼层 |阅读模式
1)实验平台:正点原子领航者ZYNQ开发板
2)平台购买地址:https://item.taobao.com/item.htm?&id=606160108761
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-301505-1-1.html
4)对正点原子FPGA感兴趣的同学可以加群讨论:905624739 点击加入群聊
5)关注正点原子公众号,获取最新资料更新
1.jpg
1120.png

第三十一章 基于lwipecho server实验

随着物联网的兴起,万物互联需要一个强大而又灵活的协议体系,TCP/IP协议得天独厚,而在嵌入式网络设备中,由于硬件资源的限制,需要特殊的实现方式。LWIP作为TCP/IP协议的一种轻量级实现方式,满足了这一要求。本章我们利用SDK软件自带的lwIP Echo Server例程模板,初步了解lwip的使用。本章包括以下几个部分:
1         
1.1        简介
1.2        实验任务
1.3        硬件设计
1.4        软件设计
1.5        下载验证
1.1 简介
1)      TCP/IP协议简介
TCP/IP协议中文名为传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协议、Internet国际互联网络的基础,由网络层的IP协议和传输层的TCP协议组成。TCP/IP定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准。协议采用了4层的层级结构,每一层都呼叫它的下一层所提供的协议来完成自己的需求。通俗而言:TCP负责发现传输的问题,一有问题就发出信号,要求重新传输,直到所有数据安全正确地传输到目的地。而IP是给因特网的每一台联网设备规定一个地址。
TCP/IP协议不是TCP和IP这两个协议的合称,而是指因特网整个TCP/IP协议族。从协议分层模型方面来讲,TCP/IP由四个层次组成:网络接口层、网络层、传输层、应用层。OSI(Open System Interconnection)是开放式系统互连参考模型,该模型将TCP/IP分为七层:物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。TCP/IP模型与OSI模型对比如表1.1.1所示。
表 33.1.1 OSI模型与TCP/IP模块
编号
OSI 模型
TCP/IP 模型
1
应用层
应用层
2
表示层
3
会话层
4
传输层
传输层
5
网络层
网络层
6
数据链路层
网络接口层
7
物理层
2)      LWIP简介
LWIP是瑞典计算机科学院(SICS)的Adam Dunkels等开发的一个小型开源的TCP/IP协议栈,是TCP/IP的一种实现方式。LWIP是轻量级IP协议,有无操作系统的支持都可以运行。LWIP实现的重点是在保持TCP协议主要功能的基础上减少对 RAM的占用,它只需十几KB的RAM和40K左右的ROM就可以运行,这使LWIP协议栈适合在低端的嵌入式系统中使用。关于LWIP的详细信息大家可以去http://savannah.nongnu.org/projects/lwip/这个网站去查阅。
LWIP 的主要特性如下:
•IGMP 协议,用于网络组管理,可以实现多播数据的接收
•Internet协议(IP),包括 IPv4 和 IPv6,支持 IP 分片与重装,包括通过多个网络接口的数据包转发
•用于网络维护和调试的Internet控制消息协议(ICMP)
•用户数据报协议(UDP)
•传输控制协议(TCP)拥塞控制,往返时间(RTT)估计,快速恢复和重传
•DNS,域名解析
•SNMP,简单网络管理协议
•动态主机配置协议(DHCP)
•以太网地址解析协议(ARP)
•AUTOIP,IP 地址自动配置
&#8226PP,点对点协议,支持 PPPoE
我们本次使用的lwip202_v1_2是一个基于开源lwIP库版本2.0.2构建的SDK库(Vivado 2018.3版本)。lwip202_v1_2库为Ethernetlite(axi_ethernetlite)、TEMAC(axi_ethernet)以及千兆以太网控制器和MAC(GigE)内核提供适配器。该库可以在MicroBlaze、ARM Cortex-A9、ARM Cortex-A53和ARM Cortex-R5处理器上运行。Ethernetlite和TEMAC核心适用于MicroBlaze系统。千兆以太网控制器和MAC(GigE)内核仅适用于ARM Cortex-A9(Zynq-7000处理器设备)、ARM Cortex-A53和ARM Cortex-R5系统(Zynq UltraScale+ MPSoC)。
lwip202_v1_2提供二种用户编程接口方式:raw API和socket API。
Raw API:是为高性能和低内存开销而定制的。这种类型的API把网络协议栈和应用程序放在一个进程里,连接网络协议和应用程序的纽带是回调函数,回调函数实际上是一个普通的C函数。为了接收数据,应用程序会首先向协议栈注册一个回调函数,当关联的连接有一个信息到达时,该回调函数就被协议栈调用。这种实现方式即有优点也有缺点。优点是数据的接收和发送不会导致进程的切换,提供了最好的性能,执行速度快,而且消耗的内存资源少;缺点是应用程序无法进行连续运算,因为网络协议的处理和运算是在同一进程中完成的,二者无法并行发生。Raw API是资源较少的嵌入式系统的首选方法,也是在没有操作系统的情况下运行lwIP时唯一可用的API。
Socket API:提供了一个基于open-read-write-close 模块的BSD socket-style接口,需要操作系统。此接口在性能和内存要求方面不如Raw API高效,不适用于小型嵌入式系统,但移植性更好。
本章我们使用无需操作系统(standalone)的RAW API编程接口。
3)       PS的千兆以太网控制器
在介绍PS的千兆以太网控制器之前,我们首先了解下MAC与PHY芯片及GMII与RGMII接口。
以太网卡工作在OSI模型的最后两层,物理层和数据链路层,物理层定义了数据传送与接收所需要的电与光信号、线路状态、时钟基准、数据编码和电路等,并向数据链路层设备提供标准接口。物理层的芯片称之为 PHY。此外PHY还提供了和对端设备连接的重要功能并通过LED灯显示出当前的连接的状态和工作状态。当我们给网卡接入网线的时候,PHY不断发出的脉冲信号检测到对端有设备,它们通过一套标准的语言交流,互相协商并确定连接速度、工作模式、是否采用流控等。通常情况下,协商的结果是两个设备中能同时支持的最大速度和最好的双工模式。这个技术被称为AutoNegotiation,即自协商。
数据链路层则提供寻址机构、数据帧的构建、数据差错检查、传送控制、向网络层提供标准的数据接口等功能。以太网卡中数据链路层的芯片称之为MAC控制器。
MAC控制器与PHY通过MII(MediumIndependent Interface)接口进行连接。MII接口有很多类型,千兆以太网多使用GMII(Gigabit Medium Independent Interface)或RGMII(Reduced Gigabit Media IndependentInterface)接口进行连接。
image004.png

33.1.1 GMII接口
GMII接口提供了8位数据通道,125MHz的时钟速率,从而具有1000Mbps的数据传输速率。除MDC和MDIO外,有24根接口信号线,如图33.1.1所示。
GMII接口主要包括四个部分。一是从MAC层到物理层(PHY)的发送数据接口,二是从物理层到MAC层的接收数据接口,三是从物理层到MAC层的状态指示信号,四是MAC 层和物理层之间传送控制和状态信息的MDIO接口。各部分接口信号说明见下表:
表 33.1.2 GMII接口信号
  
信号名称
  
数量
描述
归类
GTX_CLK
1
发送时钟信号
MAC到PHY的发送数据接口
TXD[7:0]
8
发送数据信号
TX_ER
1
发送错误提示信号
TX_EN
1
发送使能信号
RX_CLK
1
接收时钟信号
PHY到MAC的接收数据接口
RXD[7:0]
8
接收数据信号
RX_ER
1
接收错误提示信号
RX_DV
1
接收数据有效信号
COL
1
冲突检测信号
PHY到MAC的状态指示信号接口
CRS
1
载波侦听信号
MDC
1
Management Clock
MAC和PHY间传送控制和状态信息接口
MDIO
1
Management Data IO
RGMII接口即Reduced GMII,是GMII接口的简化版本。RGMII采用4位数据接口,工作时钟125MHz,并且在上升沿和下降沿同时传输数据,因此传输速率可达1000Mbps。采用 RGMII的目的是降低电路成本,使实现这种接口的器件的引脚数从24个减少到14个(不包括MDC和MDIO),接口信号如下图所示:

33.1.2 RGMII接口
可以看到RGMII接口相对于GMII 接口,在TXD和RXD上总共减少8根数据线。TX_CTL信号线上传送TX_EN和TX_ER两种信息,在TX_CLK的上升沿发送TX_EN,下降沿发送TX_ER;同样的,RX_CTL信号线上传送RX_DV和RX_ER两种信息,在RX_CLK的上升沿发送RX_DV,下降沿发送RX_ER。进一步减少了2根数据线。其他信号同GMII接口。
现在我们来看下PS的千兆以太网控制器(GEM)。PS的千兆以太网控制器实现了与IEEE802.3-2008标准兼容的10/100/1000 Mb/s以太网MAC,能够以上述三种速度在半双工或全双工模式下运行。PS配备两个千兆以太网控制器。每个控制器都可以独立配置,其内部原理图如下:
image006.jpg

33.1.3 以太网控制器
DMA控制器通过AHB总线接口连接到存储器。MAC控制器与FIFO接口的连接为嵌入式处理系统中的分组数据存储提供scatter-gather类型的功能。另外从图 33.1.3中可以看到,如果通过MIO连接至PS端的以太网PHY芯片,则每个控制器使用RGMII接口以节省引脚。如果通过EMIO连接至PL端的以太网PHY芯片,则每个控制器使用GMII接口。
可以通过APB总线访问千兆以太网控制器的寄存器。寄存器用于配置MAC的功能、选择不同的操作模式、以及启用和监控网络管理统计信息。控制器为管理PHY芯片提供MDIO接口,可以从MDIO接口控制PHY芯片。
1.2 实验任务
本章的实验任务是建立PS的以太网的硬件环境,使用SDK软件自带的Lwip Echo Server模板了解LWIP的使用。
1.3 硬件设计
领航者ZYNQ底板上有一个RJ45以太网接口,用于连接以太网线,其原理图如图 33.3.1所示:
image008.jpg

33.3.1 RJ45接口原理图
以太网的数据传输离不开以太网PHY(物理层)芯片的支持。我们的领航者ZYNQ开发板上使用的PHY芯片为Realtek公司的RTL8211E,其原理图如图 33.3.2所示:
image010.jpg

33.3.2 RTL8211E原理图
Realtek RTL8211E是高度集成的以太网收发器,符合 10Base-T、100Base-TX和1000Base-T IEEE 802.3标准,提供了所有必要的物理层功能。RTL8211E采用最先进的 DSP 技术和模拟前端(AFE),实现了交叉检测和自动校正、极性校正、自适应均衡、串音消除、回声消除、定时恢复和纠错等功能,以提供10Mbps、100Mbps或1000Mbps的强大传输和接收能力。
在图 33.3.2中,RTL8211E右侧引脚连接到底板的RJ45接口,左侧引脚通过RGMII接口与PS端相连接。MDC/MDIO接口用来配置RTL8211E。其复位信号与PS的PS_POR_B相连接,在PS的上电复位时同时复位RTL8211E,不需要通过MIO来控制RTL8211E与PS的MIO引脚的连接如图 33.3.3所示。从图 33.3.3可以看到,RTL8211E的RGMII接口通过MIO16-27引脚与PS相连接,MDC/MDIO连接到PS的MIO52-53引脚。
image012.jpg

33.3.3 RTL8821EPS的接口
根据实验任务我们可以画出本次实验的系统框图,如下图所示:
image014.png

33.3.4 系统框图
在图 33.3.4中,UART用于打印程序相关的信息,千兆以太网控制器和MAC(GigE)内核通过MIO与外部以太网进行连接。
step1:创建Vivado工程
本次实验的硬件设计可以在《第一章 Hello World》实验的基础上进行。
1-1 我们先打开《第一章Hello World》实验的Vivado工程,打开后将工程另存为“lwip_echo_server”工程,如下图所示,然后点击“OK”按钮。
image016.jpg

33.3.5 另存为工程为lwip_echo
step2:使用IP Integrator创建Processing System
2-1 在Flow Navigator中,点击IP INTEGRATOR下的Open Block Design,如下图所示:
image018.jpg
33.3.6 打开Block Design
2-2 在打开的下图Diagram窗口,双击打开ZYNQ7 Processing System重定义窗口。
image020.jpg

33.3.7 重定义ZYNQ7 Processing System
2-3 在打开的重定义窗口中,点击左侧的MIO Configuration,在右侧的界面中展开“I/O Peripherals”。勾选“ENET 0”和其下的“MDIO”,在“IO”列选择ENET 0的IO为MIO16…27,MDIO的IO为MIO52…53。因为MIO的Bank1即原理图中的BANK501为1.8V,所以我们选择Bank1 I/O Voltage为LVCOMS 1.8V。另外设置Speed列的速度为“fast”,如下图所示,完成后,点击右下角的“OK”。
image022.jpg

33.3.8 PS以太网接口配置界面
2-4 由于不需要添加其它IP,按Ctrl+S快捷键保存Diagram。此时我们的第二步完成,进入第三步
step3:生成顶层HDL
在sources面板中,右键点击Block Design设计文件“system.bd”,然后依次执行“Generate Output Products”和“Create HDLWrapper”。
step4:生成Bitstream文件并导出到SDK
由于本实验未用到PL部分,所以无需生成Bitstream文件,只需导出到SDK即可。如果使用到PL,则需要添加引脚约束以及对该系统进行综合、实现并生成Bitstream文件。
4-1 导出硬件。
在菜单栏中选择 File> Export > Export hardware。
并在弹出的对话框中,取消勾选“Includebitstream”,直接点击“OK”按钮。
因为是在前一工程的基础上建立的,还保留着前一工程的结果,所以会弹出“Module Already Exported”对话框,我们点击“Yes”按钮。
4-2 硬件导出完成后,选择菜单File->Launch SDK,启动SDK开发环境。
1.4 软件设计
首先删除前一实验的工程。下面我们开始第五步——创建应用工程。
step5:在SDK中创建应用工程
5-1 在菜单栏中选择File->New->Application Project, 新建一个SDK应用工程。
5-2 在弹出的图 33.4.1所示界面中,输入工程名“lwip_echo_server”。
在该页面中,我们需要确认HardwarePlatform一栏中选择的是本次实验所导出的硬件平台system_wrapper_hw_platform_1。另外,为了方便以后能在此工程的基础上创建其他工程,我们将创建的BSP工程名称修改为一个不与应用工程相关的名称,此处修改“Create New”后面的方框内容为“lwip _server_bsp”,其它选项保持默认,点击“Next”。

33.4.1 创建工程
5-3 选择“lwIP Echo Server”工程模版,然后点击“Finish”按钮,如图 33.4.2所示。
lwIP Echo Server应用程序提供了如何使用轻量级IP堆栈(lwIP)的简单演示。此应用程序将领航者开发板MAC地址设置为00:0a:35:00:01:02,默认使用DHCP获取动态IP地址,如果DHCP失败,则使用默认设置的静态IPv4地址192.168.1.10或IPv6地址FE80:0:0:0:20​​A:35FF:FE00:102。服务器在端口7处侦听输入,并简单地回传发送到该端口的任何数据。
这里简单的介绍下DHCP。DHCP(Dynamic Host Configuration Protocol)即动态主机配置协议,通常应用在大型的局域网络环境中,主要作用是集中的管理、分配IP地址,使网络环境中的主机动态的获得IP地址、Gateway地址、DNS服务器地址等信息,并能够提升地址的使用率。
image026.jpg

33.4.2 选择“lwIP Echo Server”模版
5-4 展开lwip_echo_server应用工程目录下的src目录,可以看到很多源文件,如图33.4.4所示,其中大多是平台相关的文件(platform开头的文件)。下面我们简单的介绍下各文件的作用。
echo.c:Echo服务的的主要实现代码。
i2c_access.c:IIC访问PHY的功能实现,本实验不用。
iic_phyreset.c:IIC复位PHY,本使用不用。
main.c:main函数所在文件。
platform_config.h:平台配置相关文件,主要是宏定义所使用的平台。
我们打开“platform_config.h”文件,内容如下:
image028.jpg

33.4.3 platform_config.h文件内容
可以看到宏定义了 PLATFORM_ZYNQ,也就是说本实验是与ZYNQ平台相关的。所以本实验需要的是platform_zynq.c文件,而以下的与其它平台相关的platform_mb.c、platform_ppc.c、platform_zynqmp.c、platform.c都无需使用。
platform_config.h是基于硬件设计生成的。
sfp.c和si5324.c分别用于sfp PHY和si5324芯片,用于官方特定的开发板,与我们使用的领航者开发板不相关。

image030.jpg
]图 33.4.4 src目录
5-5 为了方便分析,我们将src文件夹与本实验不相关的平台文件删除,删除后的src文件夹内容如下图所示:
image031.png

33.4.5 删除不相关文件后的src文件夹内容
5-6 现在我们打开main.c文件,为了方便分析源代码,在main.c文件中将带有下图箭头所指的预编译指令删除。
image033.jpg

33.4.6 删除不需要的预编译指令
删除不适用的预编译指令后的main.c代码如下:
  1. #include <stdio.h>
  2. #include "xparameters.h"
  3. #include "netif/xadapter.h"
  4. #include "platform.h"
  5. #include "platform_config.h"
  6. #include "xil_printf.h"
  7. #include "lwip/tcp.h"
  8. #include "xil_cache.h"
  9. #if LWIP_IPV6==1
  10. #include "lwip/ip.h"
  11. #else
  12. #if LWIP_DHCP==1
  13. #include "lwip/dhcp.h"
  14. #endif
  15. #endif

  16. //函数声明
  17. void print_app_header();
  18. int start_application();
  19. int transfer_data();
  20. void tcp_fasttmr(void);
  21. void tcp_slowtmr(void);
  22. void lwip_init();

  23. #if LWIP_IPV6==0
  24. #if LWIP_DHCP==1
  25. extern volatile int dhcp_timoutcntr;
  26. err_t dhcp_start(struct netif *netif);
  27. #endif
  28. #endif

  29. extern volatile int TcpFastTmrFlag;
  30. extern volatile int TcpSlowTmrFlag;
  31. static struct netif server_netif;
  32. struct netif *echo_netif;

  33. #if LWIP_IPV6==1
  34. void print_ip6(char *msg, ip_addr_t *ip)
  35. {
  36.      print(msg);
  37.      xil_printf("%x:%x:%x:%x:%x:%x:%x:%x\n\r",
  38.              IP6_ADDR_BLOCK1(&ip->u_addr.ip6),
  39.              IP6_ADDR_BLOCK2(&ip->u_addr.ip6),
  40.              IP6_ADDR_BLOCK3(&ip->u_addr.ip6),
  41.              IP6_ADDR_BLOCK4(&ip->u_addr.ip6),
  42.              IP6_ADDR_BLOCK5(&ip->u_addr.ip6),
  43.              IP6_ADDR_BLOCK6(&ip->u_addr.ip6),
  44.              IP6_ADDR_BLOCK7(&ip->u_addr.ip6),
  45.              IP6_ADDR_BLOCK8(&ip->u_addr.ip6));
  46. }
  47. #else
  48. void print_ip(char *msg, ip_addr_t *ip)
  49. {
  50.      print(msg);
  51.      xil_printf("%d.%d.%d.%d\n\r", ip4_addr1(ip), ip4_addr2(ip),
  52.              ip4_addr3(ip), ip4_addr4(ip));
  53. }

  54. void print_ip_settings(ip_addr_t *ip, ip_addr_t *mask, ip_addr_t *gw)
  55. {
  56.      print_ip("BoardIP: ", ip);
  57.      print_ip("Netmask: ", mask);
  58.      print_ip("Gateway: ", gw);
  59. }
  60. #endif

  61. int main()
  62. {
  63. #if LWIP_IPV6==0
  64.      ip_addr_t ipaddr, netmask, gw;
  65. #endif
  66.      //设置领航者开发板的MAC地址
  67.      unsignedchar mac_ethernet_address[] =
  68.      { 0x00, 0x0a, 0x35, 0x00, 0x01, 0x02 };

  69.      echo_netif = &server_netif;

  70.      init_platform();

  71. #if LWIP_IPV6==0
  72. #if LWIP_DHCP==1
  73.      ipaddr.addr = 0;
  74.      gw.addr = 0;
  75.      netmask.addr = 0;
  76. #else
  77.      //设置静态IP地址
  78.      IP4_ADDR(&ipaddr,  192, 168,   1, 10);
  79.      IP4_ADDR(&netmask, 255, 255, 255,  0);
  80.      IP4_ADDR(&gw,      192, 168,   1,  1);
  81. #endif
  82. #endif
  83.      print_app_header();
  84.      lwip_init();

  85. #if (LWIP_IPV6 == 0)
  86.      //添加以太网MAC
  87.      if (!xemac_add(echo_netif, &ipaddr, &netmask,
  88.                          &gw, mac_ethernet_address,
  89.                         PLATFORM_EMAC_BASEADDR)) {
  90.          xil_printf("Erroradding N/W interface\n\r");
  91.          return -1;
  92.      }
  93. #else
  94.      if (!xemac_add(echo_netif, NULL, NULL, NULL, mac_ethernet_address,
  95.                          PLATFORM_EMAC_BASEADDR)) {
  96.          xil_printf("Erroradding N/W interface\n\r");
  97.          return -1;
  98.      }
  99.      echo_netif->ip6_autoconfig_enabled = 1;
  100.      netif_create_ip6_linklocal_address(echo_netif, 1);
  101.     netif_ip6_addr_set_state(echo_netif, 0, IP6_ADDR_VALID);
  102.      print_ip6("\n\rBoardIPv6 address ", &echo_netif->ip6_addr[0].u_addr.ip6);
  103. #endif
  104.      netif_set_default(echo_netif);

  105.      //启用中断
  106.      platform_enable_interrupts();

  107.      //指定网络是否已启动
  108.      netif_set_up(echo_netif);

  109. #if (LWIP_IPV6 == 0)
  110. #if (LWIP_DHCP==1)
  111.      //创建新的DHCP客户端。
  112.      dhcp_start(echo_netif);
  113.      dhcp_timoutcntr = 24;

  114.      while(((echo_netif->ip_addr.addr) == 0) && (dhcp_timoutcntr > 0))
  115.          xemacif_input(echo_netif);

  116.      if (dhcp_timoutcntr <= 0) {
  117.          if ((echo_netif->ip_addr.addr) == 0) {
  118.              xil_printf("DHCPTimeout\r\n");
  119.              xil_printf("Configuringdefault IP of 192.168.1.10\r\n");
  120.              IP4_ADDR(&(echo_netif->ip_addr),  192, 168,   1, 10);
  121.              IP4_ADDR(&(echo_netif->netmask), 255, 255, 255,  0);
  122.              IP4_ADDR(&(echo_netif->gw),      192, 168,   1,  1);
  123.          }
  124.      }

  125.      ipaddr.addr = echo_netif->ip_addr.addr;
  126.      gw.addr = echo_netif->gw.addr;
  127.      netmask.addr = echo_netif->netmask.addr;
  128. #endif
  129.      print_ip_settings(&ipaddr, &netmask, &gw);
  130. #endif
  131.      //启动应用程序
  132.      start_application();

  133.      //接收和处理数据包
  134.      while (1) {
  135.          if (TcpFastTmrFlag) {
  136.              tcp_fasttmr();
  137.              TcpFastTmrFlag = 0;
  138.          }
  139.          if (TcpSlowTmrFlag) {
  140.              tcp_slowtmr();
  141.              TcpSlowTmrFlag = 0;
  142.          }
  143.          xemacif_input(echo_netif);
  144.          transfer_data();
  145.      }
  146.      cleanup_platform();
  147.      return 0;
  148. }
复制代码

可以看到代码中有很多的#if LWIP_IPV6==0和#if LWIP_DHCP==1这类预编译指令,这是因为lwip即支持IPv4也支持IPv6,IPv4和DHCP默认支持。如果想重新配置lwip如取消DHCP,可以通过以下方式重配置lwip。
鼠标右键点击“lwip_server_bsp”,在弹出的菜单中选择“Board Support Package Settings”,如下图所示:
image035.jpg

33.4.7 Board Support Package Settings
在弹出的界面中点击左侧standalone下的lwip202,右侧就是lwip的配置面板。如下图所示,箭头所指的两处分别是配置启用DHCP和使能IPv6,可以看到,dhcp默认为true,ipv6默认为false。
image037.jpg

33.4.8 lwip的配置面板
main函数可以说是使用lwip的一个标准函数,可以在不修改main函数的情况下就可实现其它的应用功能。main函数主要完成以下功能:
1)       在代码的73行设置领航者开发板的MAC地址为00:0a:35:00:01:02。
2)       通过调用init_platform函数配置定时器和建立中断以初始化平台,定时器产生周期性中断,周期为250ms。
3)       调用lwip_init函数完成对lwip协议栈的初始化,代码第93行。
4)       初始化lwIP后,使用xemac_add函数添加以太网MAC到协议栈中。
5)       使用platform_enable_interrupts函数使能中断和启动定时器。
6)       从代码第125~139行,启动DHCP服务获取动态IP地址,如果超时未获取到动态IP地址,则使用默认的静态IP设置:
IP Address: 192.168.1.10
Netmask : 255.255.255.0
Gateway : 192.168.1.1
我们也可以根据需要修改代码第135~137行的值,从而使用不同的静态IP地址。
7)       start_application函数是用户应用函数,当我们使用lwip实现不同的应用功能时,可以在保持main函数不变的情况下,修改start_application函数的实现即可。本实验的start_application函数在echo.c文件中定义,该函数创建了一个TCP服务并设定了对应该服务的回调函数。当一个TCP连接请求被接收时,回调函数对客户端发送来的数据原封不动的发送回去,从而实现echo服务器的功能。由于本实验的目的在于初步了解lwip的使用,对于涉及到的TCP协议的使用,我们将在下一章讲解,本实验我们不多做介绍。
8)       程序进入while(1)循环执行数据包接收操作,以及它需要执行的任何其他特定于应用程序的操作。TcpFastTmrFlag和TcpSlowTmrFlag是TCP TX处理所必需的,定时器中断分别以250ms和500ms的周期来改变这两个标志位。数据包接收函数xemacif_input处理由中断处理程序接收的数据包,并将它们传递给lwIP,然后lwIP为每个接收到的数据包调用适当的回调处理程序。transfer_data函数无实际意义,可以删除。
5-7 程序修改完成后,按快捷键Ctrl+S保存main.c文件,工具会自动进行编译。编译完成后控制台(Console)中会出现提示信息“Build Finished”,同时在应用工程的Binaries目录下可以看到生成的elf文件。
1.5 下载验证
首先我们将下载器与领航者底板上的JTAG接口连接,下载器另外一端与电脑连接。然后使用Mini USB连接线将USB UART接口与电脑连接,用于串口通信。使用网线一端连接领航者开发板的以太网接口,另一端与电脑或路由器连接。最后连接开发板的电源,并打开电源开关。如下图所示:
image039.jpg

33.5.1领航者ZYNQ开发板实物图
现在进入最后一步。
step6:板级验证
6-1 在SDK软件的下方的SDK Terminal窗口中点击右上角的加号连接串口。
6-2 下载程序。
6-3 可以看到串口打印的结果如下:
image041.jpg

图 33.5.2 显示打印结果
在打印出“link speedfor phy address 1: 1000”后要等一段时间进行DHCP服务。因为我们将领航者开发板的以太网接口与电脑进行连接,所以出现了DHCP Timeout,开发板的IP地址为默认设置的静态IP地址192.168.1.10。如果和路由器进行连接,开发板的IP则是由DHCP获取的动态IP设置。TCP应答服务的端口号为7。另外需要说明的是串口打印的“TCP packets sent to port 6001 will be echoed back”可能是该模板最初版本使用的是6001端口,后面更新的时候使用了端口7,而该语句没有修改或删除,所以这是无意义的语句,可以找到print_app_header函数从而删除该语句。
在使用静态IP地址时,需要确保同网段内没有主机使用192.168.1.10 的IP地址,否则会造成IP冲突。可以在开发板未上电前或未下载程序前在CMD里输入“ping 192.168.1.10”命令查看是否能ping通,如果能ping通,说明网络中有此IP地址,此时需要更改静态IP地址为其他值,如192.168.1.123等。
6-4 我们在电脑端打开网络调试助手,设置协议类型为:TCP Client,服务器IP地址为串口打印的地址,此处为:192.168.1.10,服务器端口号为:7,然后点击连接,即可连上开发板的 TCP Sever,如下图所示:
image043.jpg

33.5.3 电脑端网络调试助手TCP Client测试界面
6-5 本实验除了可以使用网络调试助手软件外,还可以使用telnet。
我们打开电脑的CMD(按win+r键后输入cmd),输入“telnet192.168.1.10 7”,如下图所示:
image045.jpg

33.5.4 进行telnet连接
回车后,进入下图所示界面:
image047.jpg

33.5.5 连接成功后的界面
如果回车后出现像下图所示界面所示“telnet不是内部或外部命令,也不是可运行的程序或批处理文件”,则表明未开启Windows的telnet客户端功能,开启方式见6-5。
image049.jpg

33.5.6 未启用telnet客户端时的界面
此时我们按键盘上的字母和数字键,如123abc,控制台显示如下:
image051.jpg

33.5.7 控制台显示
可以看到除了1只有一个外,其它字符都显示两个,一个是我们按下的,另一个是开发板的lwip echo server应答的。可见功能基本正确,不过从使用上看还是有问题的,一是第一次按下的字符没有回显;二是不能输入字符串,这些问题主要是windows自带的telnet的问题。如果使用第三方提供的telnet工具,例如使用Win10系统的读者可以开启WSL,从而使用linux系统提供的telnet功能进行连接,如下图(通过WSL使用Ubuntu系统):
image052.png

33.5.8  功能完全正常
可以看到一点问题也没有。按“Ctrl+]”可以退出输入界面,然后输入“quit”即可退出telnet连接。
注:Telnet 协议是TCP/IP 协议族中的一员,是 Internet 远程登录服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工作的能力。在终端使用者的电脑上使用telnet 程序,用它连接到服务器。终端使用者可以在telnet程序中输入命令,这些命令会在服务器上运行,就像直接在服务器的控制台上输入一样。可以在本地就能控制服务器。
6-6 下面我们介绍一下如何开启Windows的telnet客户端功能。在Win10或Win7系统中,按“Win+r”快捷键后,在下图所示界面中输入“control”。
image054.jpg

33.5.9 打开控制面板界面
进入下图所示控制面板界面,将查看方式设置为“类别”,单击“程序”下的“卸载程序”,如下图所示:
image064.jpg

33.5.10 点击进入“程序和功能”界面
在弹出的界面中,单击“启用或关闭Windows功能”,如下图所示:
image066.jpg

33.5.11 点击“启用或关闭Windows功能”
在弹出的“Windows功能”界面中,找到“Telnet Client”,并勾选,如下图所示:
image060.jpg

33.5.12 勾选telnet client
单击确定后,如果出现“Windows需要重启电脑才能完成安装所请求的更改”字样,重新启动电脑即可,至此,Windows的telnet客户端服务已启用。
此时我们进行telnet连接会连接成功,但也有部分电脑会出现下图所示现象:
image062.jpg

33.5.13 无法连接
出现这种情况是因为本地连接(Win10为以太网)设置有问题,需要重新设置。在控制面板界面,单击“网络和Internet”下的“查看网络状态和任务”,如下图所示:

33.5.14 打开“查看网络和状态”
进入下图所示界面:

33.5.15 更改适配器设置
点击箭头所指的“更改适配器设置”,进入下图所示界面:
image068.jpg
33.5.16 打开属性界面
点击“以太网”(或者本地连接,如果有)后出现“更改此连接的设置”,点击“更改此连接的设置”,进入“属性”界面,点击“Internet协议版本4(TCP/IPv4)”,如下图所示:
image070.jpg

33.5.17 进入IPv4设置
进入下图所示界面后,按下图的设置进行修改。
image072.jpg

33.5.18 设置IPv4
经过这些设置后,基本上就可以使用telnet了。
至此,本实验完成。



正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-10-3 13:24

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表