主要内容
本文主要介绍Infineon Aurix2G TC3XX系列芯片GETH模块硬件原理,MCAL相关配置和代码示例。
-
模块简介
-
功能介绍
2.1 车载以太网硬件框架
2.2 GETH总览
2.3 Descriptors描述符机制
2.4 PHY控制接口
2.5 调试相关寄存器
2.6 引脚与中断连接
-
MCAL配置及代码示例
3.1 General
3.2 EthCtrlConfig
3.3 代码示例
-
小结
1
模块介绍
随着汽车科技的不断发展,车载以太网已经成为许多车型的标配技术。相比传统的汽车通信网络技术,车载以太网具有更高的带宽和数据传输速度,这使得车辆内部的各个系统可以更快地响应和交换信息。此外,车载以太网还能够支持更多的设备连接,从而满足现代汽车日益增长的智能化和互联需求。
英飞凌Aurix2G TC3XX系列芯片的GETH模块采用的是新思科技(Synopsys)的内核,全称DesignWare Cores Ethernet Quality-of-Service(DWC_ether_qos)。DWC_ether_qos通常用于嵌入式系统或网络设备中,可以帮助实现更可靠的数据传输、更低的延迟和更好的网络性能。
TC3XX系列中除了旗舰的TC39X系列具有两个GETH模块,即支持两路MAC,其他大部分型号都只支持一路MAC。支持10Mbps100Mbps的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系列支持MII、RMII、RGMII等媒体独立接口,从图中我们可以看出,它们作为可选接口出现,通过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,计算公式为:
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_TXDESC到TXDESC_TAIL_POINTER(左闭右开)的所有描述符,执行发送操作。当然只有第二个描述符的DMA归属位置位了,到第三个时DMA会自动Suspend,详细流程我们后面再讨论。
2.3.2 Transmit Descriptors发送描述符
这里我们只介绍常规描述符。
常规描述符有两种状态,Read-format和Write-back Format。当我们需要向外部发送数据,要按照Read-format向其中写入Buffer地址及控制信息,然后将其控制权释放给DMA;DMA在执行完搬运和数据发送之后,会对该描述符进行回写,提供时间戳及状态信息,相当于回调,告知发送状态。
Read-Format
Read Format下的描述符如上图所示,主要包括两个Buffer指针、Buffer长度信息和一些其他的控制信息。从上到下4个Word依次是TDES0到TDES3,我们一一展开介绍。
-
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的发送流程:
-
用户根据发送数据向描述符中写入信息,包括Buffer地址、长度等,然后将描述符中的DMA控制权标志位置位;
-
用户写入描述符尾指针寄存器,启动DMA;(该操作是一个启动DMA的动作,即使描述符尾指针没有变动,也需要写一下)
-
DMA对所有的请求进行仲裁;
-
DMA根据当前描述符寄存器,从内存中读取描述符;
-
DMA通道从当前发送描述符指针指向的描述符开始遍历,直到以下条件满足,然后DMA进入Suspend状态,执行步骤11:
-
遍历到的描述符属于APP(TDES3 [31] = 0) ;
-
当前发送描述符指针等于描述符尾指针寄存器;
-
发生错误;
-
如果遍历到的描述符属于DMA,则DMA从描述符中解析Buffer地址;
-
DMA根据解析到的Buffer地址,从系统内存中读取用户的发送数据,送到MTL进行发送;
-
如果packet被存放在多个Buffer里,并且使用了多个描述符,DMA会立即读取下一个描述符,步骤3到7会重复直到packet中的所有数据都被传输到MTL;
-
packet传输完成之后,如果IEEE标准规定的时间戳使能了,从MTL获取的发送时间戳将被回写到发送描述符(TDES0和TDES1),如果是多个描述符的packet,则写到最后一个描述符中;相关的状态位会被写回到TDES3,并且DMA控制位会被清空,APP拿回描述符控制权;如果没有使能时间戳,则DMA不修改TDES0和TDES1;
-
如果描述符中的发送完成中断标志位使能了,DMA状态寄存器中的发送中断位会置位,DMA回到步骤3;
-
当用户向描述符尾指针寄存器写入任何值时,会启动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-format和Write-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用于后续数据接收。
-
用户根据接收Buffer地址填充接收描述符,然后将描述符中的DMA控制权标志位置位;
-
如果DMA已经完成初始化,则会在当前接收描述符指针和接收描述符尾指针之间进行遍历,查找可用的描述符,如果没有找到,则进入Suspend状态,并执行步骤11;
-
DMA读取可用的接收描述符然后解析接收Buffer地址;
-
如果当前描述符的时间戳使能了且上一个描述符的时间戳可用,DMA将时间戳写入当前描述符的RDES0和RDES1,并将常规/增强描述符标志位置位,就是前文所说的跟随的额外增强描述符;
-
DMA处理接收到的数据并将其放置到描述符指定的Buffer中;
-
如果当前packet没有接收完全,DMA将当前描述符暂时关闭,然后到步骤10;
-
DMA将MTL传递过来的相关状态位写入到当前描述符中,清除DMA控制权标志位,并将Last Descriptor位置位;
-
DMA将帧长度写入到RDES3中,将VLAN TAG写入到RDES0中,并写入MAC control frame opcode、OAM control frame code、extended status information到RDES1中;
-
如果时间戳使能了,DMA将接收时间戳值暂存。后续将其写入到下一个增强描述符中(如步骤4描述);
-
如果描述符链表中仍有描述符需要处理,执行步骤3,否则进入Suspend状态,执行步骤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系列只有一个,如果其他型号会有RXD0B、RXD0C等供选择):
因此GPCTL中ALTI6位域设置为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示例代码对数据收发做了演示。
参考资料
-
Infineon-AURIX_TC3xx_Part2-UserManual-v02_00-EN.pdf
-
Infineon-AURIX_TC37x-UserManual-v02_00-EN.pdf
-
DWC_ether_qos_databook.pdf
·END·
若本文对您有帮助,欢迎关注我们
原文始发于微信公众号(汽车电子嵌入式):英飞凌Aurix2G TC3XX GETH模块详解
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论