ETH_PHY-Lwip 以太网通信

1、TCP/IP 协议栈

  标准 TCP/IP 协议是用于计算机通信的一组协议,通常称为 TCP/IP 协议栈,通俗讲就是符合以太网通信要求的代码集合,一般要求它可以实现每个层对应的协议,比如应用层的 HTTP、 FTP、 DNS、 SMTP 协议,传输层的 TCP、 UDP 协议、网络层的 IP、ICMP 协议等等。关于 TCP/IP 协议详细内容推荐阅读《TCP-IP 详解》和《用 TCP/IP 进行网际互连》理解。

  TCP/IP 协议栈是一系列网络协议的总和,构成网络通信的核心骨架,定义了电子设备如何连入因特网以及数据如何在它们之间进行传输。该协议采用 4 层结构,分别是应用层、传输层、网络层和网络接口层,每一层都使用下一层提供的协议来完成自己的需求。由于大部分时间都在应用层工作,下层的事情不用操心。此外,网络协议体系本身很复杂庞大,入门门槛高,因此很难搞清楚 TCP/IP 的工作原理。如果读者想深入了解 TCP/IP 协议栈的工作原理,建议阅读《计算机网络书籍》。

  Windows 操作系统、 UNIX 类操作系统都有自己的一套方法来实现 TCP/IP 通信协议,它们都提供非常完整的 TCP/IP 协议。对于一般的嵌入式设备,受制于硬件条件没办法支持使用在 Window 或 UNIX 类操作系统的运行的 TCP/IP 协议栈,一般只能使用简化版本的TCP/IP 协议栈,目前开源的适合嵌入式的有 uIP、 TinyTCP、 uC/TCP-IP、 LwIP 等等。其中LwIP 是目前在嵌入式网络领域被讨论和使用广泛的协议栈。

  1.1 、为什么需要协议栈

  物理层主要定义物理介质性质, MAC 子层负责与物理层进行数据交接,这两部分是与硬件紧密联系的,就嵌入式控制芯片来说,很多都内部集成了 MAC 控制器,完成 MAC 子层功能,所以依靠这部分功能是可以实现两个设备数据交换,而时间传输的数据就是 MAC数据包,发送端封装好数据包,接收端则解封数据包得到可用数据,这样的一个模型与使用 USART 控制器实现数据传输是非常类似的。但如果将以太网运用在如此基础的功能上,完全是大材小用,因为以太网具有传输速度快、可传输距离远、支持星型拓扑设备连接等等强大功能。功能强大的东西一般都会用高级的应用,这也是设计者的初衷。

  使用以太网接口的目的就是为了方便与其它设备互联,如果所有设备都约定使用一种互联方式,在软件上加一些层次来封装,这样不同系统、不同的设备通讯就变得相对容易了。而且只要新加入的设备也使用同一种方式,就可以直接与之前存在于网络上的其它设备通讯。这就是为什么产生了在 MAC 之上的其它层次的网络协议及为什么要使用协议栈的原因。又由于在各种协议栈中 TCP/IP 协议栈得到了最广泛使用, 所有接入互联网的设备都遵守 TCP/IP 协议。 所以,想方便地与其它设备互联通信,需要提供对 TCP/IP 协议的支持。

  1.2、互联网网络协议的分层模型

  TCP/IP 是一个庞大的协议族,它是众多网络协议的集合,包括: ARP、 IP、 ICMP、UDP、 TCP、 DNS、 DHCP、 HTTP、 FTP、 MQTT 等等。这些协议按照功能,可以被划分为几个不同的层次, HTTP、 FTP、 MQTT等它们隶属于应用层。那么 TCP/IP 为什么需要分层,分层又是依靠什么依据呢?

  通信至少是两个设备的事,需要相互兼容的硬件和软件支持,我们称之为通信协议。以太网通信在结构比较复杂,国际标准组织将整个以太网通信结构制定了 OSI 模型,总共分层七个层,分别为应用层、表示层、会话层、传输层、网络层、数据链路层以及物理层,每个层功能不同,通信中各司其职,整个模型包括硬件和软件定义。 OSI 模型是理想分层,一般的网络系统只是涉及其中几层。

  TCP/IP 是互联网最基本的协议,是互联网通信使用的网络协议,由网络层的 IP 协议和传输层的 TCP 协议组成。 TCP/IP 只有四个分层,分别为应用层、传输层、网络层以及网络访问层。虽然 TCP/IP 分层少了,但与 OSI 模型是不冲突的,它把 OSI 模型一些层次整合一起的,本质上可以实现相同功能。

  实际上,还有一个 TCP/IP 混合模型,分为五个层,它实际与 TCP/IP 四层模型是相通的,只是把网络访问层拆成数据链路层和物理层。这种分层方法对我们学习理解更容易。

  设计网络时,为了降低网络设计的复杂性,对组成网络的硬件、软件进行封装、分层,这些分层即构成了网络体系模型。在两个设备相同层之间的对话、通信约定,构成了层级协议。设备中使用的所有协议加起来统称协议栈。 在这个网络模型中,每一层完成不同的任务,都提供接口供上一层访问。而在每层的内部,可以使用不同的方式来实现接口,因而内部的改变不会影响其它层。

  在 TCP/IP 混合参考模型中,数据链路层又被分为 LLC 层(逻辑链路层)和 MAC 层(媒体介质访问层)。目前,对于普通的接入网络终端的设备, LLC 层和 MAC 层是软、硬件的分界线。如 PC 的网卡主要负责实现参考模型中的 MAC 子层和物理层,在 PC 的软件系统中则有一套庞大程序实现了 LLC 层及以上的所有网络层次的协议。

  由硬件实现的物理层和 MAC 子层在不同的网络形式有很大的区别,如以太网和 Wi-Fi,这是由物理传输方式决定的。但由软件实现的其它网络层次通常不会有太大区别,在 PC上也许能实现完整的功能, 一般支持所有协议,而在嵌入式领域则按需要进行裁剪。

  TCP/IP 协议栈中不同协议所完成的功能是不一样的, 某些协议的实现要依赖于其它协议,依据这种依赖关系,可以将协议栈分层。在图 1-1 中,低层协议为相邻的上层协议提供服务,是上层协议得以实现的基础。

  其中,物理层(PHY)规定了传输信号所需要的物理电平、介质特征;链路层( MAC)规定了数据帧能被网卡接收的条件,最常见的方式是利用网卡的 MAC 地址,发送方会在欲发送的数据帧的首部加上接收方网卡的 MAC 地址信息,接收方只有监听到属于自己的MAC 地址信息后,才会去接收并处理该数据; 每台网络设备都应该有自己的网络地址, 网络层规定了主机的网络地址该如何定义, 以及如何在网络地址和 MAC 地址之间进行映射,即 ARP 协议;网络层实现了数据包在主机之间的传递, 而一台主机内部可能运行着多个网络程序,传输层可以区分数据包是属于哪一个应用程序的, 可以说传输层实现了数据包端到端的传递。另外, 数据包在传输过程中可能会出现丢包、乱序和重复的现象,网络层并没有提供应对这些错误的机制, 而传输层可以解决这些问题,如 TCP 协议; 应用层以下的工作完成了数据的传递工作,应用层则决定了你如何应用和处理这些数据,之所以会有许多的应用层协议, 是因为互联网中传递的数据种类很多、差异很大、应用场景十分多样。

  TCP/IP 协议栈是一个分层结构的模型,每一层负责不同的网络功能。整个协议栈可以被分为四层,从上到下分别是:应用层、传输层、网络层和网络接口层。

