3. 2T光模块寄存器映射与数据模型设计
3.2T光模块的管理接口通常沿用并扩展了QSFP-DD/OSFP的CMIS(Common Management Interface Specification)框架。理解寄存器映射,本质上是在理解“管理主机如何用最少的字节访问到模块内部最关键的物理量”。本节围绕标准寄存器页A0h/A2h与厂商自定义页的划分、关键寄存器的地址与位域定义,以及如何把设计结果落地为一张映射表和一份C头文件展开。
一、标准页与厂商自定义页的职责划分
在CMIS体系中,A0h页承载模块的静态身份与能力信息,包括标识符、厂商名称、序列号、支持的速率与介质类型、页映射能力等;A2h页则承载动态监控量,如温度、电压、光功率、偏置电流以及各类告警与告警阈值。对于3.2T这种高密度模块,A2h页的低128字节通常用于实时监控(Lower Memory),高128字节用于阈值与告警标志(Upper Memory),这是主机侧轮询最频繁的区域。
厂商自定义页(Custom Page)用于放置标准未覆盖的内容,例如3.2T特有的多通道光功率细分、DSP状态、FEC统计、固件版本扩展信息等。设计时必须明确:哪些数据放标准页以保证通用工具可读,哪些放自定义页以避免与标准地址冲突。一个常见原则是——凡是CMIS已定义且主机可能依赖的监控量,一律放A2h标准地址;凡是厂商私有诊断或调试量,放自定义页,并在A0h的页映射描述中声明自定义页号。
二、关键寄存器的地址与位域定义
以温度为例,A2h页0x00~0x01为温度值,采用16位有符号定点数,单位1/256℃。若读回原始值0x1A80,则温度 = 0x1A80 / 256 = 26.5℃。电压位于0x02~0x03,单位100μV,读回0x1D4C即0x1D4C×100μV = 7.5V。光功率通常位于0x06~0x07,单位0.1μW,需结合校准系数换算为dBm。告警阈值则分布在A2h高128字节,例如温度高告警阈值在0x10~0x11,与实时值同格式,便于直接比较。
位域设计上,告警标志寄存器(如0x08)每一位对应一种告警类型:bit0温度高、bit1温度低、bit2电压高、bit3电压低、bit4光功率高、bit5光功率低等。主机读取后按位与掩码判断,避免逐字节解析。设计映射表时,必须把“地址、长度、数据类型、单位、缩放因子、读写属性、告警位”这些字段固定下来,作为软硬件协同的唯一依据。
三、寄存器映射表设计
下表给出一个面向3.2T模块的简化映射表示例(参数为教学示例,非实测值):
| 页 | 地址 | 名称 | 长度 | 类型 | 单位/缩放 | 属性 | 告警位 |
|---|---|---|---|---|---|---|---|
| A2h | 0x00 | 温度 | 2 | int16 | 1/256 ℃ | RO | 0x08 bit0/1 |
| A2h | 0x02 | 电压 | 2 | uint16 | 100 μV | RO | 0x08 bit2/3 |
| A2h | 0x04 | 偏置电流 | 2 | uint16 | 2 μA | RO | 0x08 bit6/7 |
| A2h | 0x06 | 光功率 | 2 | uint16 | 0.1 μW | RO | 0x08 bit4/5 |
| A2h | 0x08 | 告警标志 | 1 | bitfield | — | RO | — |
| A2h | 0x10 | 温度高阈值 | 2 | int16 | 1/256 ℃ | RW | — |
| A2h | 0x12 | 温度低阈值 | 2 | int16 | 1/256 ℃ | RW | — |
| A2h | 0x14 | 电压高阈值 | 2 | uint16 | 100 μV | RW | — |
| A0h | 0x00 | 标识符 | 1 | uint8 | — | RO | — |
| A0h | 0x9F | 页映射 | 1 | bitfield | — | RO | — |
| 自定义 | 0x80:0x00 | DSP状态 | 4 | uint32 | — | RO | — |
四、生成C头文件
映射表确定后,直接将其转化为C头文件,供固件与上位机共用。关键是用宏定义地址、用位域或掩码定义告警位,并给出缩放换算宏,避免魔法数字散落各处。
#ifndef CMIS_3P2T_REGMAP_H
#define CMIS_3P2T_REGMAP_H
/* 页选择 */
#define PAGE_A0H 0x00
#define PAGE_A2H 0x00
#define PAGE_CUSTOM_BASE 0x80
/* A2h 实时监控量 */
#define REG_TEMP_ADDR 0x00
#define REG_VOLT_ADDR 0x02
#define REG_BIAS_ADDR 0x04
#define REG_OPWR_ADDR 0x06
#define REG_ALARM_ADDR 0x08
/* 告警位域 */
#define ALARM_TEMP_HIGH (1u << 0)
#define ALARM_TEMP_LOW (1u << 1)
#define ALARM_VOLT_HIGH (1u << 2)
#define ALARM_VOLT_LOW (1u << 3)
#define ALARM_OPWR_HIGH (1u << 4)
#define ALARM_OPWR_LOW (1u << 5)
/* 阈值寄存器 */
#define REG_TEMP_HIGH_TH 0x10
#define REG_TEMP_LOW_TH 0x12
#define REG_VOLT_HIGH_TH 0x14
/* 缩放换算 */
#define TEMP_LSB_C 0.00390625f /* 1/256 ℃ */
#define VOLT_LSB_V 0.0001f /* 100 μV */
#define OPWR_LSB_UW 0.1f /* 0.1 μW */
/* 自定义页 */
#define CUSTOM_PAGE_DSP 0x80
#define REG_DSP_STATUS 0x00
#endif /* CMIS_3P2T_REGMAP_H */
完成上述设计后,主机侧读取温度的典型流程是:选择A2h页→读0x00两字节→按int16解析→乘以1/256得到摄氏度→读0x08判断告警位→与0x10阈值比较。整个过程只依赖头文件中的宏,寄存器地址或位定义调整时,仅需改映射表与头文件,上层业务代码无需改动,这正是数据模型设计带来的可维护性。