英飞凌 Aurix2G TC3XX GETH 模块详解

英飞凌 Aurix2G TC3XX GETH 模块详解

本文主要介绍 Infineon Aurix2G TC3XX 系列芯片GETH 模块硬件原理,MCAL相关配置和代码示例。


1 模块介绍

随着汽车科技的不断发展,车载以太网已经成为许多车型的标配技术。相比传统的汽车通信网络技术,车载以太网具有更高的带宽和数据传输速度,这使得车辆内部的各个系统可以更快地响应和交换信息。此外,车载以太网还能够支持更多的设备连接,从而满足现代汽车日益增长的智能化和互联需求。

英飞凌 Aurix2G TC3XX 系列芯片的 GETH 模块采用的是新思科技(Synopsys)的内核,全称 DesignWare Cores Ethernet Quality-of-Service**(DWC_ether_qos)。**DWC_ether_qos 通常用于嵌入式系统或网络设备中,可以帮助实现更可靠的数据传输、更低的延迟和更好的网络性能。

TC3XX 系列中除了旗舰的 TC39X 系列具有两个 GETH 模块,即支持两路 MAC,其他大部分型号都只支持一路 MAC。支持 10Mbps\100Mbps 的 RMII 协议以及 1000Mbps 的 RGMII 协议(部分中低型号不支持 RGMII),提供符合 IEEE 802.3-2008 的 MAC、MII 协议。

2 功能介绍

2.1 车载以太网硬件框架

为了使读者能够更好地理解 GETH 模块的相关功能,我们需要先介绍下车载以太网的硬件基本框架。

在这里插入图片描述
以太网的 MAC(Media Access Control)是数据链路层中的一个子层,负责控制数据在物理介质上的传输。MAC 层负责实现数据帧的封装和解封装,处理数据帧的发送和接收顺序,并通过 MAC 地址来识别数据包的接收方。MAC 一般在我们的 MCU 中,类似 Can Controller。

MAC 之外还需要一个以太网收发器,也就是我们常说的 PHY,负责物理层的功能,例如将数据转换为适合在传输介质上传输的信号、管理数据的编码和解码,以及处理与传输介质相关的电气特性。MAC 和 PHY 之间有两条交互,一条是 IEEE 指定的 MII(Medium Independent Interface),主要进行数据帧的交互;另外一个就是 SMI 接口,用于通过 MAC 进行 PHY 的配置、读取 PHY 寄存器等功能。二者一个是数据接口,一个是控制接口。

IEEE 802.3 标准中对以太网通信系统明确了有电气隔离的要求,因此,在以太网物理层 PHY 芯片之间,一般需要会通过网络变压器进行隔离。因此 PHY 需要接信号变压器、保护电路等。

然后末端就是一个 RJ45 接口,也就是我们电脑常见的网线插孔,用于进行物理层信号的传输。但是车载设备中一般没有网口,控制器之间的连接都是直接集成在线束中。

关于以太网的其他相关内容,大家可以自行查阅资料,工业上这块内容已经相当成熟了。

2.2 GETH 总览

Aurix 中的 GETH 模块除了包含 MAC 内核,还具有专属的 DMA 模块,负责进行数据的收发处理。英飞凌集成后的 GETH 架构如图所示:

在这里插入图片描述

从图中我们可以看出,和其他片内外设一样,MCU 内部通过 SRI 数据总线,与 GETH 模块进行以太网数据,通过 SPB 总线进行 GETH 模块寄存器设置。GETH 同样和 IR 模块进行交互,以进行中断路由处理。

GETH 独有的 DMA 模块用于数据的仲裁和搬运处理,从驱动层解放了 MCU 的负载。

Aurix TC3XX 系列支持 MIIRMIIRGMII 等媒体独立接口,从图中我们可以看出,它们作为可选接口出现,通过 Port 与外部相连。另外部分中低型号是不支持 RGMII 的,选型时需要注意。

下方 SMI 接口用来进行 PHY 的配置,以及寄存器读写等操作。

然后我们看 GETH 模块内部框图(下图为 Synopsys 提供的手册,因此命名为 EQOS,指 DWC_ether_qos,即 GETH 模块):

在这里插入图片描述

该图和前面的类似,只是进行了内部拆解,最外层 AHB Master 接口接到英飞凌的 SRI 总线上,供 DMA 进行数据读取和写入;AHB Slave 总线接入到英飞凌的 SPB 总线上用于 MCU 对 GETH 模块的控制。第二层 EQOS-DMA 主要包含 DMA 硬件,包括仲裁单元。第三层 EQOS-MTL 是传输层,用于组包拆包(不是 TCP)。最后一层是 EOQS-Core,就是模块的内核,负责数据的最下层收发处理。本节我们分别介绍这些模块的结构和功能。

2.2.1 GETH 时钟

GETH 模块时钟为 fGETH,其来源为 fSOURCE0,即系统时钟,分频系数为 CCUCON5.GETHDIV,计算公式为:

f G E T H = f S O U R C E 0 G E T H D I V \begin{equation} f_{GETH} = \frac {f_{SOURCE0}} {GETHDIV} \end{equation} fGETH=GETHDIVfSOURCE0

GETH 模块的寄存器控制总线时钟和其他外设一样,使用 SPB 时钟。