image

  (1)应用层:这是最顶层,负责处理特定的应用程序细节。在这一层,用户的数据被处理和解释。一些常见的应用层协议包括 HTTP、 FTP、 SMTP 和 DNS 等。
  (2)传输层:这一层负责数据包的分割、打包以及传输控制,确保数据能够可靠、有序地到达目的地。主要的传输层协议有 TCP 和 UDP。
  (3)网络层:负责确定数据包的路径从源到目的地。这一层的主要协议是 IP( InternetProtocol),它负责在主机之间发送和接收数据包。
  (4)网络接口层:这是最底层,负责将数据转换为可以在物理媒介上发送的信号。这一层的协议涉及到如何将数据帧封装在数据链路层,以便在网络上进行传输。
  每一层都使用下一层提供的服务,同时对上一层提供服务。这种分层结构使得协议栈更加灵活,易于扩展和维护。 不同层次上的协议一起工作,协调数据在计算机网络中的传输,使得不同的计算机能够相互通信。
  需要注意的是, TCP/IP 协议栈和传统的 OSI 模型并不完全对应。 TCP/IP 协议栈是一个简化的模型,强调了实际的协议实现和因特网的实际运作方式。相比之下, OSI 模型更加全面和理想化,它提供了一个框架来描述不同系统之间的交互方式。 下图是 IOS 协议栈与 TCP/IP 协议栈分层架构的对比图。

  ISO/OSI 分层模型也是一个分层结构,包括七个层次,从上到下分别是:应用层、表示层、会话层、传输层、网络层、数据链路层和物理层。虽然 ISO/OSI 模型为不同的系统之间的通信提供了一个理论框架,但 TCP/IP 协议栈更侧重于实际的协议实现和因特网的实际运作方式。注意:网络技术的发展并不是遵循严格的 ISO/OSI 分层概念。实际上现在的互联网使用的是TCP/IP 体系结构有时已经演变成为如下图所示那样,即某些应用程序可以直接使用 IP 层,或甚至直接使用最下面的网络接口层。

image

  无论那种表示方法, TCP/IP 模型各个层次都分别对应于不同的协议。 TCP/IP 协议栈负责确保网络设备之间能够通信。它是一组规则,规定了信息如何在网络中传输。 其中,这些协议都分布在应用层,传输层和网络层,网络接口层是由硬件来实现。如 Windows 操作系统包含了 CBISC 协议栈,该协议栈就是实现了 TCP/IP 协议栈的应用层,传输层和网络层的功能,网络接口层由网卡实现,所以 CBISC 协议栈和网卡构建了网络通信的核心骨架。因此,无论哪一款以太网产品,都必须符合 TCP/IP 体系结构,才能实现网络通信。注意:路由器和交换机等相关网络设备只实现网络层和网络接口层的功能。

  1.3、各网络层的功能

  用以太网和 Wi-Fi 作例子,它们的 MAC 子层和物理层有较大的区别,但在 MAC 之上的 LLC 层、网络层、传输层和应用层的协议,是基本上同的,这几层协议由软件实现,并对各层进行封装。根据 TCP/IP 协议,各层的要实现的功能如下:

  LLC 层: 处理传输错误;调节数据流,协调收发数据双方速度,防止发送方发送得太快而接收方丢失数据。主要使用数据链路协议。
  网络层: 本层也被称为 IP 层。 LLC 层负责把数据从线的一端传输到另一端,但很多时候不同的设备位于不同的网络中(并不是简单的网线的两头)。此时就需要网络层来解决子网路由拓扑问题、路径选择问题。在这一层主要有 IP 协议、 ICMP 协议。
  传输层: 由网络层处理好了网络传输的路径问题后,端到端的路径就建立起来了。传输层就负责处理端到端的通讯。在这一层中主要有 TCP、 UDP 协议
  应用层: 经过前面三层的处理,通讯完全建立。应用层可以通过调用传输层的接口来编写特定的应用程序。而 TCP/IP 协议一般也会包含一些简单的应用程序如 Telnet 远程登录、FTP 文件传输、 SMTP 邮件传输协议。

  实际上,在发送数据时,经过网络协议栈的每一层,都会给来自上层的数据添加上一个数据包的头,再传递给下一层。在接收方收到数据时,一层层地把所在层的数据包的头去掉,向上层递交数据。

  当用户发送数据时, 将数据向下交给传输层,这是处于应用层的操作, 应用层可以通过调用传输层的接口来编写特定的应用程序。而 TCP/IP 协议一般也会包含一些简单的应用程序如 Telnet 远程登录、 FTP 文件传输、 SMTP 邮件传输协议等。 传输层会在数据前面加上传输层首部(此处以 TCP 协议为例, 图 1-2 的传输层首部为 TCP 首部,也可以是 UDP首部) , 然后向下交给网络层。 同样地,网络层会在数据前面加上网络层首部(IP 首部) ,然后将数据向下交给链路层, 链路层会对数据进行最后一次封装,即在数据前面加上链路层首部(此处使用以太网接口为例) ,然后将数据交给网卡。最后,网卡将数据转换成物理链路上的电平信号,数据就这样被发送到了网络中。数据的发送过程,可以概括为TCP/IP 的各层协议对数据进行封装的过程,如图 1-2 所示。
  当设备的网卡接收到某个数据包后, 它会将其放置在网卡的接收缓存中,并告知TCP/IP 内核。 然后 TCP/IP 内核就开始工作了,它会将数据包从接收缓存中取出,并逐层解析数据包中的协议首部信息,并最终将数据交给某个应用程序。数据的接收过程与发送过程正好相反,可以概括为 TCP/IP 的各层协议对数据进行解析的过程。

  TCP/IP 协议栈的封包和拆包是指在网络通信中,将数据按照一定的协议和格式进行封装和解析的过程。
  在 TCP/IP 协议栈中,数据封装是指在发送端将数据按照协议规定的格式进行打包,以便在网络中进行传输。在应用层的数据被封装后,会经过传输层、网络层和网络接口层的处理,最终转换成可以在物理网络上传输的帧格式。数据封装的过程涉及到对数据的分段、压缩、加密等操作,以确保数据能够可靠、安全地传输到目的地, 下图描述的是封包处理流程。

image

  数据拆包是指接收端收到数据后,按照协议规定的格式对数据进行解析和处理,还原出原始的数据。在接收到数据后,接收端会按照协议规定的层次从下往上逐层处理数据,最终将应用层的数据还原出来。数据拆包的过程涉及到对数据的重组、解压缩、解密等操作,以确保数据能够被正确地解析和处理,下图描述的是拆包处理流程。

image

   需要注意的是, TCP/IP 协议栈的封包和拆包过程涉及到多个层次和协议的处理,需要按照协议规定的格式和顺序进行操作。在实际应用中,需要根据具体的情况选择合适的协议和格式来满足不同的需求。同时,为了保证数据的安全和可靠性,还需要采取相应的加密、压缩等措施,以避免数据被篡改或损坏。

  如今大部分电子设备都能以不同的方式接入互联网(Internet),在家庭中 PC 常见的互联网接入方式是使用路由器(Router)组建小型局域网(LAN),利用互联网专线或者调制调解器(modem)经过电话线网络,连接到互联网服务提供商(ISP),由互联网服务提供商把用户的局域网接入互联网。而企业或学校的局域网规模较大,常使用交换机组成局域网,经过路由以不同的方式接入到互联网中。

