实现网口功能需要:ETH+PHY
image.png

ETH的接口

  • SMI
    • 作用:管理接口,用于访问PHY 芯片寄存器
  • MII / RMII(两个工业标准接口)
    • 作用:(用于与外部 PHY 芯片连接、MAC层数据包传输)
    • 介质独立接口(MII)
    • 简化介质独立接口(RMII)


ETH功能框图

image.png
ETH 有专用的 DMA 控制器,它通过 AHB 主从接口与内核和存储器相连,
AHB 主接口用于控制数据传输,
AHB 从接口用于访问“控制与状态寄存器”(CSR)空间。
数据发送流程:
将数据有存储器以 DMA 传输到发送 TX FIFO 进行缓冲,
然后由 MAC 内核发送
数据接收流程:
RX FIFO 先接收以太网数据帧,再由 DMA 传输至存储器。

接口组成

SMI接口

:::info

:::

作用:用来控制、读取PHY的寄存器。

  • SMI 是 MAC 内核访问 PHY 寄存器标志接口,
  • 它由两根线组成,数据线 MDIO 和时钟线 MDC。
  • SMI 支持访问 32 个 PHY,这在设备需要多个网口时非常有用,不过一般设备都 只使用一个 PHY。

SMI帧格式

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

MII接口

介质独立接口 (MII) 定义了 10 Mbit/s 和 100 Mbit/s 的数据传输速率下 MAC 子层与 PHY 之间的互连
介质独立接口(MII)用于连接 MAC 控制器和 PHY 芯片,提供数据传输路径。

MII 需要 16 根通信线,RMII 只需 7 根通信,在功能上是相同的。
image.png

TX_CLK 数据发送时钟线。标称速率为 10Mbit/s 时为 2.5MHz;速率为 100Mbit/s 时 为 25MHz。RMII 接口没有该线。
RX_CLK 数据接收时钟线。标称速率为 10Mbit/s 时为 2.5MHz;速率为 100Mbit/s 时为 25MHz。RMII 接口没有该线。
TX_EN 数据发送使能。在整个数据发送过程保存有效电平。
TXD[3:0]或 TXD[1:0] 数据发送数据线。对于 MII 有 4 位,RMII 只有 2 位。只有在TX_EN 处于有效电平数据线才有效。
CRS 载波侦听信号,由 PHY 芯片负责驱动,当发送或接收介质处于非空闲状态时使 能该信号。在全双工模式该信号线无效。
COL 冲突检测信号,由 PHY 芯片负责驱动,检测到介质上存在冲突后该线被使能,并且保持至冲突解除。在全双工模式该信号线无效。
RXD[3:0]或 RXD[1:0] 数据接收数据线,由 PHY 芯片负责驱动。对于 MII 有 4 位,RMII 只有 2 位。在 MII 模式,当 RX_DV 禁止、RX_ER 使能时,特定的 RXD[3:0]值用于传输来自 PHY 的特定信息。
RX_DV 接收数据有效信号,功能类似 TX_EN,只不过用于数据接收,由 PHY 芯片负责驱动。对于 RMII 接口,是把 CRS 和 RX_DV 整合成 CRS_DV 信号线,当介质处于不同状态时会自切换该信号状态。
RX_ER 接收错误信号线,由 PHY 驱动,向 MAC 控制器报告在帧某处检测到错误。
REF_CLK 仅用于 RMII 接口,由外部时钟源提供 50MHz 参考时钟。

RMII接口

RMII时钟源:通常使用50MHZ的时钟驱动PHY或使用嵌入式PLL生成50MHZ频率来驱动PHY。 :::info RMII 接口是 MII接口的简化版本 ::: 质独立接口 (RMII) 规范降低了 10/100 Mbit/s 下微控制器以太网外设与外部 PHY 间的 引脚数。
根据 IEEE 802.3u 标准, MII 包括 16 个数据和控制信号的引脚。
RMII 规范将引脚 数减少为7 个(引脚数减少 62.5%)。

image.png

MAC 数据包发送和接收

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

MAC 数据包发送

MAC 数据帧发送全部由 DMA 控制

  • 流程
    • 从系统存储器读取的以太网帧由 DMA 推入 FIFO
    • 然后将帧弹出并传输到 MAC 内核
    • 帧传输结束后,从 MAC 内核获取发送状态并传回 DMA