对于 MII、RMII 和 RGMII 的数据总线时钟,大部分来自外部,仅有 RGMII 的 TxClk 来自 GETH 模块,下文连接关系中我们会展开介绍。

2.2.2 CSR Slave Interface

CSR 全称为 Control and Status Register,在 GETH 内部 DMA、MTL、MAC 都有各自的寄存器。前文也提到,MCU 通过 SPB 总线访问该接口,接口内部转 AHB 协议进行数据处理。这些对于程序员来说是透明的,我们只需要根据寄存器说明访问寄存器即可。

2.2.3 Application Master Interface

AHB Master 接口用来进行 AHB 总线数据访问,该接口由 DMA 进行控制,在系统内存和 GETH 模块之间进行数据传输。在 GETH 模块工作过程中,不管是发送端还是接收端,总是由 GETH 的 DMA 主动访问 SRI 接口。

2.2.4 DMA 控制器

DMA 负责把从外界接收到的数据包,传输到系统内存中的 RX Buffer 里,同时把系统内存中 Tx Buffer 里需要发送的数据传输出去。DMA 具有各自独立的 Tx Engine 和 Rx Engine,Tx 和 Rx 各 4 个 DMA 通道,Tx Engine 的方向是从系统内存到 MTL,Rx Engine 则是从 MTL 到系统内存中。

GETH 模块的 DMA 利用一种寄存器和 Descriptors Lists描述符链表)结合的机制,在高效搬运数据的同时,最大程度减小 CPU 的负荷。

描述符是保存在系统内存中的具有特定格式的链表结构数据,GETH 中相关的寄存器会指向对应的描述符,而描述符指向内存中的用户 Buffer,这个结构有点类似 CSA 的机制。每个 DMA 有一个 Tx 描述符链表和一个 Rx 描述符链表。

由于 Tx 和 Rx 都会通过 AHB 总线访问系统内存,即用户 Buffer,所以在全双工的情况下,存在总线访问冲突的场景,这时候就需要进行 DMA 仲裁。仲裁支持两种模式:

  • Round-Robin Arbitration:当寄存器 DMA_MODE.DA 被设置为 0 时,使用该模式,该模式通过 DMA_MODE.PR 来按照比例为 Tx 和 Rx 分配总线带宽;
  • Fixed-Priority Arbitration:当寄存器 DMA_MODE.DA 被设置为 1,DMA_MODE.TXPR 为 0 时,则接收的优先级永远高于发送;如果 DMA_MODE.TXPR 为 1 时,则仲裁规则按照下表实施;

在这里插入图片描述

DMA 的控制并不需要用户直接干预,用户只需要通过描述符来控制数据的收发,DMA 的搬运完全在后台由硬件完成,该内容在下文中会详细介绍。

2.2.5 MAC Transaction Layer

MAC 传输层(MTL)提供 FIFO 内存接口,用于缓冲和调节应用系统内存与 MAC 之间的数据包传输,它位于 GETH 模块的 DMA 和 MAC 内核之间。传输层对于数据处理有两条路径:Trasmit Path 和 Receive Path,分别使用 Application Transmit Interface (ATI)和 Application Receive Interface (ARI)接口进行数据访问。

在发送端 DMA 将数据搬运到 MTL 的 Buffer 中,当 MTL 中队列满了(threshold mode)或者队列中已经有了完整的 packet(store-and-forward mode),MTL 就会将该 packet 取出队列并发往 MAC Core。同样在接收端,MTL 从 MAC Core 接收数据并存入 Buffer 中,当数据达到阈值或者组成一个完整的 packet,则 MTL 会通知 DMA 以进行向系统内存的数据搬运。

MAC Transaction Layer 的逻辑主要由硬件后台处理,在完成初始化之后几乎不用用户进行处理,所以此处加以赘述,感兴趣的读者可以阅读 DWC_ether_qos 手册。

2.2.6 MAC

MAC 主要负责与 PHY 芯片进行数据交互,MAC 支持与 PHY 交互的多种接口,可以选择一种 PHY 接口进行通讯。MAC 的通讯接口除了与 PHY 进行通讯的 MAC Transmit Interface(MTI)和 MAC Receive Interface (MRI)以外,还有 MCU 进行 MAC 寄存器配置的 MAC Control Interface (MCI)。

到这里就是数据链路层物理层的边界了,这里简单介绍下以太网帧结构:

在这里插入图片描述

一个普通的以太网数据链路层帧包括目的地址、源地址、类型、数据以及校验和,本文提到的 packet 是指除了校验和以外的内容,因为以太网帧校验和在 GETH 模块中是由 MAC Core 处理的。

Preamble 前同步码为 7 个字节的 1 和 0 交替数据,用于 MAC 进行数据速率调整。SFD 帧起始为 1 字节前 6 位 1 和 0 交替,最后的两个连续的 1 表示告诉接收端适配器帧信息要来了。帧间隔是最小 96bit 的时间宽度,此间不进行数据传输。

MTL 层处理的数据为数据链路层数据(除校验和以外的内容),MAC 层在收发端负责物理层数据的拆包和组包工作。

MAC Transmission