2、以太网

  以太网(Ethernet)是互联网技术的一种,由于它是在组网技术中占的比例最高,很多人直接把以太网理解为互联网。

  以太网是指遵守 IEEE 802.3 标准组成的局域网,由 IEEE 802.3 标准规定的主要是位于参考模型的物理层(PHY)和数据链路层中的介质访问控制子层(MAC)。在家庭、企业和学校所组建的 PC 局域网形式一般也是以太网,其标志是使用水晶头网线来连接(当然还有其它形式)。 IEEE 还有其它局域网标准,如 IEEE 802.11 是无线局域网,俗称 Wi-Fi。 IEEE802.15 是个人域网,即蓝牙技术,其中的 802.15.4 标准则是 ZigBee 技术。

  现阶段,工业控制、环境监测、智能家居的嵌入式设备产生了接入互联网的需求,利用以太网技术,嵌入式设备可以非常容易地接入到现有的计算机网络中。

  2.1、 物理PHY

  在物理层,由 IEEE 802.3 标准规定了以太网使用的传输介质、传输速度、数据编码方式和冲突检测机制,物理层一般是通过一个 PHY 芯片实现其功能的。

  (1)传输介质

  传输介质包括同轴电缆、双绞线(水晶头网线是一种双绞线)、光纤。根据不同的传输速度和距离要求,基于这三类介质的信号线又衍生出很多不同的种类。最常用的是“五类线”适用于 100BASE-T 和 10BASE-T 的网络,它们的网络速率分别为 100Mbps 和 10Mbps。

  (2)编码

  为了让接收方在没有外部时钟参考的情况也能确定每一位的起始、结束和中间位置,在传输信号时不直接采用二进制编码。在 10BASE-T 的传输方式中采用曼彻斯特编码,在100BASE-T 中则采用 4B/5B 编码。

  曼彻斯特编码把每一个二进制位的周期分为两个间隔,在表示“ 1”时,以前半个周期为高电平,后半个周期为低电平。表示“ 0”时则相反,见下图:

               曼彻斯特编码

  采用曼彻斯特码在每个位周期都有电压变化,便于同步。但这样的编码方式效率太低,只有 50%。

  在 100BASE-T 采用的 4B/5B 编码是把待发送数据位流的每 4 位分为一组,以特定的 5位编码来表示,这些特定的 5 位编码能使数据流有足够多的跳变,达到同步的目的,而且效率也从曼彻斯特编码的 50%提高到了 80%。

  (3) CSMA/CD 冲突检测

  早期的以太网大多是多个节点连接到同一条网络总线上(总线型网络),存在信道竞争问题,因而每个连接到以太网上的节点都必须具备冲突检测功能。以太网具备 CSMA/CD冲突检测机制,如果多个节点同时利用同一条总线发送数据,则会产生冲突,总线上的节点可通过接收到的信号与原始发送的信号的比较检测是否存在冲突,若存在冲突则停止发送数据,随机等待一段时间再重传。

  现在大多数局域网组建的时候很少采用总线型网络,大多是一个设备接入到一个独立的路由或交换机接口,组成星型网络,不会产生冲突。但为了兼容,新出的产品还是带有冲突检测机制。

  2.2、 MAC 子层

  (1)MAC 的功能

  MAC 子层是属于数据链路层的下半部分,它主要负责与物理层进行数据交接,如是否可以发送数据,发送的数据是否正确,对数据流进行控制等。它自动对来自上层的数据包加上一些控制信号,交给物理层。接收方得到正常数据时,自动去除 MAC 控制信号,把该数据包交给上层。

  (2) MAC 数据包

  IEEE 对以太网上传输的数据包格式也进行了统一规定,见下图。该数据包被称为MAC 数据包。

              MAC数据包格式

  MAC 数据包由前导字段、帧起始定界符、目标地址、源地址、数据包类型、数据域、填充域、校验和域组成。

  前导字段:也称报头,这是一段方波,用于使收发节点的时钟同步。内容为连续 7 个字节的 0x55。字段和帧起始定界符在 MAC 收到数据包后会自动过滤掉。
  帧起始定界符(SFD): 用于区分前导段与数据段的,内容为 0xD5。
  MAC 地址: MAC 地址由 48 位数字组成,它是网卡的物理地址,在以太网传输的最底层,就是根据 MAC 地址来收发数据的。部分 MAC 地址用于广播和多播,在同一个网络里不能有两个相同的 MAC 地址。 PC 的网卡在出厂时已经设置好了 MAC 地址,但也可以通过一些软件来进行修改,在嵌入式的以太网控制器中可由程序进行配置。数据包中的 DA 是目标地址, SA 是源地址。
  数据包类型: 本区域可以用来描述本 MAC 数据包是属于 TCP/IP 协议层的 IP 包、 ARP包还是 SNMP 包,也可以用来描述本 MAC 数据包数据段的长度。 如果该值被设置大于 0x0600,不用于长度描述,而是用于类型描述功能,表示与以太网帧相关的 MAC客户端协议的种类。
  数据段: 数据段是 MAC 包的核心内容,它包含的数据来自 MAC 的上层。其长度可以从 0~1500 字节间变化。
  填充域:由于协议要求整个 MAC 数据包的长度至少为 64 字节(接收到的数据包如果少于 64 字节会被认为发生冲突,数据包被自动丢弃),当数据段的字节少于 46 字节时,在填充域会自动填上无效数据,以使数据包符合长度要求。
  校验和域: MAC 数据包的尾部是校验和域,它保存了 CRC 校验序列,用于检错。

  以上是标准的 MAC 数据包, IEEE 802.3 同时还规定了扩展的 MAC 数据包,它是在标准的 MAC 数据包的 SA 和数据包类型之间添加 4 个字节的 QTag 前缀字段,用于获取标志的 MAC 帧。前 2 个字节固定为 0x8100,用于识别 QTag 前缀的存在;后两个字节内容分别为 3 个位的用户优先级、 1 个位的标准格式指示符(CFI)和一个 12 位的 VLAN 标识符。

3、MAC层与PHY物理层之间的接口类型

  3.1、MAC 和 PHY接口概要

  以太网的通信离不开物理层 PHY 芯片的支持,以太网 MAC 和 PHY 之间有一个接口,常用的接口有MII、 RMII、 GMII、 RGMII 等。
  (1)MII(Medium Independent Interface, 媒体独立接口): MII 支持 10Mbps 和 100Mbps 的操作,数据位宽为 4 位

    在 100Mbps 传输速率下,时钟频率为 25Mhz
    在 10Mbps 传输速率下,时钟频率为 2.5Mhz
  (2)RMII(Reduced MII): RMII 是 MII 的简化版, 数据位宽为 2 位

    在 100Mbps 传输速率下,时钟频率为 50Mhz
    在 10Mbps 传输速率下,时钟频率为 5Mhz
  (3)GMII(Gigabit MII): GMII 接口向下兼容 MII 接口, 支持 10Mbps、 100Mbps 和 1000Mbps 的操作,数据位宽为 8 位

    在 1000Mbps 传输速率下,时钟频率为 125Mhz
    在 100Mbps 传输速率下,时钟频率为 25Mhz
    在 10Mbps 传输速率下,时钟频率为 2.5Mhz
  (4)RGMII(Reduced GMII): RGMII 是 GMII 的简化版,数据位宽为 4 位

    在 1000Mbps 传输速率下,时钟频率为 125Mhz,在时钟的上下沿同时采样数据
    在 100Mbps传输速率下,时钟频率为25MHz,为单个时钟沿采样
    在 10Mbps传输速率下,时钟频率为2.5MHz,为单个时钟沿采样
    在千兆以太网中,常用的接口为 RGMII 和 GMII 接口。 RGMII 接口的优势是同时适用于10M/100M/1000Mbps 通信速率,同时占用的引脚数较少。但 RGMII 接口也有其缺点,就是在 PCB 布线时需要尽可能对时钟、控制和数据线进行等长处理,且时序约束相对也更为严格。

  3.2、MAC 和 PHY接口介绍
  (1)MII接口
  即媒体独立接口,数据位宽为 4 位,100Mbps 速率下,时钟频率为 25MHz; 10Mbps 速率下,时钟频率为 2.5MHz。

  ETH_RXC:接收数据参考时钟, ETH_RXC 由 PHY 侧提供。
  ETH_RXDV:接收数据有效信号,高电平有效。
  ETH_RXER:接收数据错误信号,高电平有效。
  ETH_RXD:四位并行的接收数据线,在ETH_RXDV为高电平,ETH_RXER为低电平数据有效。
  ETH_TXC:发送参考时钟, ETH_TXC 由 PHY侧提供。
  ETH_TXEN:发射数据有效信号,高电平有效。
  ETH_TXER:发射数据错误信号,高电平有效。
  ETH_TXD:四位并行的发送数据线,在ETH_TXEN为高电平,ETH_TXER为低电平数据有效。

  (2)RMII接口
  即简化媒体独立接口,数据位宽为2位,100Mbps 速率下,时钟频率为 50MHz; 10Mbps 速率下,时钟频率为 5MHz

  REF_CLK:参考时钟
  CRS_DV:CRS与DV复用接口
  ETH_RXER:接收数据错误信号,高电平有效。
  ETH_RXD:二位并行的接收数据线。
  ETH_TXEN:发射数据有效信号,高电平有效。
  ETH_TXD:二位并行的发送数据线

  (3)GMII接口
  即千兆比特媒体独立接口,数据位宽为 8 位,1000Mbps 速率下,时钟频率为 125MHz; 100Mbps 速率下,时钟频率为 25M; 10Mbps 速率下,时钟频率为 2.5MHz

  ETH_RXC:接收数据参考时钟, ETH_RXC 由 PHY 侧提供。
  ETH_RXDV:接收数据有效信号,高电平有效。
  ETH_RXER:接收数据错误信号,高电平有效。
  ETH_RXD:八位并行的接收数据线,在ETH_RXDV为高电平,ETH_RXER为低电平数据有效。(4位数据有效)
  ETH_TXC:发送参考时钟, ETH_TXC 由 PHY侧提供。
  ETH_TXEN:发射数据有效信号,高电平有效。
  ETH_TXER:发射数据错误信号,高电平有效。
  ETH_TXD:八位并行的发送数据线,在ETH_TXEN为高电平,ETH_TXER为低电平数据有效。(4位数据有效)

  (4)RGMII接口
  即简化千兆比特媒体独立接口,数据位宽为4 位,1000Mbps 速率下,时钟频率为 125MHz; 100Mbps 速率下,时钟频率为 25M; 10Mbps 速率下,时钟频率为 2.5MHz

  REF_CLK:参考时钟
  ETH_RXCTL(ETH_RX_DV):接收数据控制信号。
  ETH_RXD:四位并行的接收数据线。
  ETH_TXCTL(ETH_TXEN):发送数据控制信号。
  ETH_TXD:四位并行的发送数据线
  ETH_TXCTL 和 ETH_RXCTL 控制信号同样采用 DDR 的方式在一个时钟周期内传输两位控制信号,即上升沿发送/接收数据使能(TX_EN/RX_ DV)信号,下降沿发送/接收使能信号与错误信号的异或值(TX_ERR xor TX_EN、 RX_ERR xor RX_DV)。

