QSFPER1开发文档2

QSFP-ER1 模块测试流程新增开发文档

一、需求概述

现有软件支持普通QSFP初测/终测流程,现新增 QSFP-ER1 模块测试,分为4套工位流程:

  1. 发射初测工位:发射调节 + 写Flash + 保存初测数据库
  2. 发射终测工位:发射调节/验证 + 写Flash + 保存终测数据库
  3. 接收初测工位:接收调节 + 写Flash + 保存初测数据库
  4. 接收终测工位:接收调节/验证 + 写Flash + 保存终测数据库

方案思路:不新增临时按钮,引入测试工位概念区分发射/接收;复用原有软件框架、仪器接口、数据库存储逻辑,独立实现ER1测试流程,原有QSFP业务逻辑不受改动。

二、整体开发步骤

第一步:增加测试工位枚举与全局变量

  1. Common.cs 添加工位枚举
csharp 复制代码
public enum ER1TestStation
{
    Tx,  // 发射工位
    Rx   // 接收工位
}
  1. GlobalVarFun 添加全局静态变量
csharp 复制代码
public static ER1TestStation er1Station = ER1TestStation.Tx;
  1. 工位切换方案
  • 方案A(正式):登录界面增加选项【发射工位 / 接收工位】,选择后赋值 GlobalVarFun.er1Station
  • 方案B(临时调试):代码直接硬编码设置
csharp 复制代码
GlobalVarFun.er1Station = ER1TestStation.Tx;

第二步:修改自动测试流程入口调度逻辑

原有调度代码

csharp 复制代码
if (GlobalVarFun.testType == "firstTest")
{
    FirstTestProcess();
}
else
{
    FinalTestProcess();
}

修改后调度代码

csharp 复制代码
if (GlobalVarFun.moduleType == "QSFPER1")
{
    if (GlobalVarFun.er1Station == ER1TestStation.Tx)
    {
        RunER1TxProcess();
    }
    else
    {
        RunER1RxProcess();
    }
}
else
{
    // 原有普通QSFP逻辑保持不变
    if (GlobalVarFun.testType == "firstTest")
        FirstTestProcess();
    else
        FinalTestProcess();
}

说明:RunER1TxProcess() / RunER1RxProcess() 内部依靠 GlobalVarFun.testType 区分初测firstTest / 终测finalTest

第三步:实现ER1发射测试流程 RunER1TxProcess

csharp 复制代码
private bool RunER1TxProcess()
{
    if (!test.SetDebugPWD())
        return false;

    test.SoftTxDis(true);
    Thread.Sleep(100);
    test.SoftTxDis(false);

    for (int ch = 0; ch < 4; ch++)
    {
        TestSet.ch = ch;
        if (!test.SetTxApcBias(160))
            return false;

        // 业务预留点
        // 1. 调用现有眼图仪接口
        // 2. 读取 IDECQ、Outer ER、光功率
        // 3. 根据项目需求迭代调节APC

        TestResult.txPowerbuf[ch] = TestResult.txPower;
        TestResult.txErbuf[ch] = TestResult.txEr;

        progressBar1.Value = 20 + ch * 15;
        Refresh();
    }

    // 发射初测、终测均需要校准写入Flash
    if (!test.SaveER1Calibration())
        return false;

    GlobalVarFun.record_need_save = true;
    return SaveER1TestRecord();
}

辅助方法(获取工序名称,日志打印使用)

csharp 复制代码
private string GetStageName()
{
    return GlobalVarFun.testType == "firstTest"
        ? "发射初测"
        : "发射终测";
}

提示:初测与终测流程逻辑一致,无需复制两份代码,仅通过日志区分工序。

第四步:实现ER1接收测试流程 RunER1RxProcess

csharp 复制代码
private bool RunER1RxProcess()
{
    if (!test.SetDebugPWD())
        return false;

    for (int ch = 0; ch < 4; ch++)
    {
        TestSet.ch = ch;
        UInt16 vagc = 140;
        bool pass = false;

        while (vagc <= 255)
        {
            if (!test.SetRxVagc(vagc))
                return false;
            Thread.Sleep(100);

            double ber = ReadBer(ch); // 复用现有误码仪接口
            if (ber < 1e-4)
            {
                pass = true;
                break;
            }
            vagc += 10;
        }

        if (!pass)
            return false;

        SetAttenuator(6);
        TestResult.rxPwrRealbuf[ch, 0] = ReadPower();
        TestResult.rxPwrDDMbuf[ch, 0] = test.GetRxPower();

        SetAttenuator(8);
        TestResult.rxPwrRealbuf[ch, 1] = ReadPower();
        TestResult.rxPwrDDMbuf[ch, 1] = test.GetRxPower();

        TestResult.rxSenbuf[ch] = (float)ber;

        progressBar1.Value = 20 + ch * 15;
        Refresh();
    }

    // 接收初测、终测均保存校准参数写入Flash
    if (!test.SaveER1Calibration())
        return false;

    GlobalVarFun.record_need_save = true;
    return SaveER1TestRecord();
}