当 MTL 将数据发送到 MAC,并同时拉高 SOP 信号线,则视为启动一次发送,此时 MAC 开始将数据发往 MII 或者 GMII。然后中间有一系列延时、ACK 等逻辑完成 MTL 向 MAC 的数据发送,最后 MTL 拉高 EOP 信号线,视为 MTL 传输完成。如果是全双工模式,意味着这一包发送完成了;但是如果是半双工模式,MAC 层还需要进行载波侦听和碰撞检测,以防止总线 Busy 的时候发包失败,并进行重发流程。MAC 层的发送流程如下图所示:

在这里插入图片描述

同时 MAC 将 MTL 发来的链路层数据进行组包,在包头加上前导码、帧起始,然后计算 CRC 填充到尾部,并在尾部留上帧间隔。

MAC Reception

当 MAC 从连接 PHY 端的 MII 或者 GMII 接口检测到 SFD 帧起始以后,首先会拆包取出 Preamble 前导码和 SFD 帧起始,随后开始进行数据接收。数据接收到 Buffer 中以后需要进行 MAC 地址过滤CRC 校验,如果不通过则该包会被丢弃。接收端时序图如图所示:

在这里插入图片描述

2.3 Descriptors 描述符机制

GETH 模块的收发机制采用了寄存器与描述符结合的方式,来进行数据处理,下面我们来详细介绍这套机制以及描述符的结构。

类似 CSA 的机制,Aurix 中使用系统内存存放描述符,使用尽可能简洁的寄存器来表征描述符的状态。描述符(Descriptors)是存放在系统内存,也就是 RAM 中的链接信息,它的主要功能是用作 Buffer 的指针,另外包括一些状态信息和控制信息。每条描述符大小为 4 个 word,一共 16 字节。描述符之间虽然可以配置为带间隙,但是一般都是连续存放。

从数据传递方向的角度来说,描述符有发送描述符(Transmit Descriptor)接收描述符(Receive Descriptor);从功能的角度来说,描述符有两种:

  • Normal Descriptor:常规描述符,用来描述 packet 的数据,并提供适用于将要传输的 packet 的控制信息;
  • Context Descriptor:增强描述符,用于提供适用于将要传输的数据包的控制信息。

增强描述符一般很少会用到,所以本文着重介绍常规描述符,围绕其在发送端和收发端的功能进行展开。

虽然虽然手册上说一个描述符可以指向至多两个 Buffer,且可以把 MAC 帧的 Header 和 Payload 分开存放,但是实际使用过程中,包括 MCAL 相关的代码及配置,都是一个描述符指向一个 Buffer,多个描述符组成一个 RingBuffer 结构,如下图所示。

在这里插入图片描述

比如当我们执行发送操作时(通过写描述符尾寄存器),DMA 就会从当前发送描述符(Current Descriptor Pointer)指向的位置开始往下轮询,直到描述符尾指针,对所有属于 DMA 控制的描述符指向的 Buffer 执行数据搬运。

2.3.1 描述符相关寄存器

这里我们先介绍下和描述符相关的寄存器。这里注意一下,由于搬运是由 DMA 通道执行的,所以每个 DMA 通道有自己的一套描述符寄存器。

  • DMA_CHi_CURRENT_APP_TXDESC:当前发送描述符,用于指向 DMA 下一条会读取的描述符,也就是当前用户可用的描述符;
  • DMA_CHi_CURRENT_APP_TXBUFFER:当前发送描述符指向的 Buffer 地址**,**虽然描述符里有 Buffer 的信息,但是 Aurix 还是提供了当前发送 Buffer 的寄存器,表示当前发送描述符指向的 Buffer 地址;
  • **DMA_CHi_CURRENT_APP_RXBUFFER:**当前接收描述符,表示当前用户可用的接收描述符。
  • DMA_CHi_CURRENT_APP_RXBUFFER:当前接收描述符指向的 Buffer 地址。
  • DMA_CHi_TXDESC_LIST_ADDRESS:发送描述符基址,指向第一个发送描述符;
  • DMA_CHi_RXDESC_LIST_ADDRESS:接收描述符基址,指向第一个接收描述符;
  • DMA_CHi_TXDESC_RING_LENGTH:发送描述符长度,注意 0 表示 1 个描述符,以此类推;
  • DMA_CHi_RXDESC_RING_LENGTH:接收描述符长度,注意 0 表示 1 个描述符,以此类推;
  • DMA_CHi_TXDESC_TAIL_POINTER:发送描述符尾指针,指向最后一个描述符之后的地址;
  • DMA_CHi_RXDESC_TAIL_POINTER:接收描述符尾指针,指向最后一个描述符之后的地址。

我们通过一个实际场景来介绍下这些描述符寄存器的作用,描述符的内容可以先不用关注,后面会介绍。这是我在使用过程中的一段实际内存,它里面放了 4 个发送描述符,因为我这里配置了 4 个 Buffer。

在这里插入图片描述

然后我们看各个寄存器的值:

在这里插入图片描述
在这里插入图片描述

我们可以看到当前 CURRENT_TXDESC 指向的是第二个描述符,也就是说我们要发送数据的话就使用这个描述符。然后 TXDESC_LIST_ADDRESS 指向第一个描述符,TXDESC_RING_LENGTH 为 3 表示配置了 4 个描述符。当我们向 TXDESC_TAIL_POINTER 写入尾部地址时,DMA 会轮询从 CURRENT_TXDESCTXDESC_TAIL_POINTER(左闭右开)的所有描述符,执行发送操作。当然只有第二个描述符的 DMA 归属位置位了,到第三个时 DMA 会自动 Suspend,详细流程我们后面再讨论。