4、 STM32内部的以太网外设(ETH)

  STM32F42x 系列控制器内部集成了一个以太网外设,它实际是一个通过 DMA 控制器进行介质访问控制(MAC),它的功能就是实现 MAC 层的任务。借助以太网外设,STM32F42x 控制器可以通过 ETH 外设按照 IEEE 802.3-2002 标准发送和接收 MAC 数据包。

  STM32 的 MAC 内核是一个以太网 MAC 控制器,用于实现以太网通信。它符合 IEEE802.3 标准,支持 10/100Mbit/s 的数据传输速率,并提供了地址和媒体访问控制方式。
  STM32 的 MAC 内核与 TCP/IP 协议栈的层次联系主要体现在网络层和链路层。 MAC 内核作为链路层设备,负责与物理层接口(如以太网 PHY)进行通信,并提供了对数据包的封装、解析和发送接收等操作的支持。同时, MAC 内核还可以通过配置和管理 PHY 设备,实现网络层的地址解析和数据包的路由等功能。因此, STM32 的 MAC 内核是 TCP/IP 协议栈在网络层和链路层的实现基础之一,通过与 TCP/IP 协议栈的配合使用,可以实现以太网通信的各种功能。

  ETH 内部自带专用的 DMA 控制器用于 MAC, STM32F42x 的ETH 支持两个工业标准接口,介质独立接口(MII)和简化介质独立接口(RMII),用于与外部 PHY 芯片连接。 MII 和 RMII 接口用于 MAC数据包传输, ETH 还集成了站管理接口(SMI)接口专门用于与外部 PHY 通信,用于访问PHY 芯片寄存器。

  物理层定义了以太网使用的传输介质、传输速度、数据编码方式和冲突检测机制,PHY 芯片是物理层功能实现的实体,生活中常用水晶头网线+水晶头插座+PHY 组合构成了物理层。

  ETH 有专用的 DMA 控制器,它通过 AHB 主从接口与内核和存储器相连, AHB 主接口用于控制数据传输,而 AHB 从接口用于访问“控制与状态寄存器” (CSR)空间。在进行数据发送是,先将数据有存储器以 DMA 传输到发送 TX FIFO 进行缓冲,然后由 MAC 内核发送;接收数据时, RX FIFO 先接收以太网数据帧,再由 DMA 传输至存储器。 ETH 系统功能框图见下图:

