LWIP教程 00:从网线上的电信号到 lwIP——PHY、MAC、DMA 与 `netif` 的完整边界


title: 00-ethernet-physical-layer-and-network-stack

categories:

  • LWIP
    tags:
  • LWIP
    abbrlink: 3f0de708
    date: 2026-10-03 16:27:36

教程 00:从网线上的电信号到 lwIP------PHY、MAC、DMA 与 netif 的完整边界

摘要:从初学者视角建立 Ethernet 的 PHY、MAC 与 Frame 心智模型,再沿 PHY→MAC→DMA/Driver→pbuf→netif 解释 MCU 与 lwIP 的真实边界。

文章目录

  • [教程 00:从网线上的电信号到 lwIP------PHY、MAC、DMA 与 `netif` 的完整边界](#教程 00:从网线上的电信号到 lwIP——PHY、MAC、DMA 与 netif 的完整边界)
    • [1. 建议提前阅读:三份资料分别解决什么问题](#1. 建议提前阅读:三份资料分别解决什么问题)
    • [2. 先把 Ethernet 放进完整网络路径](#2. 先把 Ethernet 放进完整网络路径)
    • [3. 一个 Ethernet Frame 至少要先看懂什么](#3. 一个 Ethernet Frame 至少要先看懂什么)
    • [4. PHY 与 MAC:一个负责物理信号,一个负责 Frame](#4. PHY 与 MAC:一个负责物理信号,一个负责 Frame)
    • [5. MAC 收到 Frame 后,为什么还需要 DMA 和 Descriptor](#5. MAC 收到 Frame 后,为什么还需要 DMA 和 Descriptor)
    • [6. `pbuf` 与 DMA Buffer 不是同一个概念](#6. pbuf 与 DMA Buffer 不是同一个概念)
    • [7. `netif` 为什么是 lwIP 与平台驱动的关键边界](#7. netif 为什么是 lwIP 与平台驱动的关键边界)
    • [8. MAC Filter 与 `ethernet_input()` 是两个不同的分发边界](#8. MAC Filter 与 ethernet_input() 是两个不同的分发边界)
    • [9. Link Up、Interface Up、IP Ready 与 Ping Success 不是同一个状态](#9. Link Up、Interface Up、IP Ready 与 Ping Success 不是同一个状态)
    • [10. Linux TAP 能学习什么,不能证明什么](#10. Linux TAP 能学习什么,不能证明什么)
    • [11. 从这一张总图进入后续系列](#11. 从这一张总图进入后续系列)
    • 资料来源
      • [S1 Microchip AN1120 --- Ethernet Theory of Operation](#[S1] Microchip AN1120 — Ethernet Theory of Operation)
      • [S2 IEEE 802.3-2022 --- IEEE Standard for Ethernet](#[S2] IEEE 802.3-2022 — IEEE Standard for Ethernet)
      • [S3 lwIP upstream `master`:`netif` 与 Ethernet Core](#[S3] lwIP upstream master:netif 与 Ethernet Core)
      • [S4 lwIP Unix TAP Port](#[S4] lwIP Unix TAP Port)
      • [S5 STMicroelectronics --- Ethernet overview](#[S5] STMicroelectronics — Ethernet overview)
      • [S6 Texas Instruments --- DP83867 Gigabit Ethernet PHY](#[S6] Texas Instruments — DP83867 Gigabit Ethernet PHY)
      • [S7 STMicroelectronics STM32H7 Reference Manual --- Ethernet MAC/DMA](#[S7] STMicroelectronics STM32H7 Reference Manual — Ethernet MAC/DMA)
      • [S8 Microchip --- Ethernet MAC Receive Block](#[S8] Microchip — Ethernet MAC Receive Block)
      • [S9 Linux Kernel --- Universal TUN/TAP device driver](#[S9] Linux Kernel — Universal TUN/TAP device driver)
      • [S10 RFC 894 --- A Standard for the Transmission of IP Datagrams over Ethernet Networks](#[S10] RFC 894 — A Standard for the Transmission of IP Datagrams over Ethernet Networks)
      • [S11 RFC 826 --- An Ethernet Address Resolution Protocol](#[S11] RFC 826 — An Ethernet Address Resolution Protocol)

Ethernet(以太网)是局域网里最常见的链路技术之一。Ethernet Frame(以太网帧)是 MAC 在链路上传输和接收的基本二层数据单元。对 MCU 网络开发而言,真正需要同时看懂的是两条边界:一条是 网线上的信号怎样经过 PHY、MAC 和 DMA 变成内存里的 Ethernet Frame ,另一条是 这些 Frame 怎样通过 Driver、pbuf 和 netif 进入 lwIP 。

本文第一次使用几个后面会反复出现的对象:**PHY(Physical Layer transceiver,物理层收发器)**负责把网线侧的模拟/符号信号与 MAC 侧的数字接口互相转换;**MAC(Media Access Control,介质访问控制器)**负责 Ethernet Frame 的发送、接收、过滤和 FCS(Frame Check Sequence,帧校验序列)等链路层工作;**DMA(Direct Memory Access,直接内存访问)**负责在 MAC 与内存 buffer 之间搬运 Frame;Driver 管理具体 MAC/DMA/PHY;lwIP 的 **pbuf(packet buffer)承载协议栈看到的报文字节, netif(network interface)**则抽象"一个可供协议栈收发 packet 的网络接口"。S2S3

这篇文章的目标不是背完 IEEE 802.3,而是建立一个足以支撑后续源码、抓包和 MCU 驱动调试的系统模型。即使不打开任何外部链接,正文仍会把后续需要的 Ethernet 基础讲完整;外部资料只用于确认规范事实和继续深入。

1. 建议提前阅读:三份资料分别解决什么问题

下面的资料值得在学习过程中反复对照,但不是继续阅读本文的强制前置。

  1. Microchip AN1120 --- Ethernet Theory of Operation:适合第一次建立 Ethernet 协议栈位置、封装、Frame、MAC/PHY 和 RX/TX 数据流心智模型。S1 如果只读一份补充资料,优先看它的 Internet Protocol Stack、Data Encapsulation、Ethernet Frame Format 与 RX/TX stream 章节。
  2. IEEE 802.3-2022 --- IEEE Standard for Ethernet:正式规范来源,用于确认 MAC、PHY、介质接口与 Ethernet 行为边界。S2 第一次学习时不需要逐页阅读。
  3. Linux Kernel --- Universal TUN/TAP device driver:后续 Linux Host Lab 使用 TAP 模拟二层网卡,这份文档用于理解"为什么 userspace 可以直接读写 Ethernet Frame"。S9

如果后续进入真实 MCU PHY bring-up,再按芯片选择对应 Reference Manual、PHY Datasheet 和板级原理图;本文使用 STM32H7、DP83867 等资料只是说明工程边界,不把某一颗芯片的实现写成 Ethernet 通用规则。S6S7

2. 先把 Ethernet 放进完整网络路径

应用发送的数据不会直接变成网线上的电信号。这里的 IPv4(Internet Protocol version 4,互联网协议第 4 版)负责网络层寻址;IPv6(Internet Protocol version 6)是同一网络层职责的下一代协议。ARP(Address Resolution Protocol,地址解析协议)在 IPv4 Ethernet 局域网中把目标 IPv4 地址解析成下一跳 MAC 地址。Ping 常用 ICMP(Internet Control Message Protocol,互联网控制消息协议)的 Echo Request / Echo Reply 检查网络层可达性;UDP(User Datagram Protocol)和 TCP(Transmission Control Protocol)则是后续常见的传输层协议。以一个 IPv4 Ping 为例,发送方向可以先理解成:
#mermaid-svg-F2PFTr5Cl3Xx6iwf{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-F2PFTr5Cl3Xx6iwf .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .error-icon{fill:#552222;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .marker{fill:#333333;stroke:#333333;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .marker.cross{stroke:#333333;}#mermaid-svg-F2PFTr5Cl3Xx6iwf svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-F2PFTr5Cl3Xx6iwf p{margin:0;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .cluster-label text{fill:#333;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .cluster-label span{color:#333;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .cluster-label span p{background-color:transparent;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .label text,#mermaid-svg-F2PFTr5Cl3Xx6iwf span{fill:#333;color:#333;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .node rect,#mermaid-svg-F2PFTr5Cl3Xx6iwf .node circle,#mermaid-svg-F2PFTr5Cl3Xx6iwf .node ellipse,#mermaid-svg-F2PFTr5Cl3Xx6iwf .node polygon,#mermaid-svg-F2PFTr5Cl3Xx6iwf .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .rough-node .label text,#mermaid-svg-F2PFTr5Cl3Xx6iwf .node .label text,#mermaid-svg-F2PFTr5Cl3Xx6iwf .image-shape .label,#mermaid-svg-F2PFTr5Cl3Xx6iwf .icon-shape .label{text-anchor:middle;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .rough-node .label,#mermaid-svg-F2PFTr5Cl3Xx6iwf .node .label,#mermaid-svg-F2PFTr5Cl3Xx6iwf .image-shape .label,#mermaid-svg-F2PFTr5Cl3Xx6iwf .icon-shape .label{text-align:center;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .node.clickable{cursor:pointer;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .arrowheadPath{fill:#333333;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-F2PFTr5Cl3Xx6iwf .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-F2PFTr5Cl3Xx6iwf .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-F2PFTr5Cl3Xx6iwf .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .cluster text{fill:#333;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .cluster span{color:#333;}#mermaid-svg-F2PFTr5Cl3Xx6iwf div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-F2PFTr5Cl3Xx6iwf rect.text{fill:none;stroke-width:0;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .icon-shape,#mermaid-svg-F2PFTr5Cl3Xx6iwf .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .icon-shape p,#mermaid-svg-F2PFTr5Cl3Xx6iwf .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .icon-shape .label rect,#mermaid-svg-F2PFTr5Cl3Xx6iwf .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-F2PFTr5Cl3Xx6iwf .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-F2PFTr5Cl3Xx6iwf .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-F2PFTr5Cl3Xx6iwf :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} ICMP Echo Request
IPv4 Packet
Ethernet Frame
MAC TX
PHY
双绞线 / 物理介质

接收方向则反过来:
#mermaid-svg-UmsheRAPx0D1nsAA{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-UmsheRAPx0D1nsAA .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-UmsheRAPx0D1nsAA .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-UmsheRAPx0D1nsAA .error-icon{fill:#552222;}#mermaid-svg-UmsheRAPx0D1nsAA .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-UmsheRAPx0D1nsAA .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-UmsheRAPx0D1nsAA .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-UmsheRAPx0D1nsAA .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-UmsheRAPx0D1nsAA .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-UmsheRAPx0D1nsAA .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-UmsheRAPx0D1nsAA .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-UmsheRAPx0D1nsAA .marker{fill:#333333;stroke:#333333;}#mermaid-svg-UmsheRAPx0D1nsAA .marker.cross{stroke:#333333;}#mermaid-svg-UmsheRAPx0D1nsAA svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-UmsheRAPx0D1nsAA p{margin:0;}#mermaid-svg-UmsheRAPx0D1nsAA .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-UmsheRAPx0D1nsAA .cluster-label text{fill:#333;}#mermaid-svg-UmsheRAPx0D1nsAA .cluster-label span{color:#333;}#mermaid-svg-UmsheRAPx0D1nsAA .cluster-label span p{background-color:transparent;}#mermaid-svg-UmsheRAPx0D1nsAA .label text,#mermaid-svg-UmsheRAPx0D1nsAA span{fill:#333;color:#333;}#mermaid-svg-UmsheRAPx0D1nsAA .node rect,#mermaid-svg-UmsheRAPx0D1nsAA .node circle,#mermaid-svg-UmsheRAPx0D1nsAA .node ellipse,#mermaid-svg-UmsheRAPx0D1nsAA .node polygon,#mermaid-svg-UmsheRAPx0D1nsAA .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-UmsheRAPx0D1nsAA .rough-node .label text,#mermaid-svg-UmsheRAPx0D1nsAA .node .label text,#mermaid-svg-UmsheRAPx0D1nsAA .image-shape .label,#mermaid-svg-UmsheRAPx0D1nsAA .icon-shape .label{text-anchor:middle;}#mermaid-svg-UmsheRAPx0D1nsAA .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-UmsheRAPx0D1nsAA .rough-node .label,#mermaid-svg-UmsheRAPx0D1nsAA .node .label,#mermaid-svg-UmsheRAPx0D1nsAA .image-shape .label,#mermaid-svg-UmsheRAPx0D1nsAA .icon-shape .label{text-align:center;}#mermaid-svg-UmsheRAPx0D1nsAA .node.clickable{cursor:pointer;}#mermaid-svg-UmsheRAPx0D1nsAA .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-UmsheRAPx0D1nsAA .arrowheadPath{fill:#333333;}#mermaid-svg-UmsheRAPx0D1nsAA .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-UmsheRAPx0D1nsAA .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-UmsheRAPx0D1nsAA .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-UmsheRAPx0D1nsAA .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-UmsheRAPx0D1nsAA .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-UmsheRAPx0D1nsAA .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-UmsheRAPx0D1nsAA .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-UmsheRAPx0D1nsAA .cluster text{fill:#333;}#mermaid-svg-UmsheRAPx0D1nsAA .cluster span{color:#333;}#mermaid-svg-UmsheRAPx0D1nsAA div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-UmsheRAPx0D1nsAA .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-UmsheRAPx0D1nsAA rect.text{fill:none;stroke-width:0;}#mermaid-svg-UmsheRAPx0D1nsAA .icon-shape,#mermaid-svg-UmsheRAPx0D1nsAA .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-UmsheRAPx0D1nsAA .icon-shape p,#mermaid-svg-UmsheRAPx0D1nsAA .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-UmsheRAPx0D1nsAA .icon-shape .label rect,#mermaid-svg-UmsheRAPx0D1nsAA .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-UmsheRAPx0D1nsAA .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-UmsheRAPx0D1nsAA .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-UmsheRAPx0D1nsAA :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 双绞线 / 物理介质
PHY
MAC RX
DMA / Driver
lwIP pbuf
Ethernet / ARP(地址解析) / IPv4 / IPv6
ICMP / UDP / TCP 上层处理

这里第一次需要区分几个容易混淆的数据单位:

名称 所在层次 当前文章中的含义
Ethernet Frame(帧) Link Layer MAC 在链路上发送/接收的二层数据单元
IPv4 Packet / Datagram(包/数据报) Network Layer Ethernet payload 中承载的网络层数据
TCP Segment(段) Transport Layer IPv4/IPv6 payload 中承载的 TCP 数据单元
pbuf lwIP 内部对象 保存当前协议层可见字节及长度、链、引用关系的软件 buffer

Frame、IP Packet 与 pbuf 不是三个不同网络副本的固定关系。pbuf->payload 是一个会随协议层处理而移动的数据视图:刚进入 Ethernet 层时通常指向 Ethernet Header,进入 IPv4 层后 Ethernet Header 已经被消费,后续再继续推进到 transport header。S3

3. 一个 Ethernet Frame 至少要先看懂什么

后续源码和 Wireshark 中最常遇到的 Ethernet II Frame 可以先抽象成:

text 复制代码
+--------------------+
| Destination MAC    |  目标链路地址
+--------------------+
| Source MAC         |  源链路地址
+--------------------+
| EtherType          |  payload 属于哪种上层协议
+--------------------+
| Payload            |  ARP / IPv4 / IPv6 ...
+--------------------+
| FCS                |  链路层错误检测,通常由 MAC 硬件处理
+--------------------+

**MAC Address(MAC 地址)**是 Ethernet 链路层使用的地址,不等于 IPv4/IPv6 地址。Destination MAC 决定这一帧在当前二层网络中交给哪个接口;EtherType 则告诉接收端 payload 应该按哪一种上层协议解释,例如 ARP、IPv4 或 IPv6。S1S3

目标 lwIP 版本中的基础 Ethernet Header 对应:S3

c 复制代码
struct eth_hdr {
  struct eth_addr dest;
  struct eth_addr src;
  u16_t type;
};

这段结构体没有 Preamble、SFD 或 FCS,不代表这些内容在线路上不存在,而是说明 lwIP 与 MAC 硬件的观察边界并不等于完整线侧 Frame 。Preamble/SFD 通常由 MAC 发送/识别,FCS 通常由 MAC 生成和校验;Driver 交给 lwIP 的 buffer 一般从 Destination MAC 开始,也通常不再包含 FCS。S1S4

IPv4 在 Ethernet 中如何封装由 RFC 894 定义;ARP 如何把协议地址解析为 hardware address 可继续参考 RFC 826。S10S11 Stage 02/04 会用真实 Ping 抓包再把这两个协议映射回源码。

4. PHY 与 MAC:一个负责物理信号,一个负责 Frame

PHY 面向物理介质,MAC 面向 Ethernet Frame。它们通常不是通过"网线协议"直接对话,而是通过 MII(Media Independent Interface)、RMII(Reduced MII)、GMII(Gigabit MII)、RGMII(Reduced Gigabit MII)等标准化数字接口传输 data/control/clock。S2S5

除了数据接口,PHY 还常提供 MDC(Management Data Clock)和 MDIO(Management Data Input/Output)组成的管理接口,供 CPU/Driver 读写 PHY 寄存器;它承载的是管理控制,不承载正常 Ethernet Frame payload。S5S6
#mermaid-svg-q5IfR4XYMKJ7AbPB{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-q5IfR4XYMKJ7AbPB .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-q5IfR4XYMKJ7AbPB .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-q5IfR4XYMKJ7AbPB .error-icon{fill:#552222;}#mermaid-svg-q5IfR4XYMKJ7AbPB .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-q5IfR4XYMKJ7AbPB .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-q5IfR4XYMKJ7AbPB .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-q5IfR4XYMKJ7AbPB .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-q5IfR4XYMKJ7AbPB .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-q5IfR4XYMKJ7AbPB .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-q5IfR4XYMKJ7AbPB .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-q5IfR4XYMKJ7AbPB .marker{fill:#333333;stroke:#333333;}#mermaid-svg-q5IfR4XYMKJ7AbPB .marker.cross{stroke:#333333;}#mermaid-svg-q5IfR4XYMKJ7AbPB svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-q5IfR4XYMKJ7AbPB p{margin:0;}#mermaid-svg-q5IfR4XYMKJ7AbPB .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-q5IfR4XYMKJ7AbPB .cluster-label text{fill:#333;}#mermaid-svg-q5IfR4XYMKJ7AbPB .cluster-label span{color:#333;}#mermaid-svg-q5IfR4XYMKJ7AbPB .cluster-label span p{background-color:transparent;}#mermaid-svg-q5IfR4XYMKJ7AbPB .label text,#mermaid-svg-q5IfR4XYMKJ7AbPB span{fill:#333;color:#333;}#mermaid-svg-q5IfR4XYMKJ7AbPB .node rect,#mermaid-svg-q5IfR4XYMKJ7AbPB .node circle,#mermaid-svg-q5IfR4XYMKJ7AbPB .node ellipse,#mermaid-svg-q5IfR4XYMKJ7AbPB .node polygon,#mermaid-svg-q5IfR4XYMKJ7AbPB .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-q5IfR4XYMKJ7AbPB .rough-node .label text,#mermaid-svg-q5IfR4XYMKJ7AbPB .node .label text,#mermaid-svg-q5IfR4XYMKJ7AbPB .image-shape .label,#mermaid-svg-q5IfR4XYMKJ7AbPB .icon-shape .label{text-anchor:middle;}#mermaid-svg-q5IfR4XYMKJ7AbPB .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-q5IfR4XYMKJ7AbPB .rough-node .label,#mermaid-svg-q5IfR4XYMKJ7AbPB .node .label,#mermaid-svg-q5IfR4XYMKJ7AbPB .image-shape .label,#mermaid-svg-q5IfR4XYMKJ7AbPB .icon-shape .label{text-align:center;}#mermaid-svg-q5IfR4XYMKJ7AbPB .node.clickable{cursor:pointer;}#mermaid-svg-q5IfR4XYMKJ7AbPB .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-q5IfR4XYMKJ7AbPB .arrowheadPath{fill:#333333;}#mermaid-svg-q5IfR4XYMKJ7AbPB .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-q5IfR4XYMKJ7AbPB .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-q5IfR4XYMKJ7AbPB .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-q5IfR4XYMKJ7AbPB .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-q5IfR4XYMKJ7AbPB .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-q5IfR4XYMKJ7AbPB .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-q5IfR4XYMKJ7AbPB .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-q5IfR4XYMKJ7AbPB .cluster text{fill:#333;}#mermaid-svg-q5IfR4XYMKJ7AbPB .cluster span{color:#333;}#mermaid-svg-q5IfR4XYMKJ7AbPB div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-q5IfR4XYMKJ7AbPB .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-q5IfR4XYMKJ7AbPB rect.text{fill:none;stroke-width:0;}#mermaid-svg-q5IfR4XYMKJ7AbPB .icon-shape,#mermaid-svg-q5IfR4XYMKJ7AbPB .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-q5IfR4XYMKJ7AbPB .icon-shape p,#mermaid-svg-q5IfR4XYMKJ7AbPB .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-q5IfR4XYMKJ7AbPB .icon-shape .label rect,#mermaid-svg-q5IfR4XYMKJ7AbPB .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-q5IfR4XYMKJ7AbPB .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-q5IfR4XYMKJ7AbPB .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-q5IfR4XYMKJ7AbPB :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} RMII / RGMII 等数据接口
MDC / MDIO 管理接口
RJ45 / Magnetics
PHY
MAC
CPU / Driver

这里还要区分两类接口:

  • RMII/RGMII 等数据接口:真正承载 MAC 与 PHY 之间的帧数据和时序;
  • MDC/MDIO 管理接口 :只承载 PHY 管理寄存器访问,CPU/Driver 可通过它读取 PHY ID、Link、Auto-Negotiation、speed/duplex 等状态。S5S6

**Auto-Negotiation(自动协商)**是链路伙伴之间协商可用速率、双工等能力的 PHY/Ethernet 机制;speed/duplex 分别表示链路速率和半双工/全双工工作方式。它们由 PHY/MAC/Driver 处理,不由 lwIP Core 实现。后续 Stage 22 与 Stage 44 会专门处理 link lifecycle 与具体 STM32 PHY 恢复流程。

因此:

text 复制代码
MDIO 能读 PHY ID
    != Link Up
Link Up
    != RMII/RGMII 数据时序正确
数字接口正确
    != DMA descriptor 正常推进
DMA 正常
    != lwIP 收包路径正确

这组"不等价关系"是 Ethernet 调试最重要的第一层边界。

5. MAC 收到 Frame 后,为什么还需要 DMA 和 Descriptor

真实 MCU 中,MAC 通常不会逐字节调用 C 函数把 Frame 填进 pbuf。MAC 与内存之间一般由 DMA 搬运,而 DMA 依靠 **Descriptor(描述符)**知道 buffer 在哪里、多长、当前由 CPU 还是 DMA 使用以及传输结果是什么。S7

可以把 RX 数据流先理解为:
#mermaid-svg-KKyWFoGP7Xn9C9Bf{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-KKyWFoGP7Xn9C9Bf .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .error-icon{fill:#552222;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .marker{fill:#333333;stroke:#333333;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .marker.cross{stroke:#333333;}#mermaid-svg-KKyWFoGP7Xn9C9Bf svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-KKyWFoGP7Xn9C9Bf p{margin:0;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .cluster-label text{fill:#333;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .cluster-label span{color:#333;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .cluster-label span p{background-color:transparent;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .label text,#mermaid-svg-KKyWFoGP7Xn9C9Bf span{fill:#333;color:#333;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .node rect,#mermaid-svg-KKyWFoGP7Xn9C9Bf .node circle,#mermaid-svg-KKyWFoGP7Xn9C9Bf .node ellipse,#mermaid-svg-KKyWFoGP7Xn9C9Bf .node polygon,#mermaid-svg-KKyWFoGP7Xn9C9Bf .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .rough-node .label text,#mermaid-svg-KKyWFoGP7Xn9C9Bf .node .label text,#mermaid-svg-KKyWFoGP7Xn9C9Bf .image-shape .label,#mermaid-svg-KKyWFoGP7Xn9C9Bf .icon-shape .label{text-anchor:middle;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .rough-node .label,#mermaid-svg-KKyWFoGP7Xn9C9Bf .node .label,#mermaid-svg-KKyWFoGP7Xn9C9Bf .image-shape .label,#mermaid-svg-KKyWFoGP7Xn9C9Bf .icon-shape .label{text-align:center;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .node.clickable{cursor:pointer;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .arrowheadPath{fill:#333333;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-KKyWFoGP7Xn9C9Bf .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-KKyWFoGP7Xn9C9Bf .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-KKyWFoGP7Xn9C9Bf .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .cluster text{fill:#333;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .cluster span{color:#333;}#mermaid-svg-KKyWFoGP7Xn9C9Bf div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-KKyWFoGP7Xn9C9Bf rect.text{fill:none;stroke-width:0;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .icon-shape,#mermaid-svg-KKyWFoGP7Xn9C9Bf .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .icon-shape p,#mermaid-svg-KKyWFoGP7Xn9C9Bf .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .icon-shape .label rect,#mermaid-svg-KKyWFoGP7Xn9C9Bf .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-KKyWFoGP7Xn9C9Bf .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-KKyWFoGP7Xn9C9Bf .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-KKyWFoGP7Xn9C9Bf :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} MAC RX
RX Descriptor
RX Buffer
Driver
pbuf
netif->input()

常见 Descriptor 需要表达的概念包括:

text 复制代码
buffer address
length
ownership
first/last segment
status/error

其中 **ownership(所有权)**回答"当前谁有权读写或回收这个 buffer"。例如 RX descriptor 在 DMA 持有时,CPU 不能把它当成已经完成的 packet 使用;DMA 收到完整 Frame 并交还后,Driver 才能读取长度/status、构造 pbuf,最后在资源不再被 lwIP 使用时把 buffer 重新交给 DMA。

典型 RX 生命周期:
#mermaid-svg-6GPbsJiTBCyFunyG{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-6GPbsJiTBCyFunyG .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-6GPbsJiTBCyFunyG .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-6GPbsJiTBCyFunyG .error-icon{fill:#552222;}#mermaid-svg-6GPbsJiTBCyFunyG .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-6GPbsJiTBCyFunyG .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-6GPbsJiTBCyFunyG .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-6GPbsJiTBCyFunyG .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-6GPbsJiTBCyFunyG .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-6GPbsJiTBCyFunyG .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-6GPbsJiTBCyFunyG .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-6GPbsJiTBCyFunyG .marker{fill:#333333;stroke:#333333;}#mermaid-svg-6GPbsJiTBCyFunyG .marker.cross{stroke:#333333;}#mermaid-svg-6GPbsJiTBCyFunyG svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-6GPbsJiTBCyFunyG p{margin:0;}#mermaid-svg-6GPbsJiTBCyFunyG .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-6GPbsJiTBCyFunyG .cluster-label text{fill:#333;}#mermaid-svg-6GPbsJiTBCyFunyG .cluster-label span{color:#333;}#mermaid-svg-6GPbsJiTBCyFunyG .cluster-label span p{background-color:transparent;}#mermaid-svg-6GPbsJiTBCyFunyG .label text,#mermaid-svg-6GPbsJiTBCyFunyG span{fill:#333;color:#333;}#mermaid-svg-6GPbsJiTBCyFunyG .node rect,#mermaid-svg-6GPbsJiTBCyFunyG .node circle,#mermaid-svg-6GPbsJiTBCyFunyG .node ellipse,#mermaid-svg-6GPbsJiTBCyFunyG .node polygon,#mermaid-svg-6GPbsJiTBCyFunyG .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-6GPbsJiTBCyFunyG .rough-node .label text,#mermaid-svg-6GPbsJiTBCyFunyG .node .label text,#mermaid-svg-6GPbsJiTBCyFunyG .image-shape .label,#mermaid-svg-6GPbsJiTBCyFunyG .icon-shape .label{text-anchor:middle;}#mermaid-svg-6GPbsJiTBCyFunyG .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-6GPbsJiTBCyFunyG .rough-node .label,#mermaid-svg-6GPbsJiTBCyFunyG .node .label,#mermaid-svg-6GPbsJiTBCyFunyG .image-shape .label,#mermaid-svg-6GPbsJiTBCyFunyG .icon-shape .label{text-align:center;}#mermaid-svg-6GPbsJiTBCyFunyG .node.clickable{cursor:pointer;}#mermaid-svg-6GPbsJiTBCyFunyG .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-6GPbsJiTBCyFunyG .arrowheadPath{fill:#333333;}#mermaid-svg-6GPbsJiTBCyFunyG .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-6GPbsJiTBCyFunyG .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-6GPbsJiTBCyFunyG .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-6GPbsJiTBCyFunyG .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-6GPbsJiTBCyFunyG .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-6GPbsJiTBCyFunyG .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-6GPbsJiTBCyFunyG .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-6GPbsJiTBCyFunyG .cluster text{fill:#333;}#mermaid-svg-6GPbsJiTBCyFunyG .cluster span{color:#333;}#mermaid-svg-6GPbsJiTBCyFunyG div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-6GPbsJiTBCyFunyG .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-6GPbsJiTBCyFunyG rect.text{fill:none;stroke-width:0;}#mermaid-svg-6GPbsJiTBCyFunyG .icon-shape,#mermaid-svg-6GPbsJiTBCyFunyG .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-6GPbsJiTBCyFunyG .icon-shape p,#mermaid-svg-6GPbsJiTBCyFunyG .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-6GPbsJiTBCyFunyG .icon-shape .label rect,#mermaid-svg-6GPbsJiTBCyFunyG .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-6GPbsJiTBCyFunyG .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-6GPbsJiTBCyFunyG .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-6GPbsJiTBCyFunyG :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} DMA owns RX descriptor
MAC 收到 Frame
DMA 写 buffer / status
CPU / Driver 取得 completed descriptor
构造或挂接 pbuf
netif->input(p, netif)
lwIP 消费并最终释放
Driver 回收 buffer / descriptor

TX 则方向相反:lwIP 把一个已经完成二层封装的 pbuf 交给 netif->linkoutput(),Driver 把 payload 组织给 TX descriptor,满足平台所需的 cache/memory ordering 后把 ownership 交给 DMA;发送完成后资源才可以回收。Stage 20/21 讲通用 ownership、zero-copy 与 backpressure,Stage 43 再进入 STM32H7 的具体 descriptor/cache 路径。

6. pbuf 与 DMA Buffer 不是同一个概念

这是从驱动进入 lwIP 时最容易形成错误心智模型的地方。

DMA Buffer 是 MAC/DMA 能访问的一段内存;pbuf 是 lwIP 的 packet buffer 对象,除了指向数据,还维护 len、tot_len、链和引用计数等协议栈语义。S3

二者可以有两种常见关系:

text 复制代码
Copy RX:
DMA Buffer --copy--> lwIP-owned pbuf

Zero-copy / custom RX:
DMA Buffer <---- pbuf 指向同一片数据 ---->

Copy 模式生命周期简单,但增加一次内存复制;Zero-copy 可以减少复制,却要求 Driver、DMA 与 lwIP 对"什么时候可以再次使用这片内存"有严格一致的 ownership contract。Stage 03 会专门解释 pbuf 生命周期,Stage 20/43 再把它与 DMA buffer 连接起来。

在带 D-Cache(Data Cache,数据缓存)的 MCU 上还会多一个可见性问题:CPU Cache 与 DMA 访问主存可能看到不同版本的数据。Clean 通常表示把 CPU cache 中的脏数据写回主存,Invalidate 表示丢弃 CPU cache 中旧副本,让后续读取重新从主存取得 DMA 已更新的数据。具体何时做、操作范围和对齐要求属于平台实现,不是 lwIP 协议规则。

7. netif 为什么是 lwIP 与平台驱动的关键边界

struct netif 把"协议栈如何向一个接口收发 packet"抽象成 callback。目标版本中,当前系列最重要的是:S3

callback 当前职责
netif->input Driver 把收到的 packet 交给协议栈
netif->output IPv4 输出入口,Ethernet 场景常进入 ARP/二层封装
netif->output_ip6 IPv6 输出入口
netif->linkoutput 已完成 L2 封装的数据真正交给 link driver

因此 RX 可以简化为:

text 复制代码
Driver 取得 Frame
→ 构造/挂接 pbuf
→ netif->input(p, netif)
→ tcpip_input() 或 ethernet_input()
→ ARP / IPv4 / IPv6 ...

TX 则通常是:

text 复制代码
IPv4 / IPv6 上层输出
→ 二层封装
→ netif->linkoutput()
→ Driver / DMA
→ MAC
→ PHY

netif 不等于物理网卡硬件本身;它是 lwIP 中代表网络接口的软件对象。真实 MCU 上它连接 Ethernet Driver,Linux Host Lab 中则可以连接 TAP Port。正因为这个抽象存在,同一套 lwIP Core 才能在不同硬件/Host Port 上复用。S3S4

8. MAC Filter 与 ethernet_input() 是两个不同的分发边界

当 Frame 从线进入本机时,至少会经历两种完全不同的"要不要接收/交给谁"的判断。

第一层是 MAC hardware receive filter :硬件根据 Destination MAC、broadcast(广播,面向当前二层广播域内所有节点)、multicast(组播,面向加入某个组的节点)、promiscuous(混杂模式,接收本来不属于本机的更多 Frame)等规则决定 Frame 是否进入本机 RX path。不同 MAC 的 perfect/hash/filter 细节不同,这是硬件/Driver 行为。S7S8

第二层是 lwIP 的协议分发:Frame 已经被 Driver 交给 ethernet_input() 后,lwIP 根据 EtherType 决定 payload 进入 ARP、IPv4、IPv6 等哪个上层处理器。S3
#mermaid-svg-LU8iJpfCgmUTKpPL{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-LU8iJpfCgmUTKpPL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-LU8iJpfCgmUTKpPL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-LU8iJpfCgmUTKpPL .error-icon{fill:#552222;}#mermaid-svg-LU8iJpfCgmUTKpPL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-LU8iJpfCgmUTKpPL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-LU8iJpfCgmUTKpPL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-LU8iJpfCgmUTKpPL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-LU8iJpfCgmUTKpPL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-LU8iJpfCgmUTKpPL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-LU8iJpfCgmUTKpPL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-LU8iJpfCgmUTKpPL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-LU8iJpfCgmUTKpPL .marker.cross{stroke:#333333;}#mermaid-svg-LU8iJpfCgmUTKpPL svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-LU8iJpfCgmUTKpPL p{margin:0;}#mermaid-svg-LU8iJpfCgmUTKpPL .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-LU8iJpfCgmUTKpPL .cluster-label text{fill:#333;}#mermaid-svg-LU8iJpfCgmUTKpPL .cluster-label span{color:#333;}#mermaid-svg-LU8iJpfCgmUTKpPL .cluster-label span p{background-color:transparent;}#mermaid-svg-LU8iJpfCgmUTKpPL .label text,#mermaid-svg-LU8iJpfCgmUTKpPL span{fill:#333;color:#333;}#mermaid-svg-LU8iJpfCgmUTKpPL .node rect,#mermaid-svg-LU8iJpfCgmUTKpPL .node circle,#mermaid-svg-LU8iJpfCgmUTKpPL .node ellipse,#mermaid-svg-LU8iJpfCgmUTKpPL .node polygon,#mermaid-svg-LU8iJpfCgmUTKpPL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-LU8iJpfCgmUTKpPL .rough-node .label text,#mermaid-svg-LU8iJpfCgmUTKpPL .node .label text,#mermaid-svg-LU8iJpfCgmUTKpPL .image-shape .label,#mermaid-svg-LU8iJpfCgmUTKpPL .icon-shape .label{text-anchor:middle;}#mermaid-svg-LU8iJpfCgmUTKpPL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-LU8iJpfCgmUTKpPL .rough-node .label,#mermaid-svg-LU8iJpfCgmUTKpPL .node .label,#mermaid-svg-LU8iJpfCgmUTKpPL .image-shape .label,#mermaid-svg-LU8iJpfCgmUTKpPL .icon-shape .label{text-align:center;}#mermaid-svg-LU8iJpfCgmUTKpPL .node.clickable{cursor:pointer;}#mermaid-svg-LU8iJpfCgmUTKpPL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-LU8iJpfCgmUTKpPL .arrowheadPath{fill:#333333;}#mermaid-svg-LU8iJpfCgmUTKpPL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-LU8iJpfCgmUTKpPL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-LU8iJpfCgmUTKpPL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LU8iJpfCgmUTKpPL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-LU8iJpfCgmUTKpPL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LU8iJpfCgmUTKpPL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-LU8iJpfCgmUTKpPL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-LU8iJpfCgmUTKpPL .cluster text{fill:#333;}#mermaid-svg-LU8iJpfCgmUTKpPL .cluster span{color:#333;}#mermaid-svg-LU8iJpfCgmUTKpPL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-LU8iJpfCgmUTKpPL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-LU8iJpfCgmUTKpPL rect.text{fill:none;stroke-width:0;}#mermaid-svg-LU8iJpfCgmUTKpPL .icon-shape,#mermaid-svg-LU8iJpfCgmUTKpPL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LU8iJpfCgmUTKpPL .icon-shape p,#mermaid-svg-LU8iJpfCgmUTKpPL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-LU8iJpfCgmUTKpPL .icon-shape .label rect,#mermaid-svg-LU8iJpfCgmUTKpPL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LU8iJpfCgmUTKpPL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-LU8iJpfCgmUTKpPL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-LU8iJpfCgmUTKpPL :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} accepted
线上的 Ethernet Frame
MAC hardware filter
DMA / Driver
pbuf
ethernet_input()
EtherType
ARP
IPv4
IPv6

所以"Frame 为什么没有进入 lwIP"和"Frame 进入 lwIP 后为什么没有进入 IPv4"是两个层次的问题,不能用同一个断点解释。

Ethernet 网络 bring-up 至少包含多个独立状态。lwIP 也明确把 link state 与 interface up/down 分开管理。S3

状态 表示什么 不能推出什么
PHY Link Up PHY 已建立物理链路 DMA 与 lwIP 一定正常
NETIF_FLAG_LINK_UP 软件记录 link 已可用 interface 已启用或 IP 已配置
NETIF_FLAG_UP 协议栈允许该接口工作 地址/路由一定正确
IP Ready address/netmask/route 等网络层条件满足 对端一定可达
ARP/ICMP Success L2/L3 基本收发闭环 UDP/TCP/Application 一定正确

这也是后续排障顺序应该从底向上推进的原因:

text 复制代码
PHY Link
→ MAC/RMII/RGMII
→ DMA Descriptor / Buffer
→ Driver / pbuf
→ netif input/output
→ Ethernet / ARP
→ IPv4 / IPv6
→ ICMP / UDP / TCP
→ Application

如果最后一个已经确认正确的边界是 DMA,就不应该先在 TCP callback 中寻找原因。

10. Linux TAP 能学习什么,不能证明什么

本仓库后续使用 Linux TAP 学习 lwIP。TAP 是 Linux 提供的虚拟二层网络设备:userspace 程序从 TAP fd 读取时拿到 Ethernet Frame,写回 TAP 时则把 Ethernet Frame 注入 Host 网络路径。S9

目标 Unix Port 中,TAP RX 会读取 Frame、构造 PBUF_RAW 再交给 netif->input();TX 则把 pbuf 数据写回 TAP。S4

因此 Host Lab 很适合研究:

text 复制代码
Ethernet Header
ARP / IPv4 / IPv6
ICMP / UDP / TCP
pbuf / netif
thread / mailbox

但它没有真实 MCU 的:

text 复制代码
PHY 模拟前端
实际 Auto-Negotiation 波形
RMII/RGMII 时序
MAC DMA descriptor
MCU D-Cache coherency
magnetics / ESD / PCB layout

所以 TAP 上 Ping 成功能够证明当前 Host Port 与 lwIP Core 的数据通路成立,却不能证明目标板 PHY/MAC/DMA bring-up 正确。反过来,目标板 Link Up 也不能证明 lwIP Core 路径已经工作。

11. 从这一张总图进入后续系列

到这里,后续所有文章都可以挂回同一张边界图:
#mermaid-svg-fYsXk7NRRytuNNIA{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-fYsXk7NRRytuNNIA .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-fYsXk7NRRytuNNIA .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-fYsXk7NRRytuNNIA .error-icon{fill:#552222;}#mermaid-svg-fYsXk7NRRytuNNIA .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-fYsXk7NRRytuNNIA .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-fYsXk7NRRytuNNIA .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fYsXk7NRRytuNNIA .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fYsXk7NRRytuNNIA .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-fYsXk7NRRytuNNIA .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fYsXk7NRRytuNNIA .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fYsXk7NRRytuNNIA .marker{fill:#333333;stroke:#333333;}#mermaid-svg-fYsXk7NRRytuNNIA .marker.cross{stroke:#333333;}#mermaid-svg-fYsXk7NRRytuNNIA svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-fYsXk7NRRytuNNIA p{margin:0;}#mermaid-svg-fYsXk7NRRytuNNIA .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-fYsXk7NRRytuNNIA .cluster-label text{fill:#333;}#mermaid-svg-fYsXk7NRRytuNNIA .cluster-label span{color:#333;}#mermaid-svg-fYsXk7NRRytuNNIA .cluster-label span p{background-color:transparent;}#mermaid-svg-fYsXk7NRRytuNNIA .label text,#mermaid-svg-fYsXk7NRRytuNNIA span{fill:#333;color:#333;}#mermaid-svg-fYsXk7NRRytuNNIA .node rect,#mermaid-svg-fYsXk7NRRytuNNIA .node circle,#mermaid-svg-fYsXk7NRRytuNNIA .node ellipse,#mermaid-svg-fYsXk7NRRytuNNIA .node polygon,#mermaid-svg-fYsXk7NRRytuNNIA .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-fYsXk7NRRytuNNIA .rough-node .label text,#mermaid-svg-fYsXk7NRRytuNNIA .node .label text,#mermaid-svg-fYsXk7NRRytuNNIA .image-shape .label,#mermaid-svg-fYsXk7NRRytuNNIA .icon-shape .label{text-anchor:middle;}#mermaid-svg-fYsXk7NRRytuNNIA .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-fYsXk7NRRytuNNIA .rough-node .label,#mermaid-svg-fYsXk7NRRytuNNIA .node .label,#mermaid-svg-fYsXk7NRRytuNNIA .image-shape .label,#mermaid-svg-fYsXk7NRRytuNNIA .icon-shape .label{text-align:center;}#mermaid-svg-fYsXk7NRRytuNNIA .node.clickable{cursor:pointer;}#mermaid-svg-fYsXk7NRRytuNNIA .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-fYsXk7NRRytuNNIA .arrowheadPath{fill:#333333;}#mermaid-svg-fYsXk7NRRytuNNIA .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-fYsXk7NRRytuNNIA .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-fYsXk7NRRytuNNIA .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fYsXk7NRRytuNNIA .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-fYsXk7NRRytuNNIA .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fYsXk7NRRytuNNIA .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-fYsXk7NRRytuNNIA .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-fYsXk7NRRytuNNIA .cluster text{fill:#333;}#mermaid-svg-fYsXk7NRRytuNNIA .cluster span{color:#333;}#mermaid-svg-fYsXk7NRRytuNNIA div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-fYsXk7NRRytuNNIA .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-fYsXk7NRRytuNNIA rect.text{fill:none;stroke-width:0;}#mermaid-svg-fYsXk7NRRytuNNIA .icon-shape,#mermaid-svg-fYsXk7NRRytuNNIA .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fYsXk7NRRytuNNIA .icon-shape p,#mermaid-svg-fYsXk7NRRytuNNIA .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-fYsXk7NRRytuNNIA .icon-shape .label rect,#mermaid-svg-fYsXk7NRRytuNNIA .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fYsXk7NRRytuNNIA .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-fYsXk7NRRytuNNIA .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-fYsXk7NRRytuNNIA :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 物理介质
PHY
MAC
DMA / Driver
pbuf
netif
Ethernet / ARP / IP
ICMP / UDP / TCP
Application

接下来的学习顺序也由这张图自然展开:

  • Stage 01 先把 upstream 源码、Linux Host、Debug build tree 与 compile database 准备好;
  • Stage 02 从真实 main() 走到第一次 Ping,把 TAP Frame 映射到 lwIP 调用链;
  • Stage 03/04 再分别深化 pbuf 生命周期与 Ethernet/ARP/IPv4/ICMP 分发;
  • Stage 20~22 抽象 DMA ownership、descriptor ring/backpressure 与 PHY link lifecycle;
  • Stage 42~44 最终回到 STM32H750 + RT-Thread 的具体实现。

Stage 00 最需要带走的不是某个寄存器,而是三个边界:PHY/MAC 负责物理链路与 Ethernet Frame,DMA/Driver 负责硬件 buffer 与软件 packet 的交接,lwIP 从 pbuf/netif 这一侧继续实现网络协议。

资料来源

S1 Microchip AN1120 --- Ethernet Theory of Operation

  • 类型:厂商 Application Note / Ethernet 入门资料
  • 版本:AN1120 / DS01120A
  • URL/文档:AN1120 官方页面、Ethernet Theory of Operation PDF
  • 使用位置:Ethernet 系统位置、封装、Frame、MAC/PHY、RX/TX 数据流
  • 支撑内容:用于建立 Ethernet 协议栈与 Frame 的规范化心智模型,并作为后续深入阅读入口

S2 IEEE 802.3-2022 --- IEEE Standard for Ethernet

  • 类型:标准规范
  • 版本:IEEE 802.3-2022
  • URL/文档:IEEE 802.3-2022
  • 使用位置:PHY/MAC、Ethernet 标准边界、链路层术语
  • 支撑内容:Ethernet MAC、Physical Layer、介质接口与标准职责边界

S3 lwIP upstream master:netif 与 Ethernet Core

  • 类型:目标版本上游源码
  • 版本:d08f4773edd0182b7910fc8f046eed82ffcd67c9
  • URL/文档:src/include/lwip/netif.h、src/include/lwip/prot/ethernet.h、src/netif/ethernet.c
  • 使用位置:struct eth_hdr、netif callback、EtherType 分发、link/interface 状态
  • 支撑内容:确认 lwIP 看到的 Ethernet Header、netif->input/output/linkoutput 与 Ethernet Core 边界

S4 lwIP Unix TAP Port

  • 类型:目标版本上游 Port 源码
  • 版本:d08f4773edd0182b7910fc8f046eed82ffcd67c9
  • URL/文档:contrib/ports/unix/port/netif/tapif.c
  • 使用位置:TAP 与真实 MAC/DMA 的能力边界、PBUF_RAW RX/TX
  • 支撑内容:Host Port 从 TAP fd 读取/写入 Ethernet Frame 并连接 pbuf/netif

S5 STMicroelectronics --- Ethernet overview

  • 类型:厂商平台资料
  • URL/文档:STM32MPU Ethernet overview
  • 使用位置:PHY/MAC 数据接口与 MDC/MDIO 管理接口
  • 支撑内容:MII/RMII/GMII/RGMII 与 MDC/MDIO 的平台实现示例

S6 Texas Instruments --- DP83867 Gigabit Ethernet PHY

  • 类型:PHY 数据手册
  • 版本:DP83867E/IS/CS
  • URL/文档:DP83867E/IS/CS Data Sheet
  • 使用位置:RGMII timing/delay、PHY 管理状态与 speed/duplex 示例
  • 支撑内容:说明真实 PHY 上时序、内部 delay、管理状态属于平台/器件实现

S7 STMicroelectronics STM32H7 Reference Manual --- Ethernet MAC/DMA

  • 类型:MCU Reference Manual
  • 版本:RM0433 Rev.5
  • URL/文档:STM32H7 Reference Manual
  • 使用位置:MAC filtering、DMA descriptor、硬件/Driver 边界
  • 支撑内容:提供具体 MCU 的 MAC/DMA/过滤实现实例;不作为 Ethernet 通用格式来源

S8 Microchip --- Ethernet MAC Receive Block

  • 类型:MAC 官方文档
  • URL/文档:MAC Receive Block
  • 使用位置:MAC receive filter/error 与 RX delivery 边界
  • 支撑内容:说明 FCS/length/symbol error 与硬件接收资源、过滤和丢弃之间的控制器实现边界

S9 Linux Kernel --- Universal TUN/TAP device driver

  • 类型:Linux Kernel 官方文档
  • URL/文档:Universal TUN/TAP device driver
  • 使用位置:Linux Host Lab 中 TAP 的定位
  • 支撑内容:TAP 的 userspace 虚拟 Ethernet device 模型及读写边界

S10 RFC 894 --- A Standard for the Transmission of IP Datagrams over Ethernet Networks

  • 类型:Internet Standard
  • URL/文档:RFC 894
  • 使用位置:IPv4 datagram 与 Ethernet Frame 的封装关系
  • 支撑内容:确认 IPv4 over Ethernet 的标准封装

S11 RFC 826 --- An Ethernet Address Resolution Protocol

  • 类型:Internet Standard
  • URL/文档:RFC 826
  • 使用位置:与 Stage 02/04 Ping/ARP 源码教程的衔接
  • 支撑内容:ARP Request/Reply 与 protocol address 到 hardware address 的解析语义
相关推荐
小黄蚁1 小时前
无人驾驶入门笔记(一)
笔记·自动驾驶·信息与通信
cehuishi95271 小时前
测绘外业调查如何正确的开展
运维·服务器·网络
zmsup1 小时前
从运维需求到产品能力:OpsArk Agent 的运维智能平台架构设计思路
运维·系统架构·agent·智能体·运维智能平台
m0_734172422 小时前
Python用zip配对前先检查长度
python·学习
乌暮2 小时前
拆解网页的底层逻辑:用费曼学习法讲透 HTML 与 CSS
前端·css·学习·html
江屿风2 小时前
【Linux系统】【从菜鸟驿站到操作系统:一节课打通Linux重定向与缓冲区真相】流食般投喂
linux·运维·服务器·开发语言·笔记
今天要早睡_2 小时前
Linux 基础指令速查:从 ls 到 tar 的常用命令全解析
linux·运维·chrome
辣知2 小时前
辣知·化智73 左丘明留下的那面镜子
学习
吴声子夜歌2 小时前
Docker入门与实战——核心概念与安装配置
运维·docker·容器