2.3.2 Transmit Descriptors 发送描述符

这里我们只介绍常规描述符。

常规描述符有两种状态,Read-formatWrite-back Format。当我们需要向外部发送数据,要按照 Read-format 向其中写入 Buffer 地址及控制信息,然后将其控制权释放给 DMA;DMA 在执行完搬运和数据发送之后,会对该描述符进行回写,提供时间戳及状态信息,相当于回调,告知发送状态。

Read-Format

在这里插入图片描述

Read Format 下的描述符如上图所示,主要包括两个 Buffer 指针、Buffer 长度信息和一些其他的控制信息。从上到下 4 个 Word 依次是 TDES0TDES3,我们一一展开介绍。

  • TDES0:

    • BUF1AP:Buffer1 的地址;
  • TDES1:

    • BUF2AP:Buffer2 的地址,但是我们一般不使用,包括 Infineon 官方的 MCAL 代码都是不用的;
  • TDES2:

    • IOC(31):Interrupt on Completion,完成中断标志位,packet 发送完之后会置位;
    • TTSE(30):Transmit Timestamp Enable,发送时间戳使能位;
    • B2L(29:16):Buffer2 的长度;
    • VTIR(15:14):VLAN 标签插入、替换标志位,VLAN 一般由上层处理,AUTOSAR 中也一般交给 EthIf 来管理,所以该位一般是 0;
    • B1L(13:0):Buffer1 的长度;
  • TDES3:

    • OWN(31):DMA 控制权标志位,该位置位表示 DMA 拥有该描述符的控制权,它会去读取相应的 Buffer,并回写该描述符,并将该位清除;
    • CTXT(30):常规描述符和增强描述符位,0 表示常规描述符;
    • FD(29):First Descriptor,表征第一个描述符,一般数据存在于多个 Buffer 时,有头部、连续描述符之分,我们一般使用连续 Buffer,只需要一个描述符,因此 FD 包括下面的 LD 一直都置位;
    • LD(28):Last Descriptor,表征是最后一个描述符;
    • CPC(27:26):CRC Pad 控制位,
    • SAIC(25:23):SA Insertion Control,源地址插入控制,可以配置让 MAC 层根据 MAC 地址寄存器自动修改源 MAC 地址,而不用上层指定;
    • SLOTNUMorTHL(22:19):Slot Number Control Bits in AV Mode,AV 模式下的槽数量控制位,用于上层 Header 信息的辅助处理,一般不使用;
    • RES_18(18):预留;
    • CIC/TPL(17:16):Aurix 提供了 TCP/IP 的 CheckSum 辅助计算功能,能够通过硬件计算为上层降低负载;
    • TPL(15):Reserved or TCP Payload Length;
    • FL/TPL(14:0):Packet Length or TCP Payload Length,一般用作 Packet 长度;

Write-Back Format

在这里插入图片描述

我们可以看到 Write-Back 格式的描述符包含了时间戳和状态位,状态位这里就不展开介绍了,感兴趣的读者可以翻阅手册进行查询。

2.3.3 发送流程介绍

然后我们就着描述符来介绍 GETH 的发送流程:

  1. 用户根据发送数据向描述符中写入信息,包括 Buffer 地址、长度等,然后将描述符中的 DMA 控制权标志位置位;

  2. 用户写入描述符尾指针寄存器,启动 DMA;(该操作是一个启动 DMA 的动作,即使描述符尾指针没有变动,也需要写一下)

  3. DMA 对所有的请求进行仲裁;

  4. DMA 根据当前描述符寄存器,从内存中读取描述符;

  5. DMA 通道从当前发送描述符指针指向的描述符开始遍历,直到以下条件满足,然后 DMA 进入 Suspend 状态,执行步骤 11:

    1. 遍历到的描述符属于 APP(TDES3 [31] = 0) ;
    2. 当前发送描述符指针等于描述符尾指针寄存器;
    3. 发生错误;
  6. 如果遍历到的描述符属于 DMA,则 DMA 从描述符中解析 Buffer 地址;

  7. DMA 根据解析到的 Buffer 地址,从系统内存中读取用户的发送数据,送到 MTL 进行发送;

  8. 如果 packet 被存放在多个 Buffer 里,并且使用了多个描述符,DMA 会立即读取下一个描述符,步骤 3 到 7 会重复直到 packet 中的所有数据都被传输到 MTL;

  9. packet 传输完成之后,如果 IEEE 标准规定的时间戳使能了,从 MTL 获取的发送时间戳将被回写到发送描述符(TDES0 和 TDES1),如果是多个描述符的 packet,则写到最后一个描述符中;相关的状态位会被写回到 TDES3,并且 DMA 控制位会被清空,APP 拿回描述符控制权;如果没有使能时间戳,则 DMA 不修改 TDES0 和 TDES1;

  10. 如果描述符中的发送完成中断标志位使能了,DMA 状态寄存器中的发送中断位会置位,DMA 回到步骤 3;

  11. 当用户向描述符尾指针寄存器写入任何值时,会启动 DMA 的 Polling,并回到步骤 3,并且下溢中断状态位被清零。如果用户通过清除 DMA 控制寄存器中的相应标志位来停止 DMA,则 DMA 进入 Stop 模式;