image

  从上图描述中可以明确地了解到,绿色框框的 RX FIFO 和 TX FIFO 都是 2KB 的物理存储器,它们分别存储网络层递交的以太网数据和接收的以太网数据。以太网 DMA 是网络层和数据链路层的中间桥梁,是利用存储器到存储器方式传输。红色框框的内容可分为两个部分讲解,RMII 与 MII 是 MAC 内核(数据链路层)与 PHY 芯片(物理层)的数据交互通道,用来传输以太网数据。 MDC 和 MDIO 是 MAC 内核对 PHY 芯片的管理和配置,是站管理接口(SMI)所需的通信引脚。站管理接口( SMI)允许应用程序通过 2 条线:时钟( MDC)和数据线(MDIO)访问任意 PHY 寄存器。该接口支持访问多达 32 个 PHY。应用程序可以从 32 个PHY 中选择一个 PHY,然后从任意 PHY 包含的 32 个寄存器中选择一个寄存器,发送控制数据或接收状态信息。任意给定时间内只能对一个 PHY 中的一个寄存器进行寻址。在 MAC 对PHY 进行读写操作的时候,应用程序不能修改 MII 的地址寄存器和 MII 的数据寄存器。在此期间对 MII 地址寄存器或 MII 数据寄存器执行的写操作将会被忽略。

  4.1、SMI 接口

  SMI 是 MAC 内核访问 PHY 寄存器标志接口,它由两根线组成,数据线 MDIO 和时钟线 MDC。 SMI 支持访问 32 个 PHY,这在设备需要多个网口时非常有用,不过一般设备都只使用一个 PHY。 PHY 芯片内部一般都有 32 个 16 位的寄存器,用于配置 PHY 芯片属性、工作环境、状态指示等等,当然很多 PHY 芯片并没有使用到所有寄存器位。 MAC 内核就是通过 SMI 向 PHY 的寄存器写入数据或从 PHY 寄存器读取 PHY 状态,一次只能对一个PHY 的其中一个寄存器进行访问。 SMI 最大通信频率为 2.5MHz,通过控制以太网 MACMII 地址寄存器 (ETH_MACMIIAR)的 CR 位可选择时钟频率。

  (1)SMI 帧格式

  SMI 是通过数据帧方式与 PHY 通信的,帧格式如下表,数据位传输顺序从左到右。

                    SMI 帧格式 

  PADDR 用于指定 PHY 地址,每个 PHY 都有一个地址,一般由 PHY 硬件设计决定,所以是固定不变的。 RADDR 用于指定 PHY 寄存器地址。 TA 为状态转换域, 若为读操作,MAC 输出两个位高阻态,而 PHY 芯片则在第一位时输出高阻态,第二位时输出“ 0”。若为写操作, MAC 输出“ 10”, PHY 芯片则输出高阻态。 数据段有 16 位,对应 PHY 寄存器每个位,先发送或接收到的位对应以太网 MAC MII 数据寄存器(ETH_MACMIIDR)寄存器的位 15。 

  (2)SMI 读写操作

  当以太网 MAC MII 地址寄存器 (ETH_MACMIIAR)的写入位和繁忙位被置 1 时, SMI将向指定的 PHY 芯片指定寄存器写入 ETH_MACMIIDR 中的数据。写操作时序见下图:

                   SMI 写操作

  当以太网 MAC MII 地址寄存器 (ETH_MACMIIAR)的写入位为 0 并且繁忙位被置 1 时,SMI 将从向指定的 PHY 芯片指定寄存器读取数据到 ETH_MACMIIDR 内。读操作时序见下图:

                   SMI 读操作 

  4.2、 MII 和 RMII 接口

  (1)MII接口

  介质独立接口(MII)是一个媒体独立接口,也称为媒体接口。它是 IEEE-802.3 定义的以太网行业标准。 MII 包括一个数据接口,以及一个 MAC 和 PHY 之间的管理接口。数据接口包括分别用于发送器和接收器的两条独立信道,每条信道都有自己的数据、时钟和控制信号。MII 数据接口总共需要 16 个信号。管理接口是个双信号接口:一个是时钟信号,另一个是数据信号。通过管理接口,上层能监视和控制 PHY。下图为 MCU 通过 MII 接口与 PHY 芯片的连接图。

  介质独立接口(MII)用于连接 MAC 控制器和 PHY 芯片,提供数据传输路径。 RMII 接口是 MII 接口的简化版本, MII 需要 16 根通信线, RMII 只需 7 根通信,在功能上是相同的。

             MII 接口连接

  TX_CLK:数据发送时钟线。标称速率为 10Mbit/s 时为 2.5MHz;速率为 100Mbit/s 时为 25MHz。 RMII 接口没有该线。
  TXD[3:0]:数据发送数据线。对于 MII 有 4 位, RMII 只有 2 位。只有在TX_EN 处于有效电平数据线才有效。
  TX_EN:数据发送使能。在整个数据发送过程保存有效电平。
  RX_CLK:数据接收时钟线。标称速率为 10Mbit/s 时为 2.5MHz;速率为 100Mbit/s 时为 25MHz。 RMII 接口没有该线。
  RXD[3:0]:数据接收数据线,由 PHY 芯片负责驱动。对于 MII 有 4 位,RMII 只有 2 位。在 MII 模式,当 RX_DV 禁止、 RX_ER 使能时,特定的 RXD[3:0]值用于传输来自 PHY 的特定信息。
  RX_ER:接收错误信号线,由 PHY 驱动,向 MAC 控制器报告在帧某处检测到错误。该信号必须保持一个或多个周期(MII_RX_CLK),从而向 MAC 子层指示在帧的某处检测到错误。
  RX_DV:接收数据有效信号,功能类似 TX_EN,只不过用于数据接收,由 PHY 芯片负责驱动。对于 RMII 接口,是把 CRS 和 RX_DV 整合成 CRS_DV 信号线,当介质处于不同状态时会自切换该信号状态。
  CRS:载波侦听信号,由 PHY 芯片负责驱动,当发送或接收介质处于非空闲状态时使能该信号。在全双工模式该信号线无效。
  COL:冲突检测信号,由 PHY 芯片负责驱动,检测到介质上存在冲突后该线被使能,并且保持至冲突解除。在全双工模式该信号线无效。
  MDC:管理接口的时钟,它是一个非周期信号,信号的最小周期(实际是正电平时间和负电平时间之和)为 400ns,最小正电平时间和负电平时间为 160ns,最大的正负电平时间无限制。
  MDIO:是一根双向的数据线。用来传送 MAC 层的控制信息和物理层的状态信息

  (2)RMII接口

  简化媒体独立接口( RMII)是一种标准的以太网接口之一,比 MII 有更少的 I/O 传输。RMII 口通常只用两根线来传输数据,而 MII 口需要用四根线。对于 10M 线速, RMII 的速率是 5M,而 MII 的速率是 2.5M;对于 100M 线速, RMII 的速率是 50M,而 MII 的速率是 25M。
  RMII 用于传输以太网包,在 MII/RMII 接口是 4/2bit 的,在以太网的 PHY 里需要做串并转换、编解码等才能在双绞线和光纤上进行传输,其帧格式遵循 IEEE 802.3(10M)/IEEE802.3u(100M)/IEEE 802.1q(VLAN)。 下图为 MCU 通过 RMII 接口与 PHY 芯片的连接图。

             RMII 接口连接 

  TXD[1:0]:数据发送数据线。对于 MII 有 4 位, RMII 只有 2 位。只有在TX_EN 处于有效电平数据线才有效。
  TX_EN:数据发送使能。在整个数据发送过程保存有效电平。
  RXD[1:0]:数据接收数据线,由 PHY 芯片负责驱动。对于 MII 有 4 位,RMII 只有 2 位。在 MII 模式,当 RX_DV 禁止、 RX_ER 使能时,特定的 RXD[3:0]值用于传输来自 PHY 的特定信息。
  CRS_DV:接收数据有效信号,功能类似 TX_EN,只不过用于数据接收,由 PHY 芯片负责驱动。
  MDC:管理接口的时钟,它是一个非周期信号,信号的最小周期(实际是正电平时间和负电平时间之和)为 400ns,最小正电平时间和负电平时间为 160ns,最大的正负电平时间无限制。
  MDIO:是一根双向的数据线。用来传送 MAC 层的控制信息和物理层的状态信息
  REF_CLK:仅用于 RMII 接口,由外部时钟源提供 50MHz 参考时钟。因为要达到 100Mbit/s 传输速度, MII 和 RMII 数据线数量不同,使用 MII 和 RMII 在时钟线的设计是完全不同的。对于 MII 接口,一般是外部为 PHY 提供 25MHz 时钟源,再由 PHY 提供 TX_CLK 和 RX_CLK 时钟。对于 RMII 接口,一般需要外部直接提供 50MHz时钟源,同时接入 MAC 和 PHY。

  从上图描述中可以明确地了解到, REF_CLK 引脚负责提供 50MHz 的时钟频率。这个时钟信号对 MAC 内核和 PHY 芯片都至关重要,确保它们之间的时钟同步,从而保证数据传输的准确性和稳定性。

  LAN8720A型号PHY 芯片只支持 RMII 接口,电路设计时参考图RMII 接口连接 。

  ETH 相关硬件在 STM32F42x 控制器分布参考表如下图,其中, PPS_OUT IEEE 1588 定义的一个时钟同步机制。

  4.3、MAC 数据包发送和接收

  ETH 外设负责 MAC 数据包发送和接收。利用 DMA 从系统寄存器得到数据包数据内容, ETH 外设自动填充完成 MAC 数据包封装,然后通过 PHY 发送出去。在检测到有MAC 数据包需要接收时, ETH 外设控制数据接收,并解封 MAC 数据包得到解封后数据通过 DMA 传输到系统寄存器内。

  (1)MAC 数据包发送

  MAC 数据帧发送全部由 DMA 控制,从系统存储器读取的以太网帧由 DMA 推入 FIFO,然后将帧弹出并传输到 MAC 内核。帧传输结束后,从 MAC 内核获取发送状态并传回DMA。在检测到 SOF(Start Of Frame)时, MAC 接收数据并开始 MII 发送。在 EOF(End OfFrame)传输到 MAC 内核后,内核将完成正常的发送,然后将发送状态返回给 DMA。如果在发送过程中发送常规冲突, MAC 内核将使发送状态有效, 然后接受并丢弃所有后续数据,直至收到下一 SOF。检测到来自 MAC 的重试请求时,应从 SOF 重新发送同一帧。如果发送期间未连续提供数据, MAC 将发出下溢状态。在帧的正常传输期间,如果 MAC 在未获得前一帧的 EOF 的情况下接收到 SOF,则将忽略该 SOF 并将新的帧视为前一帧的延续。

  MAC 控制 MAC 数据包的发送操作,它会自动生成前导字段和 SFD 以及发送帧状态返回给 DMA,在半双工模式下自动生成阻塞信号,控制 jabber(MAC 看门狗)定时器用于在传输字节超过 2048 字节时切断数据包发送。 在半双工模式下, MAC 使用延迟机制进行流量控制,程序通过将 ETH_MACFCR 寄存器的 BPA 位置 1 来请求流量控制。 MAC 包含符合IEEE 1588 的时间戳快照逻辑。 

               MAC 数据包发送时序(无冲突)

  (2) MAC 数据包接收

  MAC 接收到的数据包填充 RX FIFO,达到 FIFO 设定阈值后请求 DMA 传输。在默认直通模式下,当 FIFO 接收到 64 个字节(使用 ETH_DMAOMR 寄存器中的 RTC 位配置)或完整的数据包时,数据将弹出,其可用性将通知给 DMA。 DMA 向 AHB 接口发起传输后,数据传输将从 FIFO 持续进行,直到传输完整个数据包。完成 EOF 帧的传输后,状态字将弹出并发送到 DMA 控制器。在 Rx FIFO 存储转发模式(通过 ETH_DMAOMR 寄存器中的RSF 位配置)下,仅在帧完全写入 Rx FIFO 后才可读出帧。

  当 MAC 在 MII 上检测到 SFD 时,将启动接收操作。 MAC 内核将去除报头和 SFD,然后再继续处理帧。检查报头字段以进行过滤, FCS 字段用于验证帧的 CRC 如果帧未通过地址滤波器,则在内核中丢弃该帧。

             MAC 数据包接收时序(无错误)

  4.4、 MAC 过滤

  MAC 过滤功能可以选择性的过滤设定目标地址或源地址的 MAC 帧。它将检查所有接收到的数据帧的目标地址和源地址,根据过滤选择设定情况,检测后报告过滤状态。有单播源地址过滤。

  单播目标地址过滤是将接收的相应 DA 字段与预设的以太网 MAC 地址寄存器内容比较,最高可预设 4 个过滤 MAC 地址。多播目标地址过滤是根据帧过滤寄存器中的 HM 位执行对多播地址的过滤,是对 MAC 地址寄存器进行比较来实现的。单播和多播目标地址过滤都还支持 Hash 过滤模式。广播目标地址过滤通过将帧过滤寄存器的 BFD 位置 1 使能,这使得 MAC 丢弃所有广播帧。

  单播源地址过滤是将接收的 SA 字段与 SA 寄存器内容进行比较过滤。MAC 过滤还具备反向过滤操作功能,即让过滤结构求补集。

  4.5、以太网 DMA 描述符

  在移植 lwIP 之前,需要具备一定的以太网 DMA 描述符相关知识。下面,我将使用F4_V1.26.0 版本的 HAL 库和 F4_V1.27.0( F7/H7 相同)版本的 HAL 库来详细讲解以太网DMA 描述符。如果这两个版本之间存在不同的以太网知识,我会进行重点标注,以帮助读者更好地理解和应用。
  (1)ST 的以太网 DMA 描述符简介
  ST 以太网模块中的以太网数据包传输通过以太网 DMA 描述符在接收/发送 FIFO 和内存之间完成。该模块有两个描述符列表,一个用于接收,另一个用于发送。这两个列表的基地址被分别写入 DMARDLAR 寄存器和 DMATDLAR 寄存器。此外,这两个描述符列表支持两种链接方式, 如下图所示。