重要约束:ReadBer()SetAttenuator()ReadPower() 必须复用原有QSFP项目已封装仪器接口,禁止重新编写仪器驱动代码

第五步:数据库存储逻辑(复用原有机制)

现阶段不新建数据库表、不新增追溯字段,沿用原有存储函数 SaveRecordToSQL()

原有逻辑自动区分数据表:

csharp 复制代码
if (GlobalVarFun.testType == "firstTest")
{
    strName = "QSFP_FirstTest_Record_Table";
}
else
{
    strName = "QSFP_FinalTest_Record_Table";
}
数据缓存赋值规范

ER1测试流程执行数据库保存前,务必正确填充缓存变量:

  • TestResult.txPowerbuf[ch]
  • TestResult.txErbuf[ch]
  • TestResult.rxPwrRealbuf[ch, index]
  • TestResult.rxPwrDDMbuf[ch, index]
  • TestResult.rxSenbuf[ch]

封装统一保存方法 SaveER1TestRecord()

csharp 复制代码
private bool SaveER1TestRecord()
{
    if (GlobalVarFun.sql_connect_status == false)
    {
        AddTestLog("SQL数据库未连接,测试记录未保存");
        return false;
    }

    if (backgroundWorkerAutoSet.IsBusy)
    {
        AddTestLog("数据库保存线程正在执行");
        return false;
    }

    backgroundWorkerAutoSet.RunWorkerAsync();
    return true;
}

设置标志位通知后台线程执行入库:

csharp 复制代码
GlobalVarFun.record_need_save = true;

第六步:数据库字段映射修正

现存BUG
csharp 复制代码
tx_erbuf[j] = TestResult.txPowerbuf[j]; // 错误:光功率写入TxER字段
修改为
csharp 复制代码
tx_erbuf[j] = TestResult.txErbuf[j];
字段映射对照表
数据库字段 数据源变量
TxPower TestResult.txPowerbuf
TxER TestResult.txErbuf
RxPower TestResult.rxPwrRealbuf / rxPwrDDMbuf
Sensitivity TestResult.rxSenbuf

开发时逐一对齐所有读写映射,防止字段错位。

三、推荐开发&测试顺序(风险最低)

禁止一次性完成4套流程,分步验证:

  1. 先实现【发射初测】
  2. 验证APC调节、眼图、光功率读取正常
  3. 验证 SaveER1Calibration() Flash写入正常
  4. 核对数据库TxPower、TxER入库数据准确
  5. 复用发射初测代码,支持【发射终测】
  6. 实现【接收初测】
  7. 验证BER、VAGC、6dB/8dB光功率采集正常
  8. 复用接收初测代码,支持【接收终测】
  9. 完整联调高温老化后的终测整条流程

四、重点研读源码清单(开发前优先熟悉)

  1. Login_Form.cs:模块类型、测试阶段初始化逻辑
  2. Main_Form.cs:定时器调度 timer1_Tick()
  3. FirstTestProcess()FinalTestProcess():原有标准流程
  4. SaveRecordToSQL():数据库入库完整逻辑
  5. 眼图数据读取封装函数
  6. BER、光功率、衰减器仪器封装函数

五、总体设计原则

最大限度复用现有软件基础设施:登录模块、定时器、模块插拔检测、进度条、数据库后台保存机制;仅替换ER1独有的发射/接收测试算法

优点:改动范围可控、回归测试量小、兼容现有产线作业流程。

六、开发注意事项

  1. 在未稳定验证IDECQ寄存器读取逻辑前,禁止放开TX自动校准、Flash批量写入;
  2. 调试阶段优先单独验证:COM端口识别、波特率、模块信息读取、BER单点读取;
  3. 所有仪器操作优先复用已有封装,不新增独立串口/仪器管理代码;
  4. 流程任意环节失败,立即return false,保证异常终止,避免非法写入Flash。
相关推荐
光通信学徒8 天前
光模块APSU_IEEE802.3dj D3p2
模块测试
嘉仕新能23 天前
8714 可编程电子负载在快充模块测试中的应用:CC/CV/CR/CP 四模式如何匹配
模块测试·嘉仕新能·新能源测试设备·电子负载·快充模块测试·8714·cccvcrcp
Jeremy_WW1 个月前
QSFP-DD MSA Hardware协议解读(二)
网络·模块测试·智能硬件
半导体守望者2 个月前
AE AZX射频调谐器射频负载匹配(调谐)原理PPT
学习·机器人·自动化·制造·模块测试
半导体守望者3 个月前
ADTEC AX-1000Ⅱ电源 RF电源等离子电源操作指南RF PLASMA GENERATOR
学习·机器人·自动化·制造·模块测试
半导体守望者3 个月前
MKS RPS AX7657-85 故障分析与可能解决方案
学习·机器人·自动化·制造·模块测试
凝小飞3 个月前
cucumber JAVA 一键部署指南
java·集成测试·模块测试
慧一居士3 个月前
冒烟自测用例怎么写?
功能测试·单元测试·测试用例·可用性测试·模块测试
A000—ic测试座(陈佳鑫)3 个月前
电信号转换光信号:光模块是如何保障光通信链路的传输质量与效率-光模块测试座
模块测试