发送正常的情况:
在检测到 SOF(Start Of Frame)时,MAC 接收数据并开始 MII 发送。
在 EOF(End Of Frame)传输到 MAC 内核后,内核将完成正常的发送,然后将发送状态返回给DMA。


发送错误的情况:
如果在发送过程中发送常规冲突,MAC 内核将使发送状态有效,然后接受并丢弃所有后续数据, 直至收到下一 SOF。
检测到来自 MAC 的重试请求时,应从 SOF 重新发送同一帧。
如果发送期间未连续提供数据,MAC 将发出下溢状态。
在帧的正常传输期间,如果 MAC 在未获得前一帧的 EOF 的情况下接收到 SOF,则将忽略该 SOF 并将新的帧视为前一帧的延续。

MAC数据包接收

  • 流程
    • MAC 接收到的数据包填充 RX FIFO
    • 达到 FIFO 设定阈值后请求 DMA 传输。

默认直通模式:

  • 当 FIFO 接收到 64 个字节(使用ETH_DMAOMR 寄存器中的 RTC 位配置)或完整的数据包时,数据将弹出,其可用性将通知给DMA。
  • DMA 向 AHB 接口发起传输后, 数据传输将从 FIFO 持续进行,直到传输完整个数据包。
  • 完成 EOF 帧的传输后,状态字将弹出并发送到 DMA 控制器。

:::info 存储转发模式
通过 ETH_DMAOMR 寄存器中的 RSF 位配置

仅在帧完全写入 Rx FIFO 后才可读出帧。 :::

MAC过滤

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

针对目标地址过滤可以有三种,分别是单播、多播和广播目标地址过滤;

针对源地址过滤就只有单播源地址过滤。

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

以太网DMA描述符

F407有一个以太网专用的DAM,DMA可以在CPU完全不干预的情况下,
通过描述符有效地将数据从源传送到目标,接收缓冲区和发送缓冲区的数据都可以通过以太网DMA来传送。

一个用于接收,一个用于发送。

描述符是一种链表,最后一个描述符会指回第一个描述符以构成环形结构。
描述符列表位于主机的物理存储空间,两个列表的基址分别写入ETH_DMARDLAR寄存器和ETH_DMATDLAR寄存器中。每个描述符最多可指向两个缓冲区,

描述符的类型

描述符有分为增强描述符常规描述符,平常使用常规描述符。

描述符的结构

  • 环形结构
  • 链接结构

image.png
在ST提供的以太网驱动库stm32f4x7_eth.c中使用是链接结构,链接结构如下
image.png :::info 1、一个以太网数据包可以跨越一个或多个DMA描述符
2、一个DMA描述符只能用于一个以太网数据包
3、DMA描述符列表中的最后一个描述符指向第一个,形成链式结构!
:::

描述符的结构体

  1. ypedef struct {
  2. __IO uint32_t Status; //状态
  3. uint32_t ControlBufferSize; //控制和buffer1,buffer2的长度
  4. uint32_t Buffer1Addr; //buffer1地址
  5. uint32_t Buffer2NextDescAddr; //buffer2地址或下一个描述符地址
  6. //一下只有增强的以太网DMA描述符含有
  7. #ifdef USE_ENHANCED_DMA_DESCRIPTORS
  8. uint32_t ExtendedStatus; //增强描述符状态
  9. uint32_t Reserved1; //保留
  10. uint32_t TimeStampLow; //时间戳低位
  11. uint32_t TimeStampHigh; //时间戳高位
  12. #endif
  13. } ETH_DMADESCTypeDef;

常规Tx DMA描述符

image.png
描述符中TDES0的bit20用来表示描述符中的第二个地址是用来保存下一个描述符地址还是第二个缓冲区的地址,

常规Rx DMA描述符

image.png
常规Rx DMA描述符中RDES1的bit14用来表示描述符中的第二个地址是用来保存一个描述符地址还是第二个缓冲区的地址。

应用

在stm32f4x7_eth.c中定义了两个DMA描述符数组,一个用于DMA接收,一个用于DMA发送,如下:

  1. __align(4) ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB];
  2. __align(4) ETH_DMADESCTypeDef DMATxDscrTab[ETH_TXBUFNB];

语雀内容

数据缓冲区在哪里?这个数据缓冲区也是定义为数组的,如下:

  1. __align(4) uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE];
  2. __align(4) uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE];

