文章目录
- [8.15.0 带 Bank 的 Page 9Fh(CDB 消息)概述](#8.15.0 带 Bank 的 Page 9Fh(CDB 消息)概述)
-
- (1)CDB的作用
- (2)CDB实例
- [(3)CDB 实例与 Bank 的关系](#(3)CDB 实例与 Bank 的关系)
- (4)为什么需要多个实例?
- [(5) CDB消息的组成](#(5) CDB消息的组成)
- 总结
摘要:此专栏主要介绍光模块通用管理接口规范(Common Management Interface Specification, CMIS)协议规范 V5.0 的解读。本文主要关注协议文档的 8.15 节关于 Page 9F 的内容。不仅是对文档的简单翻译,还会剖析协议规定背后的深层含义。为了方便与协议文档内容对应,本文的章节编号与协议文档保持一致。
8.15.0 带 Bank 的 Page 9Fh(CDB 消息)概述
(1)CDB的作用
CDB(Command Data Block,命令数据块)是 CMIS 定义的一种高级命令机制。普通的寄存器读写只能做一些简单控制(比如开关激光器、读温度),但像固件升级、安全认证、复杂诊断这类任务,往往需要:
- 传输大量数据(如固件文件)
- 执行时间较长(可能持续数秒甚至更久)
- 有明确的执行状态和返回结果
CDB 就是为这类复杂任务设计的"重型命令通道"。主机把命令和参数写入一块约定的缓冲区,然后触发模块执行,模块处理完后把结果放回缓冲区,并给出完成标志。
(2)CDB实例
一个 CDB 实例 就是一套独立的、完整的命令/应答消息交换设施。可以类比为银行柜台、计算机进程等。在光模块中,每个CDB实例都有自己的:
- 命令缓冲区(主机写命令和参数的地方)
- 应答缓冲区(模块写结果的地方)
- 状态寄存器(反映该实例当前是忙、完成还是失败)
- 命令完成标志
(3)CDB 实例与 Bank 的关系
在 CMIS 内存映射中,CDB 实例是通过 Bank 来实现的。一个 Bank 就实现一个 CDB 实例 。模块通过 CdbInstancesSupported 字段告诉主机它支持多少个实例(即多少个 Bank 用于 CDB)。这个字段为 0 表示完全不支持 CDB。
- Page 9Fh 是 CDB 主页面,存放控制、状态、命令触发等寄存器。
- Page A0h--AFh 等页面存放命令和应答数据。
- 每个 Bank 都包含一套完整的 Page 9Fh 和 A0h--AFh 子集。
(4)为什么需要多个实例?
最主要的原因是并发处理长命令。
- 如果没有多个实例,当模块正在执行一个耗时的 CDB 命令(比如擦写 Flash 固件)时,整个 CDB 通道就被占用了。此时主机如果想再发一个查询命令(比如读取模块内部日志),就无从下手,只能干等。
- 当然,前提是模块支持后台模式消息处理。如果模块只支持前台模式,那么即使有多个实例,一次也只能有一个实例在处理命令,其他实例只能排队。
(5) CDB消息的组成
CDB消息主要由三部分组成,其各自所在的字节位置如 表8-129 所示。我们可以用"寄信"来做类比。

- Command Message Header 命令信息头
CDB 命令消息头字节(9Fh:128-133)的内容如表 8-130 所示,由主机填写,模块收到不会修改其中内容。命令消息头的内容包含:- 要办什么事(CMDID:CDB 命令码)
- 随附材料有多少页(LPLLength:本地负载长度)
- 补充材料有多少页(EPLLength:扩展负载长度)
- 整张单子的防伪码(CdbChkCode:校验和)

- Reply Message Header 应答信息头
应答头由模块填写,模块只写不看。它和命令头共用 Page 9Fh,只是地址不同(命令头在 128--133,应答头在 134--135),用来告诉主机:- 命令执行结果如何(成功还是失败)
- 返回了多少字节的数据
- 数据放在哪里(本地负载还是扩展负载)

主机的"验证小技巧"
注释给了一个很有用的调试方法:主机可以在发命令时,故意把应答头填成特殊值。这样可以验证模块是否真的回填了应答头。
比如,主机在写命令消息时,把 9Fh:134--135 都写成 0xFF。如果模块正常工作,它应该在回复时把这两个字节改成有效值(比如状态码和返回长度)。如果主机后来读应答时发现还是 0xFF,那就说明模块执行命令有问题。
- Local Payload(LPL)本地负载
- 地址范围:本地负载(LPL)与命令头都在 Page 9Fh 里,范围为 Byte 136-255,适用于消息体不超过120字节的情况。
- 双向复用的特性 :主机发命令时,把命令参数塞进这个口袋。模块执行完命令后,如果有返回数据,它会把返回数据直接覆盖原来口袋里的命令参数。也就是说:应答 LPL 可能会覆盖命令 LPL。
- 如果消息体的数据大于120字节,则可以把消息体放到扩展负载(EPL)里。

- 消息交换协议
主机要发送一条 CDB 命令,必须按如下顺序写入:

- 为什么要最后写 CMDID? :因为写 CMDID 的动作本身就是"扣扳机"。模块监测到主机写到 CMDID 的最低字节时,就知道"完整命令已就绪,开始干活了"。
- 模块怎么汇报"我在忙"和"我干完了"?
模块在执行 CDB 命令期间,会通过两个地方向主机同步状态:- CdbStatus(位于低地址内存 00h:37 或 00h:38):相当于"进度条"。主机可以读它,判断命令是正在跑、成功还是失败。
- CDB CMD 完成标志(00h:8.6 或 00h:8.7):相当于"门铃"。命令一结束,模块就按下这个门铃,主机可以响应中断,知道该去读结果了。
- 校验和的计算范围
- EPLLength 和 LPLLength 总是包含在 CdbChkCode 里。
- RPLLength 和 RPLChkCode 从不包含在 CdbChkCode 里。
- 触发 CDB 命令执行
触发命令执行有两种方式,通过能力位01h:165.7告诉主机,我监听哪种写操作来启动命令。主机必须遵循,否则命令不会被触发。

总结
本文解读了 CMIS 协议中带 Bank 的 Page 9Fh(CDB 消息)机制:CDB 为固件升级、安全认证等复杂任务提供了重型命令通道,通过 Bank 实现多实例并发处理长命令,并详细剖析了命令头、应答头、本地负载及消息交换协议等核心组成。