聚焦 3GPP TS 38.322 V19.x,拆解 RLC AM 确认模式下的 ARQ 重传、STATUS PDU 交互、再分段(Resegmentation)以及三层定时器(t-PollRetransmit / t-Reassembly / t-StatusProhibit)的联动博弈机制。
5G NR 的可靠性保障是一个双层架构:
| 层次 | 机制 | 重传范围 | 典型时延 |
|---|---|---|---|
| L1(PHY) | HARQ(软合并) | 单个 MAC PDU / 传输块 | 1~4 个 slot |
| L2(RLC) | ARQ(确认重传) | 单个 RLC SDU 或其分段 | 几十到几百 ms |
HARQ 负责快速、物理层的纠错,但存在两个盲区:
RLC AM 的 ARQ 正是这两道防线之间的兜底机制。TS 38.322 Section 5.2.1 定义了 AM RLC 实体的完整架构,包含发送端(Transmitting Side)和接收端(Receiving Side),两端各自维护一套状态变量和定时器。
核心设计意图:HARQ 解决"微秒级"的快衰落,RLC ARQ 解决"毫秒级"的持续信道恶化和 HARQ 覆盖不到的边缘场景。
TS 38.322 Section 7 定义了 AM RLC 实体的全部状态变量。理解这些变量是掌握 ARQ 博弈的前提。
graph TB
subgraph TX["发送端 Transmitting Side"]
VTA["VT(A)<br/>最早未确认SN"]
VTS["VT(S)<br/>下一个待分配SN"]
VTMS["VT(MS)<br/>发送窗口上沿<br/>= VT(A) + AM_Window_Size"]
POLL_SN["POLL_SN<br/>最近一次Poll时的SN"]
PDU_WITHOUT_POLL["PDU_WITHOUT_POLL<br/>距上次Poll已发PDU数"]
BYTE_WITHOUT_POLL["BYTE_WITHOUT_POLL<br/>距上次Poll已发字节数"]
end
subgraph RX["接收端 Receiving Side"]
VRR["VR(R)<br/>下一个期望的按序SN"]
VRX["VR(X)<br/>t-Reassembly触发SN"]
VRMS["VR(MS)<br/>STATUS PDU报告上沿<br/>= VR(R) + AM_Window_Size"]
VRH["VR(H)<br/>收到的最高SN+1"]
end
VTA -->|"滑动:收到ACK后前推"| VTS
VTS -->|"窗口约束:不能超过VT(MS)"| VTMS
VRR -->|"按序接收后前推"| VRH
VRX -->|"t-Reassembly到期时"| VRMS
| 变量 | 所在端 | 含义 | 更新时机 |
|---|---|---|---|
| VT(A) | TX | 最早的尚未被确认的 SN | 收到 ACK_SN > VT(A) 的 STATUS PDU |
| VT(S) | TX | 下一个待分配的新 SN | 每次发送新 AMD PDU 后 +1 |
| VT(MS) | TX | 发送窗口上沿 = VT(A) + AM_Window_Size | 随 VT(A) 滑动 |
| VR(R) | RX | 下一个期望按序接收的 SN | 按序收到 SN = VR(R) 后前推 |
| VR(X) | RX | t-Reassembly 监控的 SN | 检测到缺口时设置 |
| VR(MS) | RX | STATUS PDU 可报告的上沿 | VR(R) 更新后前推 |
| VR(H) | RX | 收到的最高 SN + 1 | 收到任何 SN ≥ VR(H) 的 PDU |
AM_Window_Size 取决于 SN 长度配置(TS 38.322 Section 7):
| SN 长度 | AM_Window_Size | 适用场景 |
|---|---|---|
| 12 bit | 2048 | 典型 DRB 承载 |
| 18 bit | 262144 | 高吞吐量场景(如 eMBB 大包) |
下面是基于 TS 38.322 Section 5.3.3(ARQ 复位)和 Section 5.2.3(STATUS PDU 传输)的完整 ARQ 交互时序图:
sequenceDiagram
participant TX as AM RLC TX
participant RX as AM RLC RX
Note over TX,RX: 正常发送阶段
TX->>RX: AMD PDU (SN=10, SI=完整)
TX->>RX: AMD PDU (SN=11, P=1, SI=完整)
Note right of TX: P=1 触发Poll<br/>启动 t-PollRetransmit
Note over RX: 收到SN=11<br/>检测缺口: 缺少SN=10
Note over RX: 启动 t-Reassembly
RX-->>TX: STATUS PDU (ACK_SN=10, NACK_SN=10)
Note left of RX: 检查 t-StatusProhibit<br/>未运行才发送
Note over TX: 收到STATUS<br/>停止 t-PollRetransmit
Note over TX,RX: 重传阶段 - 原始PDU过大需再分段
TX->>RX: AMD PDU segment (SN=10, SI=第一段, SO=0)
TX->>RX: AMD PDU segment (SN=10, SI=最后段, SO=500)
Note right of TX: 再分段: 原始1000字节<br/>分为两段发送
Note over RX: t-Reassembly 运行中<br/>等待SN=10完整接收
RX-->>TX: STATUS PDU (ACK_SN=12)
Note over TX: VT(A) 滑动到 12
Note over TX: 通知 PDCP: SDU 10,11 已确认
发送端(TS 38.322 Section 5.3.2):
1. PDCP 通过 RLC_DATA_REQ 原语递交 RLC SDU
2. AM RLC 将 SDU 放入 Transmission Buffer,分配 SN = VT(S)
3. 当 MAC 层通过 MAC_DATA_REQ 请求时,RLC 从 Buffer 取出 SDU 进行分段(如需要),添加 RLC 头(含 SN、SI、P 字段)
4. 如果触发 Poll 条件满足(见第四章),设置 P=1,记录 POLL_SN = VT(S)-1,启动 t-PollRetransmit
接收端(TS 38.322 Section 5.2.3): 1. 收到 AMD PDU,根据 SN 和 SI 判断是否为分段 2. 如果 SN ≥ VR(H),更新 VR(H) = SN + 1 3. 如果检测到缺口(SN > VR(R) 但 VR(R) 尚未收到),启动 t-Reassembly,设置 VR(X) = VR(H) 4. 如果 P=1,触发 STATUS PDU 发送(受 t-StatusProhibit 约束)
STATUS PDU 是 RLC AM 的"心脏跳动"。TS 38.322 Section 6.3.3 定义了其精确格式:
STATUS PDU 格式 (TS 38.322 Section 6.3.3):
+--+----+--------+----+----+----+
|D/C| CPT|ACK_SN | E1 | E2 | E3 |
+--+----+--------+----+----+----+
| NACK_SN (可选) |
| SOstart (可选, E2=1) |
| SOend (可选, E2=1) |
| NACK_SN range (可选, E3=1) |
+---------------------------------+
| 字段 | 长度 | 含义 |
|---|---|---|
| D/C | 1 bit | 0=数据PDU, 1=控制PDU |
| CPT | 3 bits | 控制PDU类型,000=STATUS PDU |
| ACK_SN | 12/18 bits | 累积确认:所有 SN < ACK_SN 的 PDU 已收到 |
| E1 | 1 bit | 1=后面跟着 NACK_SN |
| E2 | 1 bit | 1=该 NACK 后面跟着 SOstart/SOend(分段级NACK) |
| E3 | 1 bit | 1=该 NACK 表示一个 SN 范围(R18新增) |
| NACK_SN | 12/18 bits | 需要重传的 SN |
| SOstart | 15 bits | 需要重传的分段起始字节偏移 |
| SOend | 15 bits | 需要重传的分段结束字节偏移(0x7FFF=到末尾) |
设计意图:E1/E2/E3 的扩展标志链式结构允许一个 STATUS PDU 中报告多个不连续的缺口和分段级的精确NACK,避免逐个 PDU 报告带来的信令开销。
Poll 是 RLC AM ARQ 中的"主动试探"机制。发送端不能一直被动等待接收端的 NACK,需要主动设置 P=1 来触发 STATUS 报告。
flowchart TD
START[发送新AMD PDU/段] --> CHECK1{新PDU到Buffer<br/>且Buffer变空?}
CHECK1 -->|是| POLL[设置 P=1]
CHECK1 -->|否| CHECK2{新段到Retx Buffer<br/>且Retx Buffer变空?}
CHECK2 -->|是| POLL
CHECK2 -->|否| CHECK3{PDU_WITHOUT_POLL<br/>≥ pollPDU?}
CHECK3 -->|是| POLL
CHECK3 -->|否| CHECK4{BYTE_WITHOUT_POLL<br/>≥ pollByte?}
CHECK4 -->|是| POLL
CHECK4 -->|否| CHECK5{t-PollRetransmit<br/>超时?}
CHECK5 -->|是| POLL
CHECK5 -->|否| NOP[不设置Poll]
POLL --> RECORD[记录 POLL_SN = VT(S)-1]
RECORD --> RESTART[重启 t-PollRetransmit]
RESTART --> RESET_COUNTER[PDU_WITHOUT_POLL=0<br/>BYTE_WITHOUT_POLL=0]
RRC 通过 RLC-BearerConfig → RLC-Config → AM-RLC 配置以下参数(TS 38.331 Section 6.3.2):
| 参数 | 可选值 | 含义 | 设置博弈 |
|---|---|---|---|
| pollPDU | 4, 8, 16, 32, 64, 128, 256, infinity(per 1M PDU) | 每发多少个PDU触发一次Poll | 小值→STATUS反馈快但开销大;大值→省信令但丢包检测慢 |
| pollByte | 1KB~256MB, infinity | 每发多少字节触发一次Poll | 与 pollPDU 联合生效,先到先触发 |
| t-PollRetransmit | 5ms~500ms, 无穷大 | Poll 超时等待时间 | 短→快速检测但可能误触发;长→容忍HARQ时延但ARQ反应慢 |
| maxRetxThreshold | 1, 2, 3, 4, 6, 8, 16, 32 | 最大重传次数 | 达到后触发 RLC 失败指示→RRC RLF |
实战博弈分析:
再分段是 RLC AM ARQ 中最精巧的设计之一。当原始 AMD PDU 的大小超过了当前 MAC 调度授权(Grant)时,发送端需要将重传的 PDU 再切割成更小的段。
TS 38.322 Section 6.2.2.5 定义了 SI(Segmentation Info)字段:
| SI 值 | 含义 |
|---|---|
| 00 | 完整 RLC SDU(未分段) |
| 01 | RLC SDU 的第一段 |
| 10 | RLC SDU 的最后一段 |
| 11 | RLC SDU 的中间段 |
flowchart LR
subgraph Original["原始 AMD PDU (SN=20, 1200字节)"]
A1["RLC Header<br/>SN=20, SI=00"]
A2["RLC Payload<br/>1200 bytes"]
end
subgraph Reseg["再分段后 (当前Grant仅500字节)"]
B1["AMD PDU Segment 1<br/>SN=20, SI=01<br/>SO=0, LSF=0"]
B2["AMD PDU Segment 2<br/>SN=20, SI=10<br/>SO=500, LSF=1"]
end
A1 -.->|首次发送失败| B1
A2 -.-> B2
再分段头格式(TS 38.322 Section 6.2.2.4):
| 字段 | 长度 | 含义 |
|---|---|---|
| SN | 12/18 bits | 原始 PDU 的 SN(不变) |
| SI | 2 bits | 分段位置信息 |
| SO | 16 bits | 本段在原始 SDU 中的字节偏移 |
| LSF | 1 bit | Last Segment Flag,1=最后一段 |
| P | 1 bit | Poll 标志 |
MAC 层的调度授权(Grant)是动态变化的。首次发送时可能分配了 1200 字节的 TBS,但重传时信道恶化,MAC 调度器只给 500 字节。如果不支持再分段,发送端必须等待更大的 Grant 才能重传,这会引入不可预测的额外时延。
再分段的价值:用当前可用的任何 Grant 尺寸"切一块"发出去,积少成多完成重传。这对于 VoNR 和 URLLC 等时延敏感场景至关重要。
RLC AM 的三个定时器形成了一个精妙的联动系统。任何一个配置不当,都会导致 ARQ 效率急剧下降甚至失效。
graph TB
subgraph TX["发送端"]
TPOLL["t-PollRetransmit<br/>触发Poll重发"]
end
subgraph RX["接收端"]
TREA["t-Reassembly<br/>检测丢包缺口"]
TSTATUS["t-StatusProhibit<br/>抑制STATUS发送频率"]
end
TX -->|"AMD PDU with P=1"| RX
RX -->|"STATUS PDU (NACK)"| TX
RX -->|"检测到SN缺口"| TREA
TREA -->|"超时:确认丢包"| TSTATUS
TSTATUS -->|"超时/未运行<br/>允许发送STATUS"| TX
TX -->|"未收到STATUS<br/>超时重发Poll"| TPOLL
TPOLL -->|"重发带P=1的PDU"| RX
style TREA fill:#ff6b6b,color:#fff
style TPOLL fill:#4ecdc4,color:#fff
style TSTATUS fill:#ffe66d,color:#333
定义(TS 38.322 Section 5.3.7):
关键博弈:t-Reassembly 值的设置直接影响丢包检测的灵敏度。
| 配置 | 风险 | 适用场景 |
|---|---|---|
| 过短(如 10ms) | HARQ 尚未完成全部重传就触发 RLC ARQ NACK,造成重复重传浪费资源 | 不推荐 |
| 过长(如 200ms) | 真正丢包检测延迟大,上层应用感知时延增加 | 非实时业务 |
| 适中(如 35~80ms) | 平衡 HARQ 完成时间和 ARQ 响应速度 | 通用场景 |
定义(TS 38.322 Section 5.3.5):
STATUS_report_needed = true),立即发送博弈分析:
t-StatusProhibit 和 t-Reassembly 的配合至关重要。如果 t-StatusProhibit > t-Reassembly,可能导致接收端检测到丢包但无法立即报告,必须等到 t-StatusProhibit 超时。这引入了额外时延。
典型配置关系:
t-StatusProhibit < t-PollRetransmit ← 推荐
如果反过来(t-StatusProhibit > t-PollRetransmit),发送端 Poll 超时后重发 Poll,但接收端仍然被 t-StatusProhibit 抑制无法回复,造成 Poll 循环浪费。
定义(TS 38.322 Section 5.3.4):
博弈:t-PollRetransmit 需要大于 HARQ 的最大处理时间(包括可能的 HARQ 重传),否则会在 HARQ 尚未完成时就触发无谓的 Poll。
t-PollRetransmit ≥ kRTT + maxHARQTx × HARQ_RTT
其中 kRTT 是一个安全系数(通常 1.5~2)。
sequenceDiagram
participant TX as TX AM RLC
participant RX as RX AM RLC
rect rgb(230, 245, 255)
Note over TX: t-PollRetransmit 域
TX->>RX: AMD PDU (SN=5, P=1)
Note right of TX: 启动 t-PollRetransmit=80ms
Note over RX: 缺口: SN=3 未收到
rect rgb(255, 230, 230)
Note over RX: t-Reassembly 域
Note right of RX: 启动 t-Reassembly=50ms
end
rect rgb(255, 255, 220)
Note over RX: t-StatusProhibit 域
Note right of RX: t-StatusProhibit=20ms<br/>未运行,可发送STATUS
end
RX-->>TX: STATUS PDU (ACK_SN=3, NACK_SN=3)
Note over TX: 停止 t-PollRetransmit
Note right of RX: 启动 t-StatusProhibit=20ms
end
Note over TX: 重传 SN=3
TX->>RX: AMD PDU (SN=3, 重传)
Note over RX: 收到SN=3, VR(R)前推
Note right of RX: 停止 t-Reassembly
Note over RX: t-StatusProhibit超时(20ms后)
RX-->>TX: STATUS PDU (ACK_SN=6)
Note over TX: VT(A) 滑动到 6
当 AMD PDU(或其分段)的重传次数达到 maxRetxThreshold 时,TS 38.322 Section 5.3.5 规定:
if RETX_COUNT >= maxRetxThreshold:
指示上层(RRC):RLC 不可恢复失败
TS 38.331 Section 5.3.10 将此作为 RLF 触发条件之一:
T310 timer trigger: "Indication from RLC that the maximum number of retransmissions has been reached for SRB1 or SRB2"
关键细节:
| 场景 | 推荐值 | 理由 |
|---|---|---|
| VoNR (DRB) | 4~8 | 语音容忍度有限,快速 RLF 重建比持续重传更好 |
| 视频流 (DRB) | 8~16 | 允许更多重传尝试,视频有一定缓冲 |
| URLLC (DRB) | 4 | 快速失败,触发冗余路径切换 |
| SRB1/SRB2 | 8 | 信令可靠性优先,但也不能无限重传 |
使用 Wireshark(需支持 NR RLC dissectors)或厂商专有工具(如 Ericsson ENM/LM、华为 U2020):
| 过滤条件 | 识别目标 |
|---|---|
| RLC AM D/C=1, CPT=0 | STATUS PDU |
| RLC AM P=1 | 带 Poll 的 AMD PDU |
| RLC AM SI≠00 | 分段/再分段 PDU |
| RLC AM SO 字段存在 | 再分段偏移量 |
故障 1:STATUS PDU 风暴
- 现象:t-StatusProhibit 配置为 0ms 或过小,接收端频繁发送 STATUS PDU
- 影响:上行资源被 STATUS PDU 占满,有效数据吞吐量下降
- 排查:检查 RRCReconfiguration 中 t-StatusProhibit 配置值
故障 2:Poll 超时循环 - 现象:t-PollRetransmit < HARQ 总处理时间,导致 Poll 重复超时 - 影响:下行不必要的 Poll PDU 浪费 Grant,甚至挤占业务数据 - 排查:对比 t-PollRetransmit 值与 HARQ maxTx × HARQ_RTT
故障 3:窗口停滞(Window Stall) - 现象:VT(S) 达到 VT(MS),无法发送新数据 - 根因:接收端 STATUS PDU 丢失或 t-StatusProhibit 过长导致 VT(A) 不前推 - 排查:检查 STATUS PDU 是否被 MAC 层丢弃(优先级低),或 t-StatusProhibit 是否大于 t-PollRetransmit
故障 4:RLC RLF 误触发 - 现象:UE 在覆盖尚可的区域频繁 RRC 重建 - 根因:maxRetxThreshold 过小,或 HARQ 配置与 RLC 定时器不协调 - 排查:查看 RLC 层日志中的 RETX_COUNT 计数趋势,配合 RSRP/SINR 判断是否真的信道恶化
| 特性 | LTE RLC AM (TS 36.322) | NR RLC AM (TS 38.322) |
|---|---|---|
| 级联(Concatenation) | RLC 层支持 | 移除,由 MAC 层处理 |
| SN 长度 | 5/10 bit | 12/18 bit |
| 再分段 | 不支持 | 支持(关键增强) |
| STATUS PDU NACK Range | 不支持 | R18新增 E3 标志 |
| RLC SDU 丢弃 | 不支持 | 支持(PDCP 触发) |
| 窗口大小 | 固定 | 更灵活(18-bit SN) |
再分段是 NR 相对 LTE 最显著的增强。LTE RLC AM 不支持再分段,意味着重传时必须用与首次发送相同大小的 PDU。如果 MAC Grant 不足,就只能等待,这在高速移动和信道快速变化场景下成为瓶颈。
Q: RLC ARQ 和 HARQ 的重传计数是独立的吗? A: 是的,完全独立。HARQ 在 L1 有自己的最大重传次数(max HARQ transmissions,由 RRC 配置,通常 4~8 次)。RLC ARQ 的 RETX_COUNT 只在 RLC 层维护。HARQ 耗尽最大次数后 MAC 丢弃 TB,RLC ARQ 才"看到"缺口并触发 NACK 重传。两者是串联关系,不是替代关系。
Q: t-StatusProhibit 设为 0 会有什么后果? A: t-StatusProhibit=0 意味着接收端可以无限制地发送 STATUS PDU。在高速运动、信道频繁波动的场景下,每收到一个带缺口的 PDU 就触发一次 STATUS PDU,可能导致上行 STATUS PDU 泛滥,挤占上行数据资源。但在极低速率、极简场景下(如 NB-IoT),设为 0 可以最小化反馈时延。
Q: 再分段时 SN 是否会改变? A: 不会。再分段后的所有段都保持原始 PDU 的 SN。接收端通过 SO(Segment Offset)和 LSF(Last Segment Flag)来区分和重组同一 SN 的不同段。这是设计上的精妙之处——SN 空间不会被重传消耗。
Q: 为什么 NR 要把 RLC 级联功能移到 MAC 层? A: NR 引入了灵活的 numerology 和 mini-slot,MAC 层需要精确控制 TB 大小来匹配动态调度。将级联放在 MAC 层可以让调度器对 TB 内部的 RLC PDU 组合有完全控制权,实现更高效的资源利用。RLC 层专注分段和 ARQ,职责更清晰。
Q: 如何判断一个 RLF 是 RLC 层导致的还是物理层导致的?
A: 查看日志中的 RLF 触发原因。如果是 rlc-MaxNumRetx 触发,说明是 RLC ARQ 达到 maxRetxThreshold;如果是 T310 expiry(物理层问题检测定时器),说明是物理层连续失步。两者都可能导致最终 RRC 重建,但根因不同,优化方向也不同——RLC RLF 优化定时器配置和 HARQ/ARQ 协调,物理层 RLF 优化覆盖和功率控制。
本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵爱卫生(微信ID: gprshome201101)维护,聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。
[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