ETH结构体

  1. typedef struct {
  2. /**
  3. @brief /*MAC
  4. */
  5. uint32_t ETH_AutoNegotiation; // 自适应功能
  6. uint32_t ETH_Watchdog; // 以太网看门狗
  7. uint32_t ETH_Jabber; // jabber 定时器功能
  8. uint32_t ETH_InterFrameGap; // 发送帧间间隙
  9. uint32_t ETH_CarrierSense; // 载波侦听
  10. uint32_t ETH_Speed; // 以太网速度
  11. uint32_t ETH_ReceiveOwn; // 接收自身
  12. uint32_t ETH_LoopbackMode; // 回送模式
  13. uint32_t ETH_Mode; // 模式
  14. uint32_t ETH_ChecksumOffload; // 校验和减荷
  15. uint32_t ETH_RetryTransmission; // 传输重试
  16. uint32_t ETH_AutomaticPadCRCStrip; // 自动去除 PAD 和 FCS 字段
  17. uint32_t ETH_BackOffLimit; // 后退限制
  18. uint32_t ETH_DeferralCheck; // 检查延迟
  19. uint32_t ETH_ReceiveAll; // 接收所有 MAC 帧
  20. uint32_t ETH_SourceAddrFilter; // 源地址过滤
  21. uint32_t ETH_PassControlFrames; // 传送控制帧
  22. uint32_t ETH_BroadcastFramesReception; // 广播帧接收
  23. uint32_t ETH_DestinationAddrFilter; // 目标地址过滤
  24. uint32_t ETH_PromiscuousMode; // 混合模式
  25. uint32_t ETH_MulticastFramesFilter; // 多播源地址过滤
  26. uint32_t ETH_UnicastFramesFilter; // 单播源地址过滤
  27. uint32_t ETH_HashTableHigh; // 散列表高位
  28. uint32_t ETH_HashTableLow; // 散列表低位
  29. uint32_t ETH_PauseTime; // 暂停时间
  30. uint32_t ETH_ZeroQuantaPause; // 零时间片暂停
  31. uint32_t ETH_PauseLowThreshold; // 暂停阈值下限
  32. uint32_t ETH_UnicastPauseFrameDetect; // 单播暂停帧检测
  33. uint32_t ETH_ReceiveFlowControl; // 接收流控制
  34. uint32_t ETH_TransmitFlowControl; // 发送流控制
  35. uint32_t ETH_VLANTagComparison; // VLAN 标记比较
  36. uint32_t ETH_VLANTagIdentifier; // VLAN 标记标识符
  37. /**
  38. * @brief / * DMA
  39. */
  40. uint32_t ETH_DropTCPIPChecksumErrorFrame; // 丢弃 TCP/IP 校验错误帧
  41. uint32_t ETH_ReceiveStoreForward; // 接收存储并转发
  42. uint32_t ETH_FlushReceivedFrame; // 刷新接收帧
  43. uint32_t ETH_TransmitStoreForward; // 发送存储并并转发
  44. uint32_t ETH_TransmitThresholdControl; // 发送阈值控制
  45. uint32_t ETH_ForwardErrorFrames; // 转发错误帧
  46. uint32_t ETH_ForwardUndersizedGoodFrames; // 转发过小的好帧
  47. uint32_t ETH_ReceiveThresholdControl; // 接收阈值控制
  48. uint32_t ETH_SecondFrameOperate; // 处理第二个帧
  49. uint32_t ETH_AddressAlignedBeats; // 地址对齐节拍
  50. uint32_t ETH_FixedBurst; // 固定突发
  51. uint32_t ETH_RxDMABurstLength; // DMA 突发接收长度
  52. uint32_t ETH_TxDMABurstLength; // DMA 突发发送长度
  53. uint32_t ETH_DescriptorSkipLength; // 描述符跳过长度
  54. uint32_t ETH_DMAArbitration; // DMA 仲裁
  55. } ETH_InitTypeDef;

ETH_Watchdog:

以太网看门狗功能选择,可选使能或禁止,它设定以太网 MAC 配置寄存器(ETH_MACCR)的 WD 位的值。如果设置为 1,使能看门狗,在接收 MAC 帧超过 2048 字节时自动切断后面数据,一般选择使能看门狗。如果设置为 0,禁用看门狗,最长可接收 16384 字节的帧。