下面是对应的流程图:

在这里插入图片描述

也就是说,DMA 初始化之后,停留在左下角的 Suspend Tx DMA Queue 状态中进行等待,用户写入描述符尾寄存器之后 DMA 开始进行 Transmit 轮询,完成发送之后继续停留在 Suspend 状态中。当前发送描述符寄存器是描述符链表的关键句柄,DMA 每次完成一次发送后其会指向下一个描述符,末尾的描述符使用完之后会回到第一个描述符。

DMA 将数据传输到 MTL 之后,就会由硬件进行后续数据的打包和发送,参考前面 MAC 章节。

2.3.4 Receive Descriptor 接收描述符及接收流程介绍

接收描述符包括两种类型:常规描述符增强描述符。常规描述符同样有 Read-formatWrite-back format。用户按照 Read-format 格式,根据 Buffer 的实际容量配置完描述符之后,将描述符控制权释放给 DMA,DMA 在收到完整且通过校验的 packet 之后,会将数据搬运到描述符指定的接收 Buffer,随后将状态信息以 Write-back 格式写回到描述符。相比于发送描述符,接收描述符的回写内容比较多,因此它的状态回写会额外占用一个增强描述符,用于补充描述状态信息。

Read-format

在这里插入图片描述

Read-format 的接收描述符格式如上图,RDES0 包含的是接收 Buffer 的地址,RDES2 包含的是 Buffer2 或者头的地址,但是我们一般 packet 存放到一个 Buffer 里,RDES3 包含两个重要的位,一个是 DMA 控制权位 OWN,另一个是常规/增强描述符标志位 INTE

Write-Back Format

在这里插入图片描述

Write-back 格式的描述符见上图,可以看到其信息还是比较多的,但是前面也提到,VLAN 一般我们会交给上层处理,所以 RDES0 一般在 Write-back 中 DMA 不去修改它的值。

  • RDES0:

    • IVT(31:16):如果 RDES3 中的 RS0V 置位,则该内容为接收 packet 的 Inner VLAN 标签,否则为无效值;
    • OVT(31:16):如果 RDES3 中的 RS0V 置位,则该内容为接收 packet 的 Outer VLAN 标签,否则为无效值;
  • RDES1:

    • OPC(31:16):OAM Sub-Type 码,或 MAC 包控制操作码,取决于 RDES3 的 OAM Sub-Type CodeIf Bits 位域;
    • TD(15):Timestamp Dropped,标志着时间戳被捕获到但是由于溢出导致丢失;
    • TSA(14):Timestamp Available,时间戳有效标志,该位如果置位则下一个增强描述符的 RDES0 和 RDES1 的时间戳有效;
    • PV(13):PTP Version,PTP 版本;
    • PFT(12):PTP Packet type;
    • PMT(11:8):PTP Message Type;
    • IPCE(7):IP Payload Error;
    • IPCB(6):IP Checksum Bypass,仅当使用了 IP Checksum 功能时有效;
    • IPV6(5):IPv6 Header Present;
    • IPV4(4):IPv4 Header Present;
    • IPHE(3):IP Header Error;
    • PT(2:0):Payload Type,指示上层包类型,如 UDP、TCP、ICMP;
  • RDES2:

    • Rsvd(31:27):Reserved;
    • MADRM(26:19):MAC 地址或者 Hash 值;
    • HF(18):Hash Filter Status;
    • DAF(17):Destination Address Filter Fail,指示目标 MAC 地址过滤失败;
    • SAF(16):SA Address Filter Fail,指示源 MAC 地址过滤失败
    • OTS(15):VLAN filter status;
    • ITS(14):Inner VLAN Tag filter status;
    • Rsvd(13:11):Reserved;
    • ARPNR(10):ARP Reply Not Generated,指示 MAC 是否进行 ARP 回复;仅当使用了 IPv4 ARP Offload 功能时有效;
    • HL(9:0):L3/L4 Header Length,有些情况下 packet 会将上层的头和数据分开存放到不同的 Buffer 中,该位域表征分割之后 Header 的长度;
  • RDES3:

    • OWN(31):DMA 控制权标志位,1 表示 DMA 拥有该标识符的控制权;
    • CTXT(30):常规/增强描述符标志位,1 表示增强描述符;
    • FD(29):First Descriptor,首描述符;
    • LD(28):Last Descriptor,末尾描述符;注意,额外的增强描述符不算在内;
    • RS2V(27):RDES2 有效位,0 表示该描述符的 RDES2 未使用;
    • RS2V(26):RDES1 有效位,0 表示该描述符的 RDES1 未使用;
    • RS2V(25):RDES0 有效位,0 表示该描述符的 RDES0 未使用;
    • CE(24):CRC 错误标志位;
    • GP(23):Giant Packet;
    • RWT(22):Receive Watchdog Timeout,表示接收超时;
    • OE(21):Overflow Error,表示 Rx FIFO 溢出;
    • RE(20):Receive Error,gmii_rxer_i signal 信号位置位时该寄存器置位,同时该位也可表征半双工模式下的载波侦听错误;
    • DE(19):Dribble Bit Error;
    • LT(18:16):Length/Type Field;
    • ES(15):Error Summary;
    • PL(14:0):Packet Length,表征收到的 packet 的数据长度,包含 CRC;

