第4章:动态地址分配(DAA)流程——初始化、地址声明、冲突检测

动态地址分配(DAA),说白了就是I3C总线上给每个设备发“身份证”的过程。你想想看,总线上挂了一堆设备,要是没个唯一的地址,数据该往哪儿送?DAA就是解决这个问题的核心机制。

我个人习惯把这套流程分成三段:初始化、地址声明、冲突检测。今天咱们就一段一段地拆开来看,同时我会把CRC校验的计算点穿插进去——毕竟这门课的核心就是CRC实战。

核心要点:DAA流程中,CRC不只是用来校验数据的完整性,它还是地址声明阶段冲突检测的关键依据。简单说,CRC如果对不上,那你声明的地址就可能是“冒牌货”。

4.1 初始化阶段:开场的广播

初始化阶段由I3C的主机(Controller)发起。我习惯叫它“开场的广播”——主机先发一条特殊的广播消息,告诉所有从机(Target):“准备开始分配地址了!”

这条广播消息的格式是这样的:

Broadcast Message: 7E + ENTDAA CCC (0x04) + CRC

这里有个细节:ENTDAA(Enter Dynamic Address Assignment),指令码固定为0x04。主机在发送这条广播时,会附加上一个1字节的CRC,用来确保这条指令没有被总线噪声篡改。CRC的计算方式,我后面会专门讲——这里先记着,ENTDAA广播里的CRC覆盖的是ENTDAA指令本身。

避坑提示:我曾经在项目中遇到过,某些早期的I3C设备对广播CRC不敏感,即使CRC错了也能响应。但这是违反规范的,千万别这么干。否则到了地址声明阶段,冲突检测就会失灵。

初始化阶段的核心工作就这些:主机发ENTDAA + CRC,所有从机收到后,确认CRC正确,就准备进入下一轮——地址声明。

4.2 地址声明阶段:设备轮流“报号”

地址声明阶段,才是整个DAA流程的“重头戏”。这个过程,说白了就是一次网上的双向确认。

我给你们梳理一下步骤:

  1. 主机发送ENTDAA广播后,所有未分配地址的设备都开始等待自己的“报号”机会。
  2. 主机接下来会发送一个“子地址”(Sublink Address),这其实是一个固定的轮询序列(比如0x00、0x01……直到0x7F)。
  3. 如果某个从未分配设备的子地址和当前轮询到的号匹配,它就开始进行地址声明。
  4. 这个设备会发送一个48位的地址声明数据帧,这个帧里包含它想申请的动态地址和CRC校验和。

下面是一张典型的地址声明帧结构表:

字段长度描述CRC参与?
设备唯一ID (UID)48 bits设备的硬件唯一标识符否
建议动态地址 (Suggested Address)7 bits设备希望分配的地址 (0x01~0x7F)是
CRC1616 bits对“建议动态地址”字段的CRC校验—

设备发送这个帧后,主机会立即计算这个CRC,确认设备声明的地址没有在传输中被破坏。

CRC计算点:这个CRC只对建议动态地址(7位)进行计算,而不是整个帧。我个人习惯在代码里写成这样:CRC16(address_byte, 7),对,只处理前7个有效位。

4.3 冲突检测:谁在撒谎?

冲突检测阶段,是DAA流程里最刺激的部分。你想想看,如果总线上一堆设备同时说“我要这个地址”,该怎么办?

设备在发送完地址声明帧后,主机并不会立刻确认。主机会先重新计算一遍CRC,然后和从机发来的CRC进行比较。如果两个CRC不相等——恭喜,冲突发现了。

重要警告:CRC比较失败,不能简单地认为是“设备在撒谎”。实际项目中,CRC冲突表明总线上的信号被破坏,或者有两个设备同时声称同一个地址。我曾经中过招——两个同型号传感器在初始化时都选了默认地址0x08,CRC当然对不上。

当冲突被检测到后,流程会怎样?

  • 主机侧:停止当前地址分配,记录冲突事件。然后重新发送ENTDAA广播,开始下一轮分配。
  • 设备侧:所有冲突的设备会收到一个终止信号(有时是NACK)。它们必须进入等待状态,等待下一次的ENTDAA广播。

这里有一个关键机制:为了避免无限次冲突,每个设备在冲突后都会随机推迟一段时间(通常是几微秒到几毫秒),再重新参与地址声明。这个随机退避时间,在I3C规范里叫“Backoff Time”。

工程建议:在实现代码时,我建议在设备的Backoff Time计算里增加一个CRC随机数种子。比如用当前设备UID的低8位作为种子,这样能有效降低不同设备选择同一个Backoff Time的概率。

4.4 整个流程的“骨架”视图

把这些串联起来,DAA流程可以画成一张流程图。下面这张SVG图,我把它叫做“DAA核心骨架”,你照着看一遍,大概5分钟就能掌握整体逻辑。

动态地址分配(DAA)核心流程图 DAA流程骨架(含CRC校验点) ① 初始化:主机发ENTDAA广播 + CRC CRC覆盖ENTDAA指令(7E + 04 + CRC) ② 地址声明:设备发建议地址 + CRC 设备发送:UID(48位)+ 建议地址(7位)+ CRC16 CRC仅覆盖“建议地址”字段(7位) ③ 冲突检测:主机校验CRC是否一致 主机重新计算CRC,与设备发来的CRC比较 一致 → 接受地址;不一致 → 冲突发生 CRC一致? 是 接受地址 分配成功 否 冲突检测 需重新分配 ⚡ 核心 CRC 逻辑 设备声明地址时发送CRC → 主机校验 → 判定冲突 → 决定分配或重试

总结一下:从初始化到地址声明再到冲突检测,整个DAA流程就是靠着CRC这个“裁判”来确保每个地址的唯一性。你想想看,如果没有CRC,总线上的设备就只能靠猜,那效率得多低?所以,掌握CRC的计算方式,就等于抓住了DAA流程的命脉。

好了,这一章的核心逻辑就这些。接下来,我们会在下面的章节里专门动手算CRC——到时候你看到代码,就能彻底理解今天讲的每一个环节。