第4章 软件协议栈架构:L1/L2/L3分层、MAC调度器、RLC分段与ARQ、PDCP加密与完整性保护

各位同学,今天我们来聊聊5G调制解调器里最核心的软件部分——协议栈。说实话,很多刚入行的工程师觉得协议栈就是一堆标准文档,照着实现就行了。但我在项目中踩过的坑告诉我,事情远没那么简单。

协议栈的分层,说白了就是把复杂问题拆成小块。L1管物理层,L2管数据链路,L3管网络层。每一层各司其职,但又紧密配合。我个人习惯把协议栈想象成一个工厂流水线——数据从上层下来,经过每道工序加工,最后变成无线信号发出去。

4.1 L1/L2/L3分层架构

先说说分层。5G NR的协议栈分三层:

  • L1(物理层):负责编码、调制、MIMO、OFDM这些硬核活儿。我见过不少团队把L1全部扔给硬件加速器,结果调度灵活性大打折扣。
  • L2(数据链路层):包含MAC、RLC、PDCP三个子层。这是软硬件协同设计的重灾区。
  • L3(网络层):主要是RRC(无线资源控制)和NAS(非接入层)。处理信令和移动性管理。

为什么会这样分层?你想想看,如果所有功能都揉在一起,调试起来得多痛苦。我在一个项目中就遇到过,因为L2和L3的接口定义不清晰,导致每次版本迭代都要改一大片代码。后来我们强制规定了层间接口的数据结构,才把问题控制住。

关键点:分层不是目的,目的是降低复杂度。但分层也带来了性能开销——每层之间的数据拷贝、上下文切换,都是成本。

这里我画了一张协议栈的架构图,帮你直观理解各层的关系:

L3 - 网络层 RRC(无线资源控制) | NAS(非接入层) 信令处理、移动性管理、连接控制 L2 - 数据链路层 PDCP:加密、完整性保护、头压缩 RLC:分段/重组、ARQ重传 MAC:调度、HARQ、随机接入 L1 - 物理层 编码/解码、调制/解调、MIMO、OFDM 数据流向

4.2 MAC调度器

MAC调度器是整个协议栈的「大脑」。它决定什么时候给哪个UE分配多少资源。嗯,这里要注意,调度器是实时性要求最高的模块之一——每个TTI(传输时间间隔)都要做一次调度决策。

我曾经在一个项目中,调度器的实现用了纯软件,结果在用户数一多的时候,CPU占用率直接飙到80%。后来我们把调度算法中的优先级计算部分用硬件加速器实现,才把CPU占用降下来。

调度器的核心逻辑其实不复杂:

// 简化版调度器伪代码
for each TTI:
    for each UE:
        // 1. 计算优先级
        priority = f(CQI, buffer_status, QoS, history)
        // 2. 按优先级排序
        sort(UE_list, priority)
        // 3. 分配资源
        for UE in sorted_UE_list:
            if remaining_resources > 0:
                allocate(UE, min(UE_demand, remaining_resources))
                remaining_resources -= allocated

我的经验:调度器的实现要特别注意「公平性」和「效率」的平衡。一味追求吞吐量,会导致边缘用户永远抢不到资源。我建议在优先级公式中加入「历史吞吐量」因子,保证每个用户都有机会。

4.3 RLC分段与ARQ

RLC层负责两件事:分段和ARQ。为什么需要分段?因为MAC层能传输的数据块大小是有限的。上层下来的一个大包,可能得切成好几块才能发出去。

ARQ(自动重传请求)是RLC层的可靠性保障。如果接收端发现某个分段丢了,就通知发送端重传。这里有个坑——ARQ和HARQ(物理层的混合自动重传)是两回事。HARQ在L1层,速度快但重传次数有限;ARQ在RLC层,速度慢但更可靠。

我记得有一次,一个同事把ARQ的超时时间设得太短,结果网络稍微有点抖动,就触发大量重传,导致吞吐量骤降。后来我们把超时时间从10ms调整到50ms,问题就解决了。

避坑指南:我曾经在RLC分段时没处理好「对齐」问题——分段后的数据块大小必须和MAC层的传输块大小匹配。否则要么浪费资源,要么数据发不出去。建议在实现时加一个「对齐检查」的断言。

4.4 PDCP加密与完整性保护

PDCP层负责三件事:加密、完整性保护、头压缩。加密用的是AES或Snow 3G算法,完整性保护用的是SHA系列。这些算法在软件里跑起来很慢,所以一般会用硬件加速器。

头压缩(ROHC)是个有意思的功能。IP头有40字节,但很多字段在同一个流里是不变的。压缩后可能只剩几个字节。我在一个项目中做过测试,开启ROHC后,VoIP业务的吞吐量提升了30%。

PDCP层的处理流程大致如下:

步骤 操作 说明
1 头压缩 对IP/UDP/RTP头进行压缩,减少开销
2 加密 使用COUNT、BEARER、DIRECTION生成密钥流
3 完整性保护 计算MAC-I,附加在PDCP PDU尾部
4 添加PDCP头 包含序列号、数据/控制指示等

这里有个细节——加密和完整性保护的顺序不能搞反。先加密再完整性保护,还是先完整性保护再加密?3GPP标准规定的是先加密再完整性保护。为什么?因为如果先做完整性保护,攻击者可以通过修改密文来破坏完整性校验,导致合法数据被丢弃。

核心要点:PDCP层的密钥管理是个大话题。每个UE、每个承载都有独立的密钥。密钥更新时,要保证新旧密钥的切换不丢包。我建议在实现时用「双缓冲」机制——旧密钥继续处理未完成的数据,新密钥处理新数据。

好了,关于协议栈的分层和各个子层的功能,我就讲到这里。这些内容看起来是标准化的,但实际实现时,每个细节都可能影响性能和可靠性。希望你们在动手写代码之前,先把这些概念理清楚。


公众号:蓝海资料掘金营,微信deep3321