Receive Context Descriptor

在这里插入图片描述

如前所述,接收的回写需要在常规描述符之后跟随一个额外的增强描述符,所以这里介绍下接收增强描述符。它的 RDES0 是时间戳的低位,RDES1 是时间戳的高位,RDES3 中包含一个 DMA 控制权标志位 OWN 和一个常规/增强类型标志位 CTXT。

2.3.5 接收流程介绍

接收流程和发送流程类似,都是 APP 操作描述符,然后等 DMA 操作数据,区别在于 APP 需要通过轮询或中断来判断是否有数据接收,并进行处理,然后重置描述符,将 Buffer 还给 DMA 用于后续数据接收。

  1. 用户根据接收 Buffer 地址填充接收描述符,然后将描述符中的 DMA 控制权标志位置位;
  2. 如果 DMA 已经完成初始化,则会在当前接收描述符指针和接收描述符尾指针之间进行遍历,查找可用的描述符,如果没有找到,则进入 Suspend 状态,并执行步骤 11;
  3. DMA 读取可用的接收描述符然后解析接收 Buffer 地址;
  4. 如果当前描述符的时间戳使能了且上一个描述符的时间戳可用,DMA 将时间戳写入当前描述符的 RDES0 和 RDES1,并将常规/增强描述符标志位置位,就是前文所说的跟随的额外增强描述符;
  5. DMA 处理接收到的数据并将其放置到描述符指定的 Buffer 中;
  6. 如果当前 packet 没有接收完全,DMA 将当前描述符暂时关闭,然后到步骤 10;
  7. DMA 将 MTL 传递过来的相关状态位写入到当前描述符中,清除 DMA 控制权标志位,并将 Last Descriptor 位置位;
  8. DMA 将帧长度写入到 RDES3 中,将 VLAN TAG 写入到 RDES0 中,并写入 MAC control frame opcode、OAM control frame code、extended status information 到 RDES1 中;
  9. 如果时间戳使能了,DMA 将接收时间戳值暂存。后续将其写入到下一个增强描述符中(如步骤 4 描述);
  10. 如果描述符链表中仍有描述符需要处理,执行步骤 3,否则进入 Suspend 状态,执行步骤 11;
  11. DMA 进入 Suspend 状态,等待用户通过写接收描述符尾寄存器进行轮询请求。

下面是对应的流程图:

在这里插入图片描述

总结下来,就是用户给了指定的 Buffer,然后将对应描述符的控制权交给 DMA,然后轮询或者中断查看描述符状态,如果有收到 packet,将数据传给上层进行处理,然后重置下描述符继续交给 DMA 去接收数据。

2.4 PHY 控制接口

对于 MCU 来说,PHY 是 MCU 的外设,除了使用 RMII、RGMII 等接口进行数据传输以外,还需要对其进行控制。PHY 作为信号收发器,其内部逻辑比其他收发器如 CAN 收发器要复杂得多。其控制逻辑一般是使用 SMI 协议,包含一个 MDC 主机时钟线,和一根 MDIO 半双工数据线。

在这里插入图片描述

SMI 协议的传输相对还是比较简单的,它有读和写两种访问形式:

在这里插入图片描述

结构包括一个类似前导码的 idle 位,一个起始位,读写标志位,操作码,PHY 地址,目的寄存器,半双工控制转换位,数据和结尾的 idle 位。

因为一个 SMI 接口可以控制多个 PHY,所以硬件连接上 PHY 是需要地址的,具体参考硬件设计说明。

PHY 的读写控制是有指定序列的,虽然大同小异,但是还是要根据其手册编写对应代码。下面是英飞凌 iLLD 中使用的读 PHY 寄存器的 Demo 代码,具体的逻辑可以参考 DP83825i 手册。其中的 Eth_WriteMii 和 Eth_ReadMii 就是 MAC 的接口。

Std_ReturnType IfxGeth_Eth_Phy_Dp83825i_read_mdio_reg(uint8 EthCtrl, uint16 regAddr, uint16 *pdata)
{
    Std_ReturnType ret = E_OK;
    uint16 regDomain;

    if(regAddr<=0x1F){
        ret |= Eth_ReadMii(EthCtrl, DP83_TRCVID, (uint8)regAddr, pdata);
    }else{
        regDomain = DP83_GetRegDomain(regAddr);
        ret |= Eth_WriteMii(EthCtrl, DP83_TRCVID, DP83_REGCR, regDomain);
        ret |= Eth_WriteMii(EthCtrl, DP83_TRCVID, DP83_ADDAR, regAddr);
        ret |= Eth_WriteMii(EthCtrl, DP83_TRCVID, DP83_REGCR, regDomain|DP83_NOINC);
        ret |= Eth_ReadMii(EthCtrl, DP83_TRCVID, DP83_ADDAR, pdata);
    }
    return ret;
}

2.5 调试相关寄存器

这里介绍几个比较重要的寄存器,调试过程中使用还是非常有必要的。下面寄存器的属性比较固定,就不一一解释了,TX 表示发送,RX 表示接收,GOOD_BAD 表示所有包,GOOD 表示成功的包,OCTET 表示字节数,Packet 表示包数:

  • TX_OCTET_COUNT_GOOD_BAD
  • TX_OCTET_COUNT_GOOD
  • TX_PACKET_COUNT_GOOD_BAD
  • TX_PACKET_COUNT_GOOD
  • RX_OCTET_COUNT_GOOD_BAD
  • RX_OCTET_COUNT_GOOD
  • RX_PACKETS_COUNT_GOOD_BAD
  • RX_RECEIVE_ERROR_PACKETS
  • RX_CRC_ERROR_PACKETS