image

  图 2.2.1.1 展示了 DMA 描述符的两种结构:环形结构和链接结构。在 ST 提供的以太网驱动库 stm32f4/f7/h7xx_hal_eth.c 中,初始化发送和接收描述符列表使用的是链接结构。 DMA 描述符的链接结构的具体描述如下图 2.2.1.2 和 2.2.1.3 所示。

image

   上图的 DMA 描述符链接结构,由以下函数实现如下表所示:

image

  这些函数应注意以下几点:
     一个以太网数据包可以跨越一个或多个 DMA 描述符
     一个 DMA 描述符只能用于一个以太网数据包。
     DMA 描述符列表中的最后一个描述符指向第一个,形成循环链式结构。
  在 ST 的以太网驱动库 stm32f4/f7/h7xx_hal_eth.h 中,有一个结构体 ETH_DMADescTypeDef,这个结构体用于定义发送和接收 DMA 描述符。以下是 ETH_DMADescTypeDef 结构体的代码示例。
  F4_V1.26.0 版本的 HAL 库:

typedef struct {
__IO uint32_t Status; /* 状态 */
uint32_t ControlBufferSize; /* 控制和 buffer1, buffer2 的长度 */
uint32_t Buffer1Addr; /* buffer1 地址 */
uint32_t Buffer2NextDescAddr; /* buffer2 地址或下一个描述符地址 */
uint32_t ExtendedStatus; /* 增强描述符状态 */
uint32_t Reserved1; /* 保留 */
uint32_t TimeStampLow; /* 时间戳低位 */
uint32_t TimeStampHigh; /* 时间戳高位 */
} ETH_DMADescTypeDef;

  F4_V1.27.0/F7_V1.17/H7_V1.10 版本的 HAL 库:

typedef struct{
__IO uint32_t DESC0;
__IO uint32_t DESC1;
__IO uint32_t DESC2;
__IO uint32_t DESC3;
__IO uint32_t DESC4;
__IO uint32_t DESC5;
__IO uint32_t DESC6;
__IO uint32_t DESC7;
uint32_t BackupAddr0; /* used to store rx buffer 1 address */
uint32_t BackupAddr1; /* used to store rx buffer 2 address */
} ETH_DMADescTypeDef;

  尽管 F4_V1.26.0 版本的 ETH_DMADescTypeDef 结构体与 F4_V1.27.0/F7_V1.17/H7_V1.10版本的 ETH_DMADescTypeDef 结构体的成员变量名称存在差异,但它们所实现的功能是一致的。例如, DESC0 和 Status 都用于描述以太网 DMA 描述符的状态。其他成员变量之间也存在一一对应的关系。这种差异可能是由于版本更新引起的命名或组织更改,但它们的核心功能保持不变。在进行相关编程和配置时,需要根据具体版本的文档和结构体定义进行相应的调整和处理。
  (2)DMA 描述符的类型
  DMA 描述符分为增强描述符和常规描述符。本教程中使用的是常规描述符,对于常规描述符,我们只需要使用 ETH_DMADescTypeDef 结构体的前四个成员变量。关于常规描述符和增强描述符的区别,建议参考 STM32F4/F7/H7xx 中文参考手册的以太网章节,以获取更详细的信息和指导。
  我们知道 STM32F4/F7/H7 的描述符分为发送描述符和接收描述符。发送描述符和接收描述符都使用 ETH_DMADescTypeDef 这个结构体来定义。本教程中,我们将以发送描述符(常规 Tx 的 DMA 描述符)为例进行讲解,而接收描述符(常规 Rx 的 DMA 描述符)与之类似。常规 Tx 的 DMA 描述符可以用下图来表示。

image

  从图 2.2.2.1 中可以看到,常规 Tx DMA 描述符包含 4 个“寄存器”: TDES0、 TDES1、TDES2 和 TDES3。而如果是增强描述符的话,则会有 8 个“寄存器”。需要注意的是,这 4 个“寄存器”并不是 STM32F4/F7/H7 真实存在的,我们在 STM32F4/F7/H7 的寄存器列表里面是找不到的。它们是由 ETH_DMADescTypeDef 这个结构体描述,被称之为“软件寄存器”。这些“寄存器”也叫做描述符字,它们与 ETH_DMADescTypeDef 结构体的关系如下表所示(此处以 Tx DMA 描述符为例)。

image

  以上表格 2.2.2.1 所列的是常规 Tx 的 DMA 描述符,常规 Rx 的 DMA 描述符与之类似。与操作寄存器类似,描述符字的每个位代表不同的状态或控制。关于 Tx 的 DMA 描述符中描述符字各个位的含义,可以参考 STM32F4/F7/H7xx 中文参考手册的以太网章节(Rx DMA 描述符)以获取更详细的信息。 通过使用这些描述符字,我们可以配置和操作 DMA 描述符的相关参数和状态,从而实现对以太网数据包传输的全面控制和管理。在理解了这些描述符字和结构体的关系后,我们可以更好地利用 STM32F4/F7/H7 的以太网模块进行数据传输和网络通信。
  前面我们了解到, ST 的官方以太网库 stm32f4/f7/h7xx_hal_eth.c 中使用了链接结构的DMA 描述符。在以太网描述符结构体 ETH_DMADescTypeDef 中, BufferAddr(对应于DESC2)用于保存缓冲区 1 的地址,而 NextDescriptor(对应于 DESC3)则用于保存下一个描述符的地址。 如下图所示。
  F4_V1.26.0 版本的 HAL 库:

image

   F4_V1.27.0/F7_V1.17/H7_V1.10 版本的 HAL 库:

image

  正如图 2.2.2.2 所示,我们需要定义两个 DMA 描述符数组,分别用于发送和接收 DMA。
  在例程中,我们将在 ethernet.c 文件中定义两个指向 ETH_DMADescTypeDef 的指针 g_eth_dma_rx_dscr_tab 和 g_eth_dma_tx_dscr_tab。一个用于 DMA 接收,一个用于 DMA 发送。以下是相关的代码示例:
  F4_V1.26.0 版本的 HAL 库:

ETH_DMADescTypeDef *g_eth_dma_rx_dscr_tab; /* 以太网 DMA 接收描述符数据结构体指针 */
ETH_DMADescTypeDef *g_eth_dma_tx_dscr_tab; /* 以太网 DMA 发送描述符数据结构体指针 */

  F4_V1.27.0/F7_V1.17/H7_V1.10 版本的 HAL 库(阿波罗、北极星):

ETH_DMADescTypeDef g_eth_dma_rx_dscr_tab[ETH_RX_DESC_CNT];
ETH_DMADescTypeDef g_eth_dma_tx_dscr_tab[ETH_TX_DESC_CNT];

  我们可以用内存分配函数给 g_eth_dma_rx_dscr_tab 和 g_eth_dma_tx_dscr_tab 这两个指针分配内存。如果读者不希望使用动态内存,也可以直接定义两个数组。在 ST 以太网驱动库 stm32f4/f7/h7xx_hal_eth.c 中,采用的是 DMA 链接结构。但 g_eth_dma_rx_dscr_tab 和 g_eth_dma_tx_dscr_tab 是两个指针(或数组),因此我们需要将这两个指针(或数组)改为链接结构。在stm32f4/f7/h7xx_hal_eth.c 文件中,有两个函数可以将两个指针(或数组)变为链接结构,它们分别是:
  F4_V1.26.0 版本的 HAL 库(探索者、 DMF407):

HAL_ETH_DMATxDescListInit 和 HAL_ETH_DMARxDescListInit。

  F4_V1.27.0/F7_V1.17/H7_V1.10 版本的 HAL 库(阿波罗、北极星):

