title: 31-slip-vs-pppos
categories:
- LWIP
tags: - LWIP
abbrlink: 5e598a48
date: 2026-10-03 16:27:36
教程 31:SLIP vs PPPoS------串口 IP Framing、错误检测、协商与工程边界
摘要:用统一的数据流、控制面与实现边界比较 lwIP SLIP 和 PPPoS,解释 framing、错误检测、协议分发、地址配置、执行上下文与生命周期差异。

文章目录
- [教程 31:SLIP vs PPPoS------串口 IP Framing、错误检测、协商与工程边界](#教程 31:SLIP vs PPPoS——串口 IP Framing、错误检测、协商与工程边界)
-
- 阅读前建议:先看协议原文,再用本文建立工程映射
- [1. 先看系统位置:两者共享 serial transport,但不是同一层次的"串口协议"](#1. 先看系统位置:两者共享 serial transport,但不是同一层次的“串口协议”)
- [2. 同一个 IPv4 datagram,在两条路径上发生了什么](#2. 同一个 IPv4 datagram,在两条路径上发生了什么)
- [3. Framing:SLIP 只解决边界与转义,PPPoS 还承担 PPP 链路格式](#3. Framing:SLIP 只解决边界与转义,PPPoS 还承担 PPP 链路格式)
- [4. 错误检测差异不是"小功能",它改变 frame 是否有资格进入 IP 层](#4. 错误检测差异不是“小功能”,它改变 frame 是否有资格进入 IP 层)
- [5. Protocol multiplexing:SLIP 隐含"就是 IP",PPP 明确写出"这是什么协议"](#5. Protocol multiplexing:SLIP 隐含“就是 IP”,PPP 明确写出“这是什么协议”)
- [6. 地址、DNS、认证:差异根源是"有没有 control plane"](#6. 地址、DNS、认证:差异根源是“有没有 control plane”)
- [7. "接口 up"在两者中不是同一个生命周期语义](#7. “接口 up”在两者中不是同一个生命周期语义)
- [8. lwIP 实现映射:只看最能解释边界的几个符号](#8. lwIP 实现映射:只看最能解释边界的几个符号)
-
- [8.1 SLIP:`slipif_init()` 直接把 IP output 接到 serial framing](#8.1 SLIP:
slipif_init()直接把 IP output 接到 serial framing) - [8.2 PPPoS:`pppos_create()` 创建 link adapter,但 PPP Core 仍拥有 session](#8.2 PPPoS:
pppos_create()创建 link adapter,但 PPP Core 仍拥有 session)
- [8.1 SLIP:`slipif_init()` 直接把 IP output 接到 serial framing](#8.1 SLIP:
- [9. RX execution context:都可以有线程/ISR,但线程模型不是协议本身](#9. RX execution context:都可以有线程/ISR,但线程模型不是协议本身)
- [10. TX error feedback:协议能力与 I/O abstraction 要分开](#10. TX error feedback:协议能力与 I/O abstraction 要分开)
- [11. 大小限制与 overhead:不要只比较固定 header 字节](#11. 大小限制与 overhead:不要只比较固定 header 字节)
- [12. IPv6:区分 lwIP integration 能力与协议标准化历史](#12. IPv6:区分 lwIP integration 能力与协议标准化历史)
- [13. 用统一维度比较 SLIP 与 PPPoS](#13. 用统一维度比较 SLIP 与 PPPoS)
- [14. 工程边界:选择的不是"哪个封装更高级",而是哪一层需要承担配置责任](#14. 工程边界:选择的不是“哪个封装更高级”,而是哪一层需要承担配置责任)
- [15. Stage 28~31 的知识边界](#15. Stage 28~31 的知识边界)
- 资料来源
-
- [S1 lwIP SLIP netif 源码](#[S1] lwIP SLIP netif 源码)
- [S2 lwIP example_app 的 SLIP 创建路径](#[S2] lwIP example_app 的 SLIP 创建路径)
- [S3 RFC 1055:A Nonstandard for Transmission of IP Datagrams over Serial Lines: SLIP](#[S3] RFC 1055:A Nonstandard for Transmission of IP Datagrams over Serial Lines: SLIP)
- [S4 RFC 1661:The Point-to-Point Protocol (PPP)](#[S4] RFC 1661:The Point-to-Point Protocol (PPP))
- [S5 RFC 1662:PPP in HDLC-like Framing](#[S5] RFC 1662:PPP in HDLC-like Framing)
- [S6 lwIP PPP/PPPoS 源码与 example](#[S6] lwIP PPP/PPPoS 源码与 example)
- [S7 RFC 5072:IP Version 6 over PPP](#[S7] RFC 5072:IP Version 6 over PPP)
SLIP(Serial Line Internet Protocol,串行线路 IP)和 PPPoS(PPP over Serial)都能让 IP 数据穿过 serial byte stream,但二者解决的问题并不相同。SLIP 是一个极简的 IP datagram framing :它告诉接收端一段 IP 数据在哪里开始/结束,并对少数字节做 escaping;PPPoS 则把完整 PPP 放到串行链路上,因此除了 framing,还具有 FCS(Frame Check Sequence,帧校验序列)错误检测、Protocol multiplexing(按 PPP Protocol 字段复用多种上层协议)、LCP(Link Control Protocol,链路控制协议)、可选认证、IPCP(Internet Protocol Control Protocol,IPv4 网络控制协议)/IPv6CP(IPv6 Control Protocol,IPv6 网络控制协议)等 control plane(用于建立、协商和维护链路的控制面)。 S3 S4 S5
Stage 28~30 已经完整展开 PPPoS 的 framing、协商和网络配置源码。本篇不再复制那些调用链,而是回答一个独立工程问题:同样是"串口传 IP",SLIP 与 PPPoS 在系统职责、错误语义、配置能力和生命周期上到底差在哪里? lwIP 源码只作为机制映射,不再作为文章骨架。S1S6
阅读前建议:先看协议原文,再用本文建立工程映射
- RFC 1055 --- A Nonstandard for Transmission of IP Datagrams over Serial Lines: SLIP
- 用途:理解 SLIP 的 END(帧结束字节)/ESC(转义前缀)framing,以及它明确不提供 地址协商、type field、错误检测等能力。S3
- RFC 1661 --- The Point-to-Point Protocol (PPP)
- 用途:理解 PPP 为什么有 Protocol field(协议类型字段)、LCP(链路控制协议)/NCP(网络控制协议)和 session phase(会话阶段),而不是只有一个串口封装器。S4
- RFC 1662 --- PPP in HDLC-like Framing
- 用途:理解异步 PPP 的 Flag(帧边界标记)、Control Escape(转义前缀)、ACCM(异步控制字符映射)与 FCS(帧校验序列)。S5
- lwIP
slipif.c与 lwIP PPP source
1. 先看系统位置:两者共享 serial transport,但不是同一层次的"串口协议"
serial transport 只提供字节收发。SLIP 直接位于 serial 与 IP 之间;PPPoS 位于 serial 与 PPP Core 之间,而 PPP Core 再承载 IPv4、IPv6 和多个 control protocol。S1S4S6
#mermaid-svg-ISPaEr5cylAmCv9m{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-ISPaEr5cylAmCv9m .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ISPaEr5cylAmCv9m .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ISPaEr5cylAmCv9m .error-icon{fill:#552222;}#mermaid-svg-ISPaEr5cylAmCv9m .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ISPaEr5cylAmCv9m .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ISPaEr5cylAmCv9m .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ISPaEr5cylAmCv9m .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ISPaEr5cylAmCv9m .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ISPaEr5cylAmCv9m .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ISPaEr5cylAmCv9m .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ISPaEr5cylAmCv9m .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ISPaEr5cylAmCv9m .marker.cross{stroke:#333333;}#mermaid-svg-ISPaEr5cylAmCv9m svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ISPaEr5cylAmCv9m p{margin:0;}#mermaid-svg-ISPaEr5cylAmCv9m .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ISPaEr5cylAmCv9m .cluster-label text{fill:#333;}#mermaid-svg-ISPaEr5cylAmCv9m .cluster-label span{color:#333;}#mermaid-svg-ISPaEr5cylAmCv9m .cluster-label span p{background-color:transparent;}#mermaid-svg-ISPaEr5cylAmCv9m .label text,#mermaid-svg-ISPaEr5cylAmCv9m span{fill:#333;color:#333;}#mermaid-svg-ISPaEr5cylAmCv9m .node rect,#mermaid-svg-ISPaEr5cylAmCv9m .node circle,#mermaid-svg-ISPaEr5cylAmCv9m .node ellipse,#mermaid-svg-ISPaEr5cylAmCv9m .node polygon,#mermaid-svg-ISPaEr5cylAmCv9m .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ISPaEr5cylAmCv9m .rough-node .label text,#mermaid-svg-ISPaEr5cylAmCv9m .node .label text,#mermaid-svg-ISPaEr5cylAmCv9m .image-shape .label,#mermaid-svg-ISPaEr5cylAmCv9m .icon-shape .label{text-anchor:middle;}#mermaid-svg-ISPaEr5cylAmCv9m .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ISPaEr5cylAmCv9m .rough-node .label,#mermaid-svg-ISPaEr5cylAmCv9m .node .label,#mermaid-svg-ISPaEr5cylAmCv9m .image-shape .label,#mermaid-svg-ISPaEr5cylAmCv9m .icon-shape .label{text-align:center;}#mermaid-svg-ISPaEr5cylAmCv9m .node.clickable{cursor:pointer;}#mermaid-svg-ISPaEr5cylAmCv9m .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ISPaEr5cylAmCv9m .arrowheadPath{fill:#333333;}#mermaid-svg-ISPaEr5cylAmCv9m .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ISPaEr5cylAmCv9m .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ISPaEr5cylAmCv9m .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ISPaEr5cylAmCv9m .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ISPaEr5cylAmCv9m .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ISPaEr5cylAmCv9m .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ISPaEr5cylAmCv9m .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ISPaEr5cylAmCv9m .cluster text{fill:#333;}#mermaid-svg-ISPaEr5cylAmCv9m .cluster span{color:#333;}#mermaid-svg-ISPaEr5cylAmCv9m 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-ISPaEr5cylAmCv9m .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ISPaEr5cylAmCv9m rect.text{fill:none;stroke-width:0;}#mermaid-svg-ISPaEr5cylAmCv9m .icon-shape,#mermaid-svg-ISPaEr5cylAmCv9m .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ISPaEr5cylAmCv9m .icon-shape p,#mermaid-svg-ISPaEr5cylAmCv9m .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ISPaEr5cylAmCv9m .icon-shape .label rect,#mermaid-svg-ISPaEr5cylAmCv9m .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ISPaEr5cylAmCv9m .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ISPaEr5cylAmCv9m .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ISPaEr5cylAmCv9m :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} PPPoS path
IPv4 / IPv6 / LCP / IPCP / ...
PPP Protocol multiplexing
HDLC-like framing + FCS
serial byte stream
SLIP path
IPv4 / IPv6 datagram
SLIP END/ESC framing
serial byte stream
这里的关键不是哪条链更长,而是职责层次 :SLIP framing 完成后,payload 直接就是 IP datagram;PPPoS framing 完成后,payload 仍然先进入 PPP Core,由 Protocol field 决定这是 IP data 还是 control packet。S1S3S6
2. 同一个 IPv4 datagram,在两条路径上发生了什么
从上层交给 netif 的 IPv4 packet 出发,可以把 TX 数据流统一成下面两条路径:
#mermaid-svg-4fWtpGkRgPxqBEyO{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-4fWtpGkRgPxqBEyO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-4fWtpGkRgPxqBEyO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-4fWtpGkRgPxqBEyO .error-icon{fill:#552222;}#mermaid-svg-4fWtpGkRgPxqBEyO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-4fWtpGkRgPxqBEyO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-4fWtpGkRgPxqBEyO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-4fWtpGkRgPxqBEyO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-4fWtpGkRgPxqBEyO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-4fWtpGkRgPxqBEyO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-4fWtpGkRgPxqBEyO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-4fWtpGkRgPxqBEyO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-4fWtpGkRgPxqBEyO .marker.cross{stroke:#333333;}#mermaid-svg-4fWtpGkRgPxqBEyO svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-4fWtpGkRgPxqBEyO p{margin:0;}#mermaid-svg-4fWtpGkRgPxqBEyO .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-4fWtpGkRgPxqBEyO .cluster-label text{fill:#333;}#mermaid-svg-4fWtpGkRgPxqBEyO .cluster-label span{color:#333;}#mermaid-svg-4fWtpGkRgPxqBEyO .cluster-label span p{background-color:transparent;}#mermaid-svg-4fWtpGkRgPxqBEyO .label text,#mermaid-svg-4fWtpGkRgPxqBEyO span{fill:#333;color:#333;}#mermaid-svg-4fWtpGkRgPxqBEyO .node rect,#mermaid-svg-4fWtpGkRgPxqBEyO .node circle,#mermaid-svg-4fWtpGkRgPxqBEyO .node ellipse,#mermaid-svg-4fWtpGkRgPxqBEyO .node polygon,#mermaid-svg-4fWtpGkRgPxqBEyO .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-4fWtpGkRgPxqBEyO .rough-node .label text,#mermaid-svg-4fWtpGkRgPxqBEyO .node .label text,#mermaid-svg-4fWtpGkRgPxqBEyO .image-shape .label,#mermaid-svg-4fWtpGkRgPxqBEyO .icon-shape .label{text-anchor:middle;}#mermaid-svg-4fWtpGkRgPxqBEyO .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-4fWtpGkRgPxqBEyO .rough-node .label,#mermaid-svg-4fWtpGkRgPxqBEyO .node .label,#mermaid-svg-4fWtpGkRgPxqBEyO .image-shape .label,#mermaid-svg-4fWtpGkRgPxqBEyO .icon-shape .label{text-align:center;}#mermaid-svg-4fWtpGkRgPxqBEyO .node.clickable{cursor:pointer;}#mermaid-svg-4fWtpGkRgPxqBEyO .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-4fWtpGkRgPxqBEyO .arrowheadPath{fill:#333333;}#mermaid-svg-4fWtpGkRgPxqBEyO .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-4fWtpGkRgPxqBEyO .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-4fWtpGkRgPxqBEyO .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4fWtpGkRgPxqBEyO .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-4fWtpGkRgPxqBEyO .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4fWtpGkRgPxqBEyO .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-4fWtpGkRgPxqBEyO .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-4fWtpGkRgPxqBEyO .cluster text{fill:#333;}#mermaid-svg-4fWtpGkRgPxqBEyO .cluster span{color:#333;}#mermaid-svg-4fWtpGkRgPxqBEyO 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-4fWtpGkRgPxqBEyO .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-4fWtpGkRgPxqBEyO rect.text{fill:none;stroke-width:0;}#mermaid-svg-4fWtpGkRgPxqBEyO .icon-shape,#mermaid-svg-4fWtpGkRgPxqBEyO .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4fWtpGkRgPxqBEyO .icon-shape p,#mermaid-svg-4fWtpGkRgPxqBEyO .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-4fWtpGkRgPxqBEyO .icon-shape .label rect,#mermaid-svg-4fWtpGkRgPxqBEyO .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4fWtpGkRgPxqBEyO .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-4fWtpGkRgPxqBEyO .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-4fWtpGkRgPxqBEyO :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} SLIP
PPPoS
IPv4 datagram
selected netif
slipif_output_v4()
slipif_output(): END/ESC encode
sio_send()
ppp_netif_output(protocol=PPP_IP)
pppos_netif_output()
Protocol + FCS + escaping
ppp_output_cb()
RX 则反过来:
- SLIP parser 看到 END,得到的完整
pbuf直接交给netif->input();upstream example 把该 callback 设成ip_input()。S1S2 - PPPoS parser 完成 frame/FCS 校验后先交给
ppp_input();ppp_input()读取Protocolfield,再决定进入 IPv4、IPv6、LCP、PAP、CHAP、IPCP 等哪一个 handler。S6
因此,"串口上都能发 IP"并不能推出两者具有相同的数据链路语义。
3. Framing:SLIP 只解决边界与转义,PPPoS 还承担 PPP 链路格式
SLIP 的 wire rule 极少:END 标记 packet boundary,payload 中如果出现 END 或 ESC,就用 ESC sequence 转义。RFC 1055 没有为 SLIP 定义 type field、sequence number 或 checksum/FCS。S3
PPPoS 使用 RFC 1662 的 asynchronous HDLC-like framing。除了 Flag/Control Escape,还涉及 Address/Control field、PPP Protocol field、FCS,以及 LCP 协商可能改变的 ACCM/PFC/ACFC。S4S5
| 维度 | SLIP | PPPoS |
|---|---|---|
| 帧边界 | END | Flag Sequence 0x7E |
| escaping | END/ESC 两类特殊字节 | Control Escape + ACCM 规则 |
| payload 类型标识 | 无;解码后默认就是 IP datagram | 有 PPP Protocol field,可区分 IP 与 control protocol |
| link-level error detection | RFC 1055 未定义 | 16-bit FCS(当前 lwIP PPPoS 路径)[S5](#维度 SLIP PPPoS 帧边界 END Flag Sequence 0x7E escaping END/ESC 两类特殊字节 Control Escape + ACCM 规则 payload 类型标识 无;解码后默认就是 IP datagram 有 PPP Protocol field,可区分 IP 与 control protocol link-level error detection RFC 1055 未定义 16-bit FCS(当前 lwIP PPPoS 路径)S5S6 framing 是否受协商影响 否 会;PFC/ACFC/ACCM 可由 LCP 结果改变)[S6](#维度 SLIP PPPoS 帧边界 END Flag Sequence 0x7E escaping END/ESC 两类特殊字节 Control Escape + ACCM 规则 payload 类型标识 无;解码后默认就是 IP datagram 有 PPP Protocol field,可区分 IP 与 control protocol link-level error detection RFC 1055 未定义 16-bit FCS(当前 lwIP PPPoS 路径)S5S6 framing 是否受协商影响 否 会;PFC/ACFC/ACCM 可由 LCP 结果改变) |
| framing 是否受协商影响 | 否 | 会;PFC/ACFC/ACCM 可由 LCP 结果改变 |
4. 错误检测差异不是"小功能",它改变 frame 是否有资格进入 IP 层
SLIP parser 能判断的是 framing 是否完整,例如 END 到达、ESC sequence 如何恢复。协议本身没有 frame-level FCS,因此接收端无法依靠 SLIP framing 判断某个完整 datagram 是否在串行链路中发生 bit error。S3
PPPoS 则在 pppos_input() 中持续累计 FCS;只有完整 frame 的 FCS 满足条件,packet 才继续进入 ppp_input()。因此 FCS 在这里属于进入 PPP Core 前的 link-level gate ,和后续 IPv4 header checksum、TCP/UDP checksum 不是同一层检查。S5S6
#mermaid-svg-VXeVqK31xChqqtn0{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-VXeVqK31xChqqtn0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-VXeVqK31xChqqtn0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-VXeVqK31xChqqtn0 .error-icon{fill:#552222;}#mermaid-svg-VXeVqK31xChqqtn0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-VXeVqK31xChqqtn0 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-VXeVqK31xChqqtn0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-VXeVqK31xChqqtn0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-VXeVqK31xChqqtn0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-VXeVqK31xChqqtn0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-VXeVqK31xChqqtn0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-VXeVqK31xChqqtn0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-VXeVqK31xChqqtn0 .marker.cross{stroke:#333333;}#mermaid-svg-VXeVqK31xChqqtn0 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-VXeVqK31xChqqtn0 p{margin:0;}#mermaid-svg-VXeVqK31xChqqtn0 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-VXeVqK31xChqqtn0 .cluster-label text{fill:#333;}#mermaid-svg-VXeVqK31xChqqtn0 .cluster-label span{color:#333;}#mermaid-svg-VXeVqK31xChqqtn0 .cluster-label span p{background-color:transparent;}#mermaid-svg-VXeVqK31xChqqtn0 .label text,#mermaid-svg-VXeVqK31xChqqtn0 span{fill:#333;color:#333;}#mermaid-svg-VXeVqK31xChqqtn0 .node rect,#mermaid-svg-VXeVqK31xChqqtn0 .node circle,#mermaid-svg-VXeVqK31xChqqtn0 .node ellipse,#mermaid-svg-VXeVqK31xChqqtn0 .node polygon,#mermaid-svg-VXeVqK31xChqqtn0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-VXeVqK31xChqqtn0 .rough-node .label text,#mermaid-svg-VXeVqK31xChqqtn0 .node .label text,#mermaid-svg-VXeVqK31xChqqtn0 .image-shape .label,#mermaid-svg-VXeVqK31xChqqtn0 .icon-shape .label{text-anchor:middle;}#mermaid-svg-VXeVqK31xChqqtn0 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-VXeVqK31xChqqtn0 .rough-node .label,#mermaid-svg-VXeVqK31xChqqtn0 .node .label,#mermaid-svg-VXeVqK31xChqqtn0 .image-shape .label,#mermaid-svg-VXeVqK31xChqqtn0 .icon-shape .label{text-align:center;}#mermaid-svg-VXeVqK31xChqqtn0 .node.clickable{cursor:pointer;}#mermaid-svg-VXeVqK31xChqqtn0 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-VXeVqK31xChqqtn0 .arrowheadPath{fill:#333333;}#mermaid-svg-VXeVqK31xChqqtn0 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-VXeVqK31xChqqtn0 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-VXeVqK31xChqqtn0 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VXeVqK31xChqqtn0 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-VXeVqK31xChqqtn0 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VXeVqK31xChqqtn0 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-VXeVqK31xChqqtn0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-VXeVqK31xChqqtn0 .cluster text{fill:#333;}#mermaid-svg-VXeVqK31xChqqtn0 .cluster span{color:#333;}#mermaid-svg-VXeVqK31xChqqtn0 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-VXeVqK31xChqqtn0 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-VXeVqK31xChqqtn0 rect.text{fill:none;stroke-width:0;}#mermaid-svg-VXeVqK31xChqqtn0 .icon-shape,#mermaid-svg-VXeVqK31xChqqtn0 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VXeVqK31xChqqtn0 .icon-shape p,#mermaid-svg-VXeVqK31xChqqtn0 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-VXeVqK31xChqqtn0 .icon-shape .label rect,#mermaid-svg-VXeVqK31xChqqtn0 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VXeVqK31xChqqtn0 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-VXeVqK31xChqqtn0 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-VXeVqK31xChqqtn0 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} SLIP: no protocol FCS
PPPoS: FCS valid
PPPoS: FCS invalid
serial bytes
framing parser
link-level integrity check
IP datagram
PPP Protocol demux
drop frame
5. Protocol multiplexing:SLIP 隐含"就是 IP",PPP 明确写出"这是什么协议"
SLIP 没有协议类型字段。lwIP 的 slipif_output_v4() 与 slipif_output_v6() 最终都调用同一个 slipif_output(),而 RX 完成后直接走 netif->input();example 选择 ip_input(),由 IP 入口继续辨认 IPv4/IPv6。S1S2
PPP frame 则显式携带 Protocol field。例如 IPv4 使用 PPP_IP,IPv6 使用 PPP_IPV6,LCP/PAP/CHAP/IPCP/IPv6CP 也各自有 protocol number。ppp_input() 读取这个字段后再做 protocol demultiplex。S4S6
这也是为什么 PPP 可以在同一条 serial link 上同时承载数据面 和控制面,而 SLIP 本身只负责把 IP datagram 运过去。
6. 地址、DNS、认证:差异根源是"有没有 control plane"
SLIP 没有 LCP/NCP。upstream example 在 netif_add() 之前准备 IPv4 address、gateway 和 netmask,然后直接 netif_set_up();这些值来自 example/Port 配置,不是 SLIP 线上协商的结果。S2
PPPoS 承载完整 PPP control plane:
#mermaid-svg-4BPTv96AyNavdBlt{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-4BPTv96AyNavdBlt .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-4BPTv96AyNavdBlt .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-4BPTv96AyNavdBlt .error-icon{fill:#552222;}#mermaid-svg-4BPTv96AyNavdBlt .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-4BPTv96AyNavdBlt .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-4BPTv96AyNavdBlt .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-4BPTv96AyNavdBlt .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-4BPTv96AyNavdBlt .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-4BPTv96AyNavdBlt .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-4BPTv96AyNavdBlt .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-4BPTv96AyNavdBlt .marker{fill:#333333;stroke:#333333;}#mermaid-svg-4BPTv96AyNavdBlt .marker.cross{stroke:#333333;}#mermaid-svg-4BPTv96AyNavdBlt svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-4BPTv96AyNavdBlt p{margin:0;}#mermaid-svg-4BPTv96AyNavdBlt .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-4BPTv96AyNavdBlt .cluster-label text{fill:#333;}#mermaid-svg-4BPTv96AyNavdBlt .cluster-label span{color:#333;}#mermaid-svg-4BPTv96AyNavdBlt .cluster-label span p{background-color:transparent;}#mermaid-svg-4BPTv96AyNavdBlt .label text,#mermaid-svg-4BPTv96AyNavdBlt span{fill:#333;color:#333;}#mermaid-svg-4BPTv96AyNavdBlt .node rect,#mermaid-svg-4BPTv96AyNavdBlt .node circle,#mermaid-svg-4BPTv96AyNavdBlt .node ellipse,#mermaid-svg-4BPTv96AyNavdBlt .node polygon,#mermaid-svg-4BPTv96AyNavdBlt .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-4BPTv96AyNavdBlt .rough-node .label text,#mermaid-svg-4BPTv96AyNavdBlt .node .label text,#mermaid-svg-4BPTv96AyNavdBlt .image-shape .label,#mermaid-svg-4BPTv96AyNavdBlt .icon-shape .label{text-anchor:middle;}#mermaid-svg-4BPTv96AyNavdBlt .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-4BPTv96AyNavdBlt .rough-node .label,#mermaid-svg-4BPTv96AyNavdBlt .node .label,#mermaid-svg-4BPTv96AyNavdBlt .image-shape .label,#mermaid-svg-4BPTv96AyNavdBlt .icon-shape .label{text-align:center;}#mermaid-svg-4BPTv96AyNavdBlt .node.clickable{cursor:pointer;}#mermaid-svg-4BPTv96AyNavdBlt .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-4BPTv96AyNavdBlt .arrowheadPath{fill:#333333;}#mermaid-svg-4BPTv96AyNavdBlt .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-4BPTv96AyNavdBlt .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-4BPTv96AyNavdBlt .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4BPTv96AyNavdBlt .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-4BPTv96AyNavdBlt .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4BPTv96AyNavdBlt .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-4BPTv96AyNavdBlt .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-4BPTv96AyNavdBlt .cluster text{fill:#333;}#mermaid-svg-4BPTv96AyNavdBlt .cluster span{color:#333;}#mermaid-svg-4BPTv96AyNavdBlt 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-4BPTv96AyNavdBlt .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-4BPTv96AyNavdBlt rect.text{fill:none;stroke-width:0;}#mermaid-svg-4BPTv96AyNavdBlt .icon-shape,#mermaid-svg-4BPTv96AyNavdBlt .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4BPTv96AyNavdBlt .icon-shape p,#mermaid-svg-4BPTv96AyNavdBlt .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-4BPTv96AyNavdBlt .icon-shape .label rect,#mermaid-svg-4BPTv96AyNavdBlt .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4BPTv96AyNavdBlt .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-4BPTv96AyNavdBlt .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-4BPTv96AyNavdBlt :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} LCP
optional PAP / CHAP
IPCP / IPv6CP
address / peer DNS / IPv6 link-local state
Network Protocol usable
Stage 29 已经解释 LCP/Auth/NCP,Stage 30 已经解释 negotiated address、peer DNS、default-netif policy、link down 与 reconnect。本篇只保留这个职责映射,不重复逐函数展开。S6
7. "接口 up"在两者中不是同一个生命周期语义
SLIP example 创建 netif 后可以直接 netif_set_up();只要 serial I/O 和静态网络参数已经准备好,就不存在"必须等待 LCP/NCP OPENED 才允许 IP"的协议门槛。S2
PPPoS 不同。pppos_create() 创建的是 link adapter + PPP control block,ppp_connect() 之后还要经历 LCP、可选认证和 NCP。lwIP 的 PPP Core 还会在 ppp_input() 根据当前 phase/LCP state 丢弃不应出现的数据协议 packet。S6
因此不能把 netif_set_up() 与 PPP_PHASE_RUNNING 直接类比成同一个状态:前者是 lwIP interface administrative state,后者属于 PPP session/control-plane progression。
8. lwIP 实现映射:只看最能解释边界的几个符号
Theory-of-Operation 不需要再复制 Stage 28~30 的完整 PPP 调用链,只需把机制定位到实现。
8.1 SLIP:slipif_init() 直接把 IP output 接到 serial framing
slipif_init() 把 IPv4/IPv6 output callback 绑定到 SLIP encoder,并打开 serial device:S1
c
#if LWIP_IPV4
netif->output = slipif_output_v4;
#endif
#if LWIP_IPV6
netif->output_ip6 = slipif_output_v6;
#endif
netif->mtu = SLIP_MAX_SIZE;
priv->sd = sio_open(sio_num);
这段实现没有创建额外 control protocol object。RX parser 完整组出 packet 后,slipif_rxbyte_input() 直接调用 netif->input(p, netif)。S1
8.2 PPPoS:pppos_create() 创建 link adapter,但 PPP Core 仍拥有 session
Stage 28 的 pppos_create() 通过 ppp_new() 创建真正的 PPP control block/netif,并注册 serial output callback;ppp_connect() 才启动 session。PPPoS 自身不是 LCP/IPCP 状态机的 owner。S6
这两个入口已经足以解释架构差异:
text
SLIP: netif -> framing adapter -> serial
PPPoS: netif -> PPP Core -> PPPoS framing adapter -> serial
9. RX execution context:都可以有线程/ISR,但线程模型不是协议本身
当前 lwIP slipif 支持几种 RX integration:独立 SLIP_USE_RX_THREAD 线程、主循环 slipif_poll(),以及配置允许时的 ISR enqueue + slipif_process_rxqueue()。S1
PPPoS example 使用自己的 serial RX thread,再通过 pppos_input_tcpip() 把字节交回 tcpip_thread;如果配置改变,PPPoS 也有其他 execution model。S6
因此"SLIP 是线程方式、PPPoS 是 Core 线程方式"不是协议结论。能比较的是:当前 lwIP integration 为了满足 Core locking/threading contract,分别提供了哪些桥接方式。
10. TX error feedback:协议能力与 I/O abstraction 要分开
当前 slipif_output() 最终调用 sio_send();该 serial abstraction 没有提供可传播的发送失败返回值,因此 slipif_output_v4()/v6() 的 API 注释说明当前路径总是返回 ERR_OK。S1
PPPoS 的 ppp_output_cb 类型允许应用 callback 返回写入长度,PPPoS encoder 可以依据回调结果形成自己的返回语义。S6
这属于当前 lwIP I/O abstraction 的实现差异,不能泛化成"SLIP 协议永远无法报告错误、PPP 协议一定能报告 UART 错误"。协议 wire format 与本地 driver/API error semantics 是两个层次。
11. 大小限制与 overhead:不要只比较固定 header 字节
SLIP 的 SLIP_MAX_SIZE 是当前 lwIP parser 接收 packet 的实现上限;PPP 的 MRU(Maximum-Receive-Unit,最大接收单元)属于 PPP 链路参数,并可通过 LCP 参与协商。S1S4S6
两者的 serial overhead 也不是"固定多几个 header byte"这么简单:
- SLIP 遇到 END/ESC 时会扩展 escaping;
- PPPoS 的 overhead 受 Address/Control、Protocol 压缩、FCS,以及 ACCM 需要 escape 的字节数量影响。S3S5
所以没有实际 payload 分布和链路配置时,不应给出一个无条件的"某方案一定更省带宽"的结论。
12. IPv6:区分 lwIP integration 能力与协议标准化历史
当前 lwIP slipif 可以设置 netif->output_ip6 = slipif_output_v6,因此实现层面能够把 IPv6 datagram 直接通过 SLIP framing 送到串行链路。S1
但 RFC 1055 本身是历史上的 IP-over-serial SLIP 文档,不提供类似 PPP IPv6CP 的 IPv6 control plane。PPP 则由 RFC 5072 定义 IPv6 over PPP 和 IPv6CP。S7
因此应该表述为:当前 lwIP 可以把 IPv6 packet 走 slipif,但它没有因此获得 PPP IPv6CP 那套协商语义。
13. 用统一维度比较 SLIP 与 PPPoS
| 维度 | SLIP | PPPoS |
|---|---|---|
| 核心职责 | 最小 IP datagram serial framing | 完整 PPP over serial link adapter + PPP control plane |
| RX 完成后的下一层 | 通常直接进入 IP input | 先进入 ppp_input() 做 Protocol demux |
| link-level FCS | 无协议定义 | 有 HDLC-like FCS |
| 协议类型复用 | 无独立 type field | PPP Protocol field |
| 链路参数协商 | 无 | LCP |
| 认证 | 无 | 可选 PAP/CHAP/EAP 等,取决于配置/协商 |
| IPv4 参数协商 | 无 | IPCP |
| IPv6 control plane | 无 IPv6CP | IPv6CP |
| peer DNS | 无协议机制 | 可通过 IPCP extension 获取,取决于实现/配置 |
| framing 参数可协商 | 基本固定 | ACCM/PFC/ACFC 等受 LCP 影响 |
| 当前 lwIP integration | thread / poll / ISR queue | PPPoS callback + Core/thread bridge 等 |
| 生命周期复杂度 | 小 | 明显更高,因为存在 session phase 和 control protocol FSM |
表中"无"表示该协议本身不提供对应机制,不代表产品不能通过其他私有命令、静态配置或上层协议补充这些能力。
14. 工程边界:选择的不是"哪个封装更高级",而是哪一层需要承担配置责任
如果链路两端已经通过产品约定预先知道 IP 参数,只需要极小的 datagram boundary/escaping 机制,那么 SLIP 的设计目标与这种场景更接近。代价是地址配置、peer 能力、认证、link-level integrity 等职责需要由其他层解决。S3
如果链路需要建立 session、协商链路参数、可选认证、配置 IPv4/IPv6、获得 peer DNS,并希望多种 Network/Control Protocol 在同一 link 上明确复用,那么 PPP/PPPoS 提供的是一套完整 control plane;代价是实现状态、定时器、协商失败路径和生命周期都更复杂。S4S5S6
这个判断不是性能排名。实际项目仍要结合 peer 支持、modem 接口、RAM/ROM、认证要求、故障恢复和部署环境决定。
15. Stage 28~31 的知识边界
经过四篇后,串口网络路径已经形成清晰分层:
- Stage 28:PPP Core 与 PPPoS framing,回答 serial bytes 如何变成 PPP packet;
- Stage 29:LCP/Auth/NCP,回答 PPP session 为什么需要协商才能进入 Network/Running;
- Stage 30:地址、DNS、route policy 与 teardown/reconnect,回答协商结果怎样成为可用
netif; - Stage 31:SLIP vs PPPoS,回答两种 serial IP 方案的职责边界与工程取舍。
Stage 31 到这里停止,不再重新展开 PPP FSM 或 address lifecycle 的源码细节。
资料来源
S1 lwIP SLIP netif 源码
- 类型:目标版本上游源码
- 版本:commit
d08f4773edd0182b7910fc8f046eed82ffcd67c9 - 定位:
src/netif/slipif.c:slipif_init()、slipif_output()、slipif_output_v4()、slipif_output_v6()、slipif_rxbyte()、slipif_rxbyte_input()、slipif_loop_thread()、slipif_poll()、ISR queue 路径;src/include/netif/slipif.h - URL/文档:lwIP slipif.c
- 使用位置:"SLIP 系统位置""framing/escaping""RX/TX 数据流""执行上下文""IPv6 integration"
- 支撑内容:证明当前 pinned lwIP
slipif的真实 framing、pbuf 与 serial I/O 实现
S2 lwIP example_app 的 SLIP 创建路径
- 类型:目标版本上游 example
- 版本:commit
d08f4773edd0182b7910fc8f046eed82ffcd67c9 - 定位:
contrib/examples/example_app/test.c:USE_SLIPIF分支;contrib/examples/example_app/lwipcfg.h - URL/文档:lwIP example_app/test.c
- 使用位置:"SLIP 初始化模型""静态 IPv4 参数""
ip_inputcallback""IPv6 integration" - 支撑内容:证明 upstream example 如何把 SLIP netif 接入 lwIP,而不是把 Port 行为泛化成 Core 规则
S3 RFC 1055:A Nonstandard for Transmission of IP Datagrams over Serial Lines: SLIP
- 类型:IETF 历史协议文档
- 版本:RFC 1055,1988
- URL/文档:RFC 1055
- 使用位置:"建议提前阅读""SLIP framing 职责""END/ESC""能力边界"
- 支撑内容:定义 SLIP 是最小 IP datagram serial framing,并明确其不承担的功能
S4 RFC 1661:The Point-to-Point Protocol (PPP)
- 类型:IETF Internet Standard
- 版本:RFC 1661 / STD 51,1994
- URL/文档:RFC 1661
- 使用位置:"建议提前阅读""PPP control plane""Protocol multiplexing""LCP/NCP""MRU"
- 支撑内容:提供 PPP 链路建立、configuration protocol 与 multi-protocol encapsulation 的规范边界
S5 RFC 1662:PPP in HDLC-like Framing
- 类型:IETF Internet Standard
- 版本:RFC 1662 / STD 51,1994
- URL/文档:RFC 1662
- 使用位置:"建议提前阅读""PPPoS framing""Flag/Control Escape""ACCM/FCS"
- 支撑内容:定义 asynchronous PPP 的 HDLC-like octet framing 与 FCS
S6 lwIP PPP/PPPoS 源码与 example
- 类型:目标版本上游源码与 example
- 版本:commit
d08f4773edd0182b7910fc8f046eed82ffcd67c9 - 定位:
src/netif/ppp/pppos.c、ppp.c、lcp.c、auth.c、ipcp.c、ipv6cp.c、fsm.c;contrib/examples/ppp/pppos_example.c - URL/文档:lwIP PPP source
- 使用位置:"PPPoS 对照模型""framing/FCS""Protocol demux""control plane""lifecycle""执行上下文"
- 支撑内容:作为 Stage 28~30 已展开机制的直接源码依据,用统一维度与 SLIP 对照
S7 RFC 5072:IP Version 6 over PPP
- 类型:IETF 标准规范
- 版本:RFC 5072,2007
- URL/文档:RFC 5072
- 使用位置:"IPv6CP 与 IPv6 over PPP 边界"
- 支撑内容:用于区分 current lwIP raw IPv6-over-slip integration 与正式 PPP IPv6CP/IPv6 protocol control