这里需要注意的是,接收端的计数是位于 VLAN 过滤器和 MAC 地址过滤器之后的,对于 MAC 地址不符的帧上述 Counter 都不会累加。

2.6 引脚与中断连接

对于不同的介质独立接口,如 RMII、MII、RGMII,有不同的连接定义,也需要不同的数据时钟。另外除了 RGMII 需要输出发送时钟以外,MCU 的时钟都需要外部进行输入。SMI 协议的引脚是固定的,一根时钟线 MDC,和一根半双工数据线 MDIO,我们只需要根据硬件设计进行配置接口。

下面我们以 RMII 接口为例,来介绍如何查询接口引脚,以进行相关配置。我们先来看 RMII 的引脚定义,下图是 DP83825i 的 RMII Master 信号定义,本文只关注 MAC 这一侧:

在这里插入图片描述

  • TX_EN:TX 使能,发送数据时拉高;
  • TX_D[1:0]:发送数据线,RMII 有两根发送数据线;
  • RX_CLK:接收时钟,不使用
  • RX_DV:接收数据有效位,不使用;
  • RX_ER:接收错误位,不使用;
  • RX_D:接收数据线,RMII 有两根接收数据线;
  • CRS_DV:载波侦听位和接收数据有效位的结合线,使用该线不需要 RX_D 线;
  • 50-MHz Reference Clock:50MHz 参考时钟,需要 PHY 或者外部晶振提供;

对于这些引脚,我们在 MCAL 中是可以直接下拉选择的,但是对于某些工具如 Vector DaVinci 配置工具,是没法直接选择的,所以我们还是需要掌握芯片内部的配置原理。

GETH 模块的引脚配置,在 GPCTL(General Purpose Control Register)寄存器中,其中位域 ALTIx(x=0~10)用来配置对应的引脚,这些配置我们不一定需要全部去配,因为它包含了 RMII、RGMII 等所有支持的配置,因此我们只需要根据我们的接口类型,配置我们需要的引脚即可。它的定义如下:

在这里插入图片描述

然后我们来到芯片手册(注意是特定型号的手册,类似 TC37x UserManual,不是 TC3XX Family UserManual)中,来到 42.4 Connectivity 章节(本文使用的是 TC37X 手册),Table 348 Connections of GETH。

比如我要配置 RXD0,查询到该数据线支持连接的引脚 RXD0A(TC37X 系列只有一个,如果其他型号会有 RXD0BRXD0C 等供选择):

在这里插入图片描述

因此 GPCTLALTI6 位域设置为 0(A 对应 0,以此类推),在 Port 模块中配置 P11.10 即可,可参考之前发布的 Port 相关的文章。对于发送数据,GETH 模块会在所有可选的输出脚中输出该信号,因此不需要在 GETH 中配置,只取决于 Port 中是否将该引脚分配给 GETH 使用。

这里需要额外注意的是,对于数据发送信号,Pin 的配置最下面有一个 PortPinControllerSelect 选项需要使能。

在这里插入图片描述

另外 MDIO 作为半双工数据引脚,引脚方向需要配置为 OUT

中断连接同样也是查询芯片用户手册:

在这里插入图片描述

3 MCAL配置及代码示例

本文使用 TC375 芯片,以 RMII 100M 接口为例,对 MCAL 配置和代码进行说明。

3.1 General

在这里插入图片描述

General 页面中大多是一些接口使能配置和权限,这里只对一些特殊项进行说明:

  • EthTimeoutCount:该参数定义了 WriteMii、复位 DMA 等访问的超时时间;
  • EthDmaSwResetWaitCycle:该参数定义了 DMA 复位之后的等待时钟周期;

在这里插入图片描述

GETH 模块具有填充上层如网络层 Checksum 的功能,可以在这里进行使能。

3.2 EthCtrlConfig

我这里使用的 AUTOSAR 版本是 AR4.2.2,如果是 AR4.4.0,controller 这里参数会稍微多一点,但是整体逻辑没有大改。

在这里插入图片描述

在这里插入图片描述

  • EthSpeed:这里配置了信号收发频率,100M 或 10M,硬件内部会自动计算分频,无需修改外部输入时钟;
  • EthPhyInterface:MII 接口模式,这里配置 RMII;
  • EthOpMode:信号模式,全双工;
  • EthCtrlPhyAddress:源 MAC 地址;
  • EthCtrlRxBufLenByte:接收数据 Buffer 尺寸,这里配最大值 1522;
  • EthCtrlTxBufLenByte:发送数据 Buffer 尺寸,这里配最大值 1522;
  • EthRxBufTotal:接收 Buffer 数量,一般 4 个就够了;
  • EthTxBufTotal:发送 Buffer 数量,一般 4 个就够了;
  • EthMdioAlternateInput:MDIO 接口输入选择,下面几个接口相同,可参考上文连接章节,不再一一赘述;
  • EthCtrlEnableMii:Mii 接口使能,控制 PHY 用的,勾选;
  • EthCtrlEnableRxInterrupt:接收中断使能,一般建议接收使用轮询,中断模式下外部数据发送较快的时候系统不可控;
  • EthCtrlEnableTxInterrupt:发送完成中断,MCAL 给的中断里主要是更新 Buffer 的使用状态,如果不用中断需要调用 TxConfirmation 来轮询 Buffer 状态,建议使用中断;
  • EthSkewTxClockDelay:Tx 发送延时,单位 222ps,RGMII 下才需要使用;
  • EthSkewRxClockDelay:Rx 发送延时,单位 222ps,RGMII 下才需要使用;
  • EthCtrlEnableCrcStripping:CRC 字段剥离配置,如果勾选 MAC 帧的 CRC 将不再传递到上层;
  • EthMDCClockFrequency:SMI 接口 MDC 时钟线的频率,一般配置 2.5M,太高 PHY 会不支持;