ETH_DMATxDescListInit 和 ETH_DMARxDescListInit。

  我们通过这两个函数我们就可以将上面两个指针(或数组) 变为链接结构了。
  (3)如何追踪 DMA 描述符
  为了追踪 Rx/Tx 的 DMA 描述符,在下图结构体中定义了两个非常重要的指针变量, 如下图所示。
  F4_V1.26.0 版本的 HAL 库(探索者、 DMF407):

image

   F4_V1.27.0/F7_V1.17/H7_V1.10 版本的 HAL 库:

image

 这两个指针变量指向 ETH_DMADescTypeDef 结构体,在使用过程中它们两个分别指向下一个要发送或者接收的描述符,如下图所示那样:

image

  至此 STM32F4/F7/H7 以太网模块中的 DMA 描述符讲解完成了,关于 DMA 描述符的详细内容读者可以参考 STM32 F4/F7/H7xx 中文参考手册。

5、PHY芯片介绍

  在 TCP/IP 体系架构中, PHY 芯片是物理层的实现,它负责将数据转换成光电模拟信号以便在网络中进行传输。常用的 PHY 芯片有两种,分别是 LAN8720A 和 YT8512C。这两款芯片都支持 10/100BASE-T 百兆以太网传输速率。为了更深入地了解这两款以太网芯片,作者将分为两个小节进行讲解。

  5.1、LAN8720A介绍

  LAN8720A 是 SMSC 公司(已被 Microchip 公司收购)设计的一个体积小、功耗低、全能型 10/100Mbps 的以太网物理层收发器。它是针对消费类电子和企业应用而设计的。LAN8720A 总共只有 24Pin,仅支持 RMII 接口。由它组成的网络结构见图 42-12。

          由 LAN8720A 组成的网络系统结构

  LAN8720A 通过 RMII 与 MAC 连接。 RJ45 是网络插座,在与 LAN8720A 连接之间还需要一个变压器,所以一般使用带电压转换和 LED 指示灯的 HY911105A 型号的插座。一般来说,必须为使用 RMII 接口的 PHY 提供 50MHz 的时钟源输入到 REF_CLK 引脚,不过LAN8720A 内部集成 PLL,可以将 25MHz 的时钟源陪频到 50MHz 并在指定引脚输出该时钟,所以我们可以直接使其与 REF_CLK 连接达到提供 50MHz 时钟的效果。

            LAN8720A 内部系统结构见图

  LAN8720A 有各个不同功能模块组成,最重要的要数接收控制器和发送控制器,其它的基本上都是与外部引脚挂钩,实现信号传输。部分引脚是具有双重功能的,比如PHYAD0 与 RXER 引脚是共用的,在系统上电后 LAN8720A 会马上读取这部分共用引脚的电平,以确定系统的状态并保存在相关寄存器内,之后则自动转入作为另一功能引脚。

  PHYAD[0]引脚用于配置 SMI 通信的 LAN8720A 地址,在芯片内部该引脚已经自带下拉电阻,默认认为 0(即使外部悬空不接),在系统上电时会检测该引脚获取得到 LAN8720A的地址为 0 或者 1,并保存在特殊模式寄存器(R18)的 PHYAD 位中,该寄存器的 PHYAD有 5 个位,在需要超过 2 个 LAN8720A 时可以通过软件设置不同 SMI 通信地址。PHYAD[0]是与 RXER 引脚共用。

  MODE[2:0]引脚用于选择 LAN8720A 网络通信速率和工作模式,可选 10Mbps 或100Mbps 通信速度,半双工或全双工工作模式,另外 LAN8720A 支持 HP Auto-MDIX 自动翻转功能,即可自动识别直连或交叉网线并自适应。一般将 MODE 引脚都设置为 1,可以让 LAN8720A 启动自适应功能,它会自动寻找最优工作方式。 MODE[0]与 RXD0 引脚共用、MODE[1]与 RXD1 引脚共用、 MODE[2]与 CRS_DV 引脚共用。

  nINT/REFCLKO 引脚用于 RMII 接口中 REF_CLK 信号线,当 nINTSEL 引脚为低电平是,它也可以被设置成 50MHz 时钟输出,这样可以直接与 STM32F42x 的 REF_CLK 引脚连接为其提供 50MHz 时钟源,这种模式要求为 XTAL1 与 XTAL2 之间或为 XTAL1/CLKIN提供 25MHz 时钟,由 LAN8720A 内部 PLL 电路陪频得到 50MHz 时钟,此时nIN/REFCLKO 引脚的中断功能不可用,用于 50MHz 时钟输出。当 nINTSEL 引脚为高电平时, LAN8720A 被设置为时钟输入,即外部时钟源直接提供 50MHz 时钟接入 STM32F42x的 REF_CLK 引脚和 LAN8720A 的 XTAL1/CLKIN 引脚,此时nINT/REFCLKO 可用于中断功能。 nINTSEL 与 LED2 引脚共用,一般使用下拉。 

  REGOFF 引脚用于配置内部+1.2V 电压源, LAN8720A 内部需要+1.2V 电压,可以通过VDDCR 引脚输入+1.2V 电压提供,也可以直接利用 LAN8720A 内部+1.2V 稳压器提供。当REGOFF 引脚为低电平时选择内部+1.2V 稳压器。 REGOFF 与 LED1 引脚共用。

  SMI 支持寻址 32 个寄存器, LAN8720A 只用到其中 14 个,参考下表:

           LAN8720A 寄存器列表 

  序号与 SMI 数据帧中的 RADDR 是对应的,这在编写驱动时非常重要,本文将它们标记为 R0~R31。寄存器可规划为三个组: Basic、 Extended 和 Vendor-specific。 Basic 是 IEEE802.3 要求的, R0 是基本控制寄存器,其位 15 为 Soft Reset 位,向该位写 1 启动LAN8720A 软件复位,还包括速度、自适应、低功耗等等功能设置。 R1 是基本状态寄存器。Extended 是扩展寄存器,包括 LAN8720A 的 ID 号、制造商、版本号等等信息。 Vendorspecific 是供应商自定义寄存器, R31 是特殊控制/状态寄存器,指示速度类型和自适应功能。

  (1)、 LAN8720A 中断管理

  LAN8720A 的器件管理接口支持非 IEEE 802.3 规范的中断功能。当中断事件发生且相应中断位被使能时, LAN8720A 会在 nINT(14 脚)产生一个低电平有效的中断信号。 LAN8720A的中断系统提供了两种中断模式:主中断模式和复用中断模式。默认的中断模式为主中断模式,LAN8720A 在上电或复位后即工作在此模式下。模式控制/状态寄存器(十进制地址为 17)的ALTINT 位决定了工作模式:当 ALTINT 为 0 时, LAN8720A 工作在主模式;当 ALTINT 为 1时,工作在复用中断模式。正点原子的 STM32 系列开发板并未使用中断功能,如需了解关于中断的具体用法,请参考 LAN8720A 数据手册的 29、 30 页。
  (2)、 PHY 地址设置
  MAC 层通过 SMI 总线对 PHY 芯片进行读写操作。 SMI 总线具有强大的控制能力,可以管理多达 32 个 PHY 芯片。通过 PHY 地址的不同,我们可以精确地配置和访问每一个 PHY 芯片。对于 LAN8720A 芯片,其 PHY 地址的设置方式如下表所示。

image

  通过设置 PHYAD0 引脚的电平,我们可以为 LAN8720A 芯片分配一个唯一的 PHY 地址。在 MAC 层和 PHY 芯片之间进行通信时, SMI 总线会根据这个地址来识别和操作特定的 PHY芯片。由于正点原子板载的 PHY(LAN8720A) 芯片将 PHYAD0 引脚拉低,因此其 PHY 地址为 0x00。
  (3)、 nINT/REFCLKO 配置
  nINTSEL 引脚(2 号引脚) 用于设置 nINT/REFCLKO 引脚(14 号引脚) 的功能。nINTSEL 配置如下表所示。

image

   当工作在 REF_CLK In 模式时, 50MHz 的外部时钟信号应接到 LAN8720 的 XTAL1/CKIN引脚(5 号引脚) 和 STM32 的 RMII_REF_CLK(PA1) 引脚上,如下图所示。

image

   为了降低成本, LAN8720A 可以从外部的 25MHz 的晶振中产生 REF_CLK 时钟。到要使用此功能时应工作在 REF_CLK Out 模式。当工作在 REF_CLO Out 模式时 REF_CLK 的时钟源如下图所示。

