dft eeprom 测试在手动关闭写保护后 执行i2c write 失败

在执行DFT测试项时,发现测试项存在PSR eeprom self test 和eeprom self test 失败

发现是i2c写入失败

手动关闭写保护尝试写入也失败

当前主板和扩展板上的eeprom是16bit位宽,其它几个板子的eeprom是8bit位宽

当前在执行dfteeprom测试时 出现了8bit位宽的板子dfteeprom能通过,但16bit位宽的板子测试失败,查看代码,能看到调用了frudata的write方法,但没看明白如何处理不同eeprom位宽不同的场景,想确认一下是否跟位宽不同有关

答案内容由AI生成,仅供参考:

结论

最可能的根本原因是 AddrWidth 配置错误(设为 1 而非 2),导致 I2C 写命令格式不符合 16bit 位宽 EEPROM 的协议要求。

其他因素如 StorageType 设置异常、写保护未解除、I2C 工具使用不当等,可能会加剧问题,但核心在于 CSR 中 地址宽度未正确配置

建议优先修正 AddrWidth=2 并重新测试,可解决大部分写入失败问题。同时配合正确的 I2C 工具命令和完整的写保护控制流程,确保测试全面覆盖。

点击此处查看详细分析解答

DFT EEPROM 测试写入失败问题分析

根据提供的日志、配置信息和代码上下文,对 DFT EEPROM 测试中 I2C 写入失败的问题进行系统性分析。

问题现象

  1. DFT 测试失败

    • PSR eeprom self testeeprom self test 均失败。
    • 日志显示写入操作返回 BMC_Error_Unknown
    • 实际读取返回值为 nil 或非预期数据。
  2. 手动写入失败

    • 使用 i2ctool64 手动执行 I2C 写操作也报错 i2c write err
    • 读操作可以成功(返回 0x00 数据),但写入失败。
  3. 硬件差异

    • 主板和扩展板使用 16bit 地址位宽的 EEPROM。
    • 其它板卡使用 8bit 位宽。
    • 观察到 8bit 位宽设备测试通过,16bit 设备失败

核心配置分析

EEPROM 配置片段

{
  "Eeprom_BCU": {
    "_OffsetWidth": 2,
    "AddrWidth": 1,
    "Address": 174,
    "WriteTmout": 100,
    "ReadTmout": 100,
    "RwBlockSize": 32,
    "WriteInterval": 20,
    "HealthStatus": 0
  }
}

虽然注释名为 _OffsetWidth,推测应为 OffsetWidth,且值为 2 表示偏移地址使用 16bit(2字节),这是关键点之一。


可能原因分析

1. AddrWidth 配置错误

当前配置 "AddrWidth": 1 表示使用 8bit 地址模式,但实际硬件为 16bit 位宽

正确做法:对于支持 16bit 地址的 EEPROM,AddrWidth 应设置为 2

影响说明:

  • AddrWidth=1 时,底层通信仅发送 1 字节地址。
  • 真实设备等待 2 字节地址 → 导致识别错误或无响应。
  • 读操作可能因设备默认状态返回 0,而写操作因指令错误而失败。

:white_check_mark: 此错误完全符合“读可行、写失败”的表现。


2. I2C 工具参数错误

命令示例:

./i2ctool64 2 4 4 0xae 0x00 0x06 0x06

参数说明需核实,若未正确指定地址宽度,则无法完成 16bit 寻址。

多数底层驱动要求明确指定 Address WidthOffset Width,否则默认按 8bit 处理。


3. 底层驱动或封装未适配 16bit 模式

Lua 测试代码分析

local ok, ret = pcall(fruData.FruDev.Write, fruData.FruDev, context.get_context_or_default(),
    EEPROM_SELFTEST_OFFSET, test_data)

此代码调用的是 FruDev.Write 方法,由 硬件代理(hwproxy) 处理。其行为依赖 CSR 配置中指定的 AddrWidthOffsetWidth

如果底层 hwproxy 或其 I2C 驱动未正确解析 AddrWidth=1(应为2),则不会生成正确的 I2C 数据包格式。


4. EEPROM 类型不匹配(Storagetype 限制)

文档指出:

StorageType="TianChi",而正常存储型应支持 EepromV2 或类似定义。

TianChi 架构有特殊限制。若 CSR 文件将 FRU 定义为非标准类型,可能导致写入路径被禁用或校验失败。


5. 写保护机制仍生效