到这里配置就结束了,是不是很简单,但这只是以太网调试的开始。

3.3 代码示例

本文示例内容包括初始化、数据发送、数据接收,均使用 Infineon MCAL 标准接口。

3.3.1 初始化

首先是初始化:

Eth_Init(&Eth_Config);            /* 模块初始化 */
    IfxGeth_Eth_Phy_Dp83825i_init();    /* PHY初始化,这里不展开介绍了 */
    
    /* 设置Controller Mode为Active */
    Eth_SetControllerMode(Eth_17_GEthMacConf_EthCtrlConfig_EthCtrlConfig_0, ETH_MODE_ACTIVE);
3.3.2 数据发送

信号发送方面只需要先申请 Buffer,然后填充对应的数据,进行发送即可,如果没有使能发送中断,需要周期调用 Eth_TxConfirmation。发送的时候 Buffer 从网络层数据开始填充,目的 MAC 地址和报文类型以入参形式传递。这里注意 bufferPtr 是用来获取 Buffer 的地址,因此入参要取指针的地址。

uint8               *bufferPtr;
Eth_BufIdxType      bufferIdx;

bufRet = Eth_ProvideTxBuffer(Eth_17_GEthMacConf_EthCtrlConfig_EthCtrlConfig_0, &bufferIdx, &bufferPtr, &length);
if(bufRet == BUFREQ_OK){
    /* Buffer填充,这里填充的数据不包括目的MAC地址、源MAC地址和报文类型,仅包含网络层数据报内容 */
}
txRet = Eth_Transmit(Eth_17_GEthMacConf_EthCtrlConfig_EthCtrlConfig_0, bufferIdx, frameType, TRUE, numOfBufToLow, &desPhyAddr[0]);

我这里使用的是发送 UDP 报文,发送 Buffer 地址为 0x70002906,Buffer 数据长度为 38 个字节,仅包含网络层内容,内存如下:

在这里插入图片描述

然后我们观察数据包,内容同上(以太网最小 64 字节,多出的 8 字节 0 为填充):

在这里插入图片描述

3.3.3 数据接收

对于接收来说,首先需要进行轮询,以更新描述符,以及进行数据处理,放到周期任务中即可。

Eth_RxStatusType rxStatus;
Eth_Receive(Eth_17_GEthMacConf_EthCtrlConfig_EthCtrlConfig_0, &rxStatus);

然后接收下层会进行回调,GETH 调用 EthIf_RxIndication 通知上层,本文这里集成了 Lwip,所以接入了对应的接口。另外注意这里如果接收用的是中断,是在中断中进行回调,处理逻辑需要注意。

void EthIf_RxIndication( uint8 CtrlIdx, Eth_FrameType FrameType, boolean IsBroadcast, const uint8* PhysAddrPtr, Eth_DataType* DataPtr, uint16 LenByte )
{
    netif_Indication(CtrlIdx,FrameType,IsBroadcast,PhysAddrPtr,DataPtr,LenByte);
}

然后我们发送一个 PING 包给控制器,电脑端观察包内容(已进行过 ARP 的 MAC 地址查找):

在这里插入图片描述

然后我们观察 EthIf_RxIndication 输入的内容,首先我们看传参:

在这里插入图片描述

传参这里帧类型为 IPv4 的 0x0800,源 MAC 地址存在 0x70000516,数据地址为 0x7000051E,数据长度为 64 字节,这里起始 GETH 硬件是将 MAC 帧整包传上来的,从 0x70000510 开始,只是函数接口形式将包进行了拆分:

在这里插入图片描述

相对于 PING 包的原始内容,末尾多了 4 字节的 CRC 字段,这是因为电脑端 WireShark 没有打开 CRC 观测。

4 小结

本文详细介绍了英飞凌 Aurix TC3XX 中的 GETH 模块,对其内部硬件结构和原理进行了分层阐述,并结合描述符机制对发送和接收流程进行了说明。最后对 MCAL 中 GETH 模块的配置进行了介绍,并通过 MCAL 示例代码对数据收发做了演示。

参考资料

  1. Infineon-AURIX_TC3xx_Part2-UserManual-v02_00-EN.pdf
  2. Infineon-AURIX_TC37x-UserManual-v02_00-EN.pdf
  3. DWC_ether_qos_databook.pdf

如您有任何问题,欢迎关注公众号【TechLink汽车软件】与我们联系!

  • 24
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值