image

  5.2、YT8512C 介绍
  YT8512C 是一款低功耗的单端口 10/100Mbps 以太网 PHY 芯片,它通过两条标准双绞线电缆收发器实现发送和接收数据所需的所有物理层功能。此外, YT8512C 还通过标准 MII 和RMII 接口与 MAC 层进行连接。 其功能结构图如下所示:

image

  上图展示了 YT8512C 芯片的内部总架构示意图。从图中我们可以看出,通过 LED0 和LED1 引脚的电平来设置 PHY 地址, PHY 内部时钟由 XTAL 和 Clock 引脚提供。同时, TXP、TXN、 RXP 和 RXN 引脚连接到 RJ45(网口),用于数据的发送和接收。
  (1)、PHY 地址设置
  MAC 层通过 SMI 总线对 PHY 芯片进行读写操作。 SMI 总线具有强大的控制能力,可以管理多达 32 个 PHY 芯片。通过 PHY 地址的不同,我们可以精确地配置和访问每一个 PHY 芯片。对于 YT8512C 芯片,其 PHY 地址的设置方式如下表所示:

image

  通过设置 LED0 和 LED1 引脚的电平,我们可以为 YT8512C 芯片分配一个唯一的 PHY 地址。在 MAC 层和 PHY 芯片之间进行通信时, SMI 总线会根据这个地址来识别和操作特定的PHY 芯片。 

  (2)、YT8521C 的 RMII 接口模式
  YT8521C 的 RMII 接口提供了两种 RMII 模式:
  ①: RMII1 模式: YT8521C 的 TXC 引脚不会输出 50MHz 时钟,这种模式下的连接示意图如下图 1.4.1.2 所示。
  ②: RMII2 模式: YT8521C 的 TXC 引脚会输出 50MHz 时钟, 这种模式下的连接示意图如下图 1.4.1.3 所示。

image

  对于 RMII 接口而言,为了使 PHY 芯片与 MAC 内核保持时钟同步操作,需要外部提供 50MHz 的时钟驱动。这个时钟可以来自 PHY 芯片、有源晶振或者 STM32 的 MCO 引脚。如果我们的电路采用 RMII1 模式, PHY 芯片将由 25MHz 晶振经过内部 PLL 倍频达到 50MHz。但是,在这种情况下, MAC 内核并没有被直接提供 50MHz 时钟以与 PHY 芯片保持同步。因此,为了保持时钟同步,我们需要在该基础上使用 MCO 或接入外部 50MHz 晶振来为 MAC 内核提供时钟。简而言之,为了确保 PHY 芯片与 MAC 内核之间的时钟同步,我们需要根据所采用的 RMII 模式,采取相应的措施来提供准确的时钟信号。

image

  如果电路按照上图模式进行连接, PHY 芯片将通过外接晶振的 25MHz 信号和内部 PLL 倍频操作,生成 50MHz 的内部时钟。接着, PHY 芯片的外围引脚 TXC 将输出 50MHz 时钟频率,这个时钟频率可以直接输入到 MAC 内核,以保持时钟同步。这样,我们就不需要再使用外部晶振或 MCO 引脚来提供 MAC 内核的时钟。

  至于 RMII1 模式和 RMII2 模式的选择,这取决于 YT8521C 的 RX_DV(8)和 RXD3(12)引脚的状态。具体如何选择这两种模式,请参考“YT8512C.PDF”手册的 17 到 18 页内容。

6、以太网接入 MCU 方案
  以太网接入方案主要分为两种:全硬件 TCP/IP 协议栈和软件 TCP/IP 协议栈。其中,软件TCP/IP 协议栈的应用非常广泛,如电脑、交换机等网络设备。而全硬件 TCP/IP 协议栈则是近年来比较新兴的以太网接入方案。下面作者将分别阐述这两种接入方案的差异和优缺点。
  (1)、 软件 TCP/IP 协议栈以太网接入方案
  这种以太网接入方案是由 lwIP、 MAC 内核和 PHY 层芯片共同实现的,用于实现以太网的物理连接。正点原子的探索者、阿波罗、北极星以及电机开发板都采用了这种类型的以太网接入方案。该方案的连接示意图如下:

image

  在上述图表中, MCU 需要内置 MAC 内核。该内核对应于 TCP/IP 体系结构中的数据链路层。 lwIP 软件库则用于实现 TCP/IP 体系结构中的应用层、传输层和网络层。同时,板载 PHY层芯片负责实现 TCP/IP 体系结构的物理层功能。通过结合 lwIP、 MAC 内核和 PHY 层芯片,我们构建了网络通信的核心骨架。
  接下来,我将为大家详细介绍软件 TCP/IP 协议栈方案的优缺点。
  优点:
  ①: 移植性:可在不同平台、不同编译环境的程序代码经过修改转移到自己的系统中运行。
  ②: 可造性:可在 TCP/IP 协议栈的基础上添加和删除相关功能。
  ③: 可扩展性:可扩展到其他领域的应用及开发。
  缺点:
  ①: 内存方面分析:传统的 TCP/IP 方案是移植一个 lwIP 的 TCP/IP 协议(RAM 50K+,ROM 80K+),造成主控可用内存减小。
  ②: 从代码量分析:移植 lwIP 可能需要的代码量超过 40KB,对于有些主控芯片内存匮乏来说无疑是一个严重的问题。
  ③: 从运行性能方面分析:由于软件 TCP/IP 协议栈方案在通信时候是不断地访问中断机制,造成线程无法运行,如果多线程运行,会使 MCU 的工作效率大大降低。
  ④: 从安全性方面分析:软件协议栈会很容易遭受网络攻击,造成单片机瘫痪。
  (2)、 硬件 TCP/IP 协议栈以太网接入方案
  全硬件 TCP/IP 协议栈是将传统的软件协议 TCP/IP 协议栈用硬件化的逻辑门电路来实现。它具备 TCP、 UDP、 ICMP 等多种网络协议的内部实现,并且实现了物理层以太网控制(MAC+PHY)以及内存管理等功能。这种方案提供了一套完整的硬件化以太网解决方案。该方案的连接示意图如下:

image

  通过这样的方式,全硬件 TCP/IP 协议栈可以大大提高以太网通信的性能和效率,特别是在需要高速、实时处理网络数据的应用场景中。同时,由于将协议栈和网络控制功能集成在芯片内部,它可以降低系统的复杂性和功耗,方便系统集成和部署。然而,这种方案的开发和实现难度较大,需要具备丰富的硬件设计和网络协议经验。
  接下来,我将为大家详细介绍硬件 TCP/IP 协议栈的优缺点。
  优点:
  ①: 从代码量方面来看:相比于传统的接入已经大大减少了代码量。
  ②: 从运行方面来看:极大的减少了中断次数,让单片机更好的完成其他线程的工作。
  ③: 从安全性方面来看:硬件化的逻辑门电路来处理 TCP/IP 协议是不可被攻击的,也就是说网络攻击和病毒对它无效,这也充分弥补了网络协议安全性不足的短板。
  缺点:
  ①: 从可扩展性来看:虽然该芯片内部使用逻辑门电路来实现应用层和物理层协议,但是它具有功能局限性,例如给 TCP/IP 协议栈添加一个协议,这样它无法快速添加了。
  ②: 从收发速率来看:全硬件 TCP/IP 协议栈芯片都是采用并口、 SPI 以及 IIC 等通讯接口来收发数据,这些数据会受通信接口的速率而影响。
  总的来说,全硬件 TCP/IP 协议栈通过简化传统的软件 TCP/IP 协议栈,卸载了 MCU 用于处理 TCP/IP 的线程,从而节约了 MCU 内部的 ROM 等硬件资源。工程师只需进行简单的套接字编程和少量的寄存器操作,即可方便地进行嵌入式以太网上层应用开发。这有助于减少产品开发周期,降低开发成本。通过全硬件 TCP/IP 协议栈的实现,系统可以获得更高的性能和效率,特别是在处理大量网络数据时。此外,由于将协议栈和网络控制功能集成在芯片内部,系统的复杂性和功耗也得到了降低,方便了系统集成和部署。然而,全硬件 TCP/IP 协议栈的开发和实现难度较大,需要具备丰富的硬件设计和网络协议经验。因此,在实际应用中需要根据具体需求和场景进行选择。

 

posted @ 2020-08-29 17:54  孤情剑客  阅读(2754)  评论(0)    收藏  举报