尽管手动关闭写保护,但以下因素可能导致仍无法写入:

  • 写保护通过 GPIO 或专用芯片控制,未正确释放。
  • CSR 中缺少 EepromWpStorageLockChip 配置项,导致写保护逻辑未触发。
  • 写保护状态缓存未刷新。

根本原因归纳

因素 状态 是否导致失败
AddrWidth 设置错误(1 而非 2) :white_check_mark: 存在 :warning: 极可能主因
使用错误的 I2C 工具参数 :white_check_mark: 存在 :white_check_mark:
CSR 中 StorageType 不当 :white_check_mark:"TianChi" :warning: 可能影响写权限
驱动不支持 16bit 地址模式 :red_question_mark: 未知 :warning: 潜在原因
写保护未彻底释放 :warning: 存疑 可能叠加影响

解决方案建议

:white_check_mark: 修改 CSR 配置

AddrWidth 改为 2,以匹配 16bit 地址宽度:

"Eeprom_BCU": {
  "OffsetWidth": 2,
  "AddrWidth": 2,
  "Address": 174,
  "WriteTmout": 100,
  "ReadTmout": 100,
  "RwBlockSize": 32,
  "WriteInterval": 20,
  "HealthStatus": 0
}

:warning: 必须与实际 EEPROM 型号规格一致(如 24C256 支持 16bit 地址)。


:white_check_mark: 确认和更新 StorageType

如果该设备不是天池平台组件,应避免使用 StorageType="TianChi"

建议改为:

"StorageType": "EepromV2"

并在初始化中确保符合 FRU 写入规则。


:white_check_mark: 使用正确的 I2C 测试命令

确保 i2ctool64 支持指定地址宽度。例如(假设工具支持):

# 指定 AddressWidth=2, OffsetWidth=2
./i2ctool64 write --bus=1 --addr=0xae --aw=2 --ow=2 --offset=0x0000 --data=0x06

或根据真实接口文档调整参数顺序。


:white_check_mark: 验证写保护关闭流程

检查以下几点:

  1. 是否存在 EepromWp 控制对象?
  2. 是否在写入前调用 hwproxy 的写保护解除接口?
  3. 是否需要操作特定寄存器或 GPIO?

例如在代码中添加显式写保护控制:

-- 假设存在 WpControl 对象
fruData.EepromWp:Write(context, 0) -- 关闭写保护
-- 等待生效
sys.wait(10)

:white_check_mark: 代码层面增强调试输出

修改 Lua 测试函数加入更多日志:

local function test_write_eeprom(fruData, origin_eeprommp)
    log:notice("Starting EEPROM self-test for Fruid=%s", fruData.FruId)
    log:notice("AddrWidth=%d, OffsetWidth=%d", fruData.FruDev.AddrWidth, fruData.FruDev.OffsetWidth)

    local raw_data = fruData.FruDev:Read(context.get_context_or_default(), EEPROM_SELFTEST_OFFSET, #test_data)
    if not raw_data then
        log:error("Read original data failed")
        error("Read failed before write")
    end

    local ok, ret = pcall(fruData.FruDev.Write, fruData.FruDev, context.get_context_or_default(),
        EEPROM_SELFTEST_OFFSET, test_data)

    if not ok then
        log:error('Write failed: %s', ret or 'unknown')
        return false
    end

    local buffer = fruData.FruDev:Read(context.get_context_or_default(), EEPROM_SELFTEST_OFFSET, #test_data)
    if not buffer then
        log:error("Verification read failed after write")
        return false
    end

    -- 比较 test_data 和 buffer
    for i = 1, #test_data do
        if buffer:byte(i) ~= test_data:byte(i) then
            log:error("Data mismatch at byte %d: expected %02x, got %02x", i, test_data:byte(i), buffer:byte(i))
            return false
        end
    end

    log:notice("Write and verify success")
    return true
end

结论

最可能的根本原因是 AddrWidth 配置错误(设为 1 而非 2),导致 I2C 写命令格式不符合 16bit 位宽 EEPROM 的协议要求。

其他因素如 StorageType 设置异常、写保护未解除、I2C 工具使用不当等,可能会加剧问题,但核心在于 CSR 中 地址宽度未正确配置

建议优先修正 AddrWidth=2 并重新测试,可解决大部分写入失败问题。同时配合正确的 I2C 工具命令和完整的写保护控制流程,确保测试全面覆盖。