Pca9555识别槽位地址失败

问题描述

Pca9555识别槽位地址失败,root.sr的配置如下

“I2c_7”: { “Chips”: [ “Pca9555_IO” ] },

“Pca9555_IO”: { “OffsetWidth”: 1, “AddrWidth”: 1, “Address”: 39, “WriteTmout”: 100, “ReadTmout”: 100, “HealthStatus”: 0 },

“DftPca9555_1”: { “Type”: 1, “Id”: 3, “Slot”: 0, “DeviceNum”: 0, “ItemName”: “PCA9555 For EXU”, “PrompteReady”: “”, “PrompteFinish”: “”, “ProcessPeriod”: 65535, “RefChip”: “#/Pca9555_IO” },

“Accessor_SoltID”: { “Chip”: “#/Pca9555_IO”, “Offset”: 1, “Size”: 1, “Mask”: 255, “Type”: 0, “Value”: 4 },

“Connector_EXU_1”: {
“Bom”: “14100513”,
“Slot”: “#/Accessor_SoltID.Value”,
….}

BMC系统内报错日志

i2ctools可以识别pca9555芯片,也可以读取到芯片的寄存器与手册上默认配置一样。

环境信息

  • 操作系统:Ubuntu 24.04

  • 软件版本:OpenUBMC2512

  • 硬件配置:

期望结果

Accessor_SoltID.Value可以读取到芯片GPIO的输入的值。

实际结果

看日志怀疑BMC在初始化芯片的时候失败了,是root.sr文件的配置有问题吗?

尝试过的解决方案

“Accessor_SoltID”: { “Chip”: “#/Pca9555_IO”, “Offset”: 1, “Size”: 1, “Mask”: 255, “Type”: 0, “Value”: 4 },

修改过Mask的值,187,0,255,现象都是一样的,这个值是判断获取那个管脚的值吗?比如255就是获取第一组8个GPIO的值?

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

:white_check_mark: 解决方案

:white_check_mark: 方案一:【推荐】确认并统一 I2C 地址为 64(0x40)

:white_check_mark: 理想做法是将硬件 PCA9555 的地址引脚 A0-A2 接地(000),使其地址变为 0x40(64d)

修改 root.sr

"Pca9555_IO": {
  "OffsetWidth": 1,
  "AddrWidth": 1,
  "Address": 64,
  "WriteTmout": 100,
  "ReadTmout": 100,
  "HealthStatus": 0
}

:pushpin: 理由:

  • 与系统标准配置一致(如 Pca9555_IO_01010109 使用地址 64)。
  • 避免因非标准地址引发的底层驱动兼容性问题。
  • 符合《CSR配置字典》推荐实践。

:white_check_mark: 方案二:保留地址 39,但验证系统是否支持该地址

若必须使用 0x27 地址(如硬件已固化),请检查以下几点:

  1. 确保 i2c 总线支持该地址范围
    • 查看内核日志 dmesg | grep i2c 是否有 bad address 警告。
  2. 确认 hwproxy 支持非标准地址
    • OpenUBMC 某些版本可能对地址做过滤或限制。
  3. 检查地址是否正确传入芯片实例
    • Pca9555_IO_01 实例最终地址是否还是 39?可通过 resource tree 工具查看运行时属性。

:memo: 可尝试:

# 查看运行时对象地址
busctl introspect bmc.kepler.hwproxy /bmc/kepler/Chips/Pca9555_IO_01

:white_check_mark: 方案三:使用 Scanner 类对象替代 Accessor 初始化(BMC Studio 建议)

根据知识库中 文档7《BMC Studio 使用指导》 提到:

由于 SRUpgrade_1 对象的 WriteProtect 需要从 Pca9555 芯片获取,因此需要在 pca9555 芯片上配置读取器 Scanner 类型对象

:pushpin: 建议改用 Scanner 对象定期扫描寄存器,而非直接用 Accessor 强制读取。

示例:

"Scanner_SlotID": {
  "Chip": "#/Pca9555_IO",
  "Offset": 1,
  "Size": 1,
  "Interval": 5000,
  "Type": 0
},
"Accessor_SoltID": {
  "Chip": "#/Scanner_SlotID",
  "Offset": 0,
  "Size": 1,
  "Mask": 255,
  "Type": 1,
  "Value": 0
}

:white_check_mark: 优势:

  • 更稳定,避免初始化时因时序问题读取失败。
  • 支持防抖和重试机制。
点击此处查看详细分析解答

Pca9555识别槽位地址失败问题分析与解决方案


:magnifying_glass_tilted_left: 问题概述

用户在使用 BMC 系统(OpenUBMC2512)时,通过 root.sr 配置 Pca9555_IO 芯片用于读取 GPIO 输入以识别设备槽位 ID,但系统初始化时 Accessor 无法成功读取芯片寄存器值,导致 Connector_EXU_1.Slot 引用失败。

系统日志报错核心信息为:

chip: Pca9555_IO_01, bus: I2c_7, read failed: i2c.lua:117: response error, i2c read fail, ret: 5

同时 i2cdetect 未在地址 39 检测到设备,但在地址 0x27(十进制 39)存在设备且可通过 i2ctransfer 正常通信。


:puzzle_piece: 关键信息分析

:white_check_mark: 1. 硬件层通信正常

  • i2cdetect -a 7 显示在 地址 0x27(39d) 存在设备。
  • i2ctransfer 命令可成功读取多个寄存器,返回值符合 PCA9555 上电默认值(如 0xFE, 0xFF),表明:
    • I2C 总线连接正常。
    • 芯片供电和硬件连接无问题。
    • PCA9555 功能正常。

:cross_mark: 2. BMC 系统层访问失败

  • BMC 的 hwproxy 在初始化时尝试通过 I2C 读取 Pca9555_IO_01 芯片。
  • 日志明确指出 read failed: i2c read fail, ret: 5,说明底层驱动未能完成读操作。
  • 错误发生在 Accessor_SoltID 尝试读取 Offset: 1 时。

:warning: 3. 配置与实际不符?

  • root.sr 中配置:
    "Pca9555_IO": {
      ...
      "Address": 39
    }
    
  • 十进制地址 39 对应十六进制 0x27与实际物理地址一致,地址配置本身没有错误

:books: 根本原因分析

:magnifying_glass_tilted_right: 1. PCA9555 默认 I2C 地址为 0x27?

根据 搜索结果 #1《CSR配置字典之Pca9555类》 中的说明:

PCA9555 支持多个设备级联,通过地址引脚(A0-A2)配置不同 I2C 地址。
默认地址为:0x27(A2=A1=A0=1)

:white_check_mark: 因此,i2cdetect0x27 检测到设备是正常的。


:firecracker: 2. Root Cause:地址类型混淆 —— 十进制 vs 十六进制?

虽然 Address: 39 在数值上等于 0x27,但 OpenUBMC 系统是否期望地址以特定进制写入

重点在于:系统是否将 39 解释为十进制,还是需要明确使用十六进制表示?

从知识库中的多个 Address 使用实例看:

  • Address: 640x40(常见于 Pca9555)
  • Address: 2320xE8(Hi1822 网卡)
  • Address: 64 是 Pca9555 的 另一个常见地址组合(当 A2=A1=A0=0)

:red_exclamation_mark: 这意味着:PCA9555 的 I2C 地址由硬件引脚决定,同一个芯片可能有多种地址。


:red_exclamation_mark: 核心矛盾:物理芯片地址为 0x27,但 OpenUBMC 中 Pca9555 类建议使用地址 64

知识库实体描述与文档支持

  • 多处提到 Pca9555 的 I2C 地址为 64(即 0x40):
    • AddressPca9555_IO64
    • Pca9555_IO_01010109Address64
    • 搜索结果1的CSR文档中示例地址为 64

:red_exclamation_mark: 如果当前系统设计沿用了默认模板或库定义,默认期望地址是 64(0x40),而实际芯片地址是 39(0x27),就会导致:

  • BMC hwproxy 驱动尝试向 Address: 39 发起通信。
  • 但由于该地址未在某些驱动或规则中被允许(如白名单机制)、或地址宽度过小、或驱动未正确处理该映射,导致失败。

:thread: 3. 其他可能因素排查

问题点 分析 结论
AddrWidth / OffsetWidth 配置 均设置为 1,符合 PCA9555 要求(单字节地址/偏移) :white_check_mark: 正确
Accessor.Mask 的作用 仅用于屏蔽读取后的数据位,并不决定读哪个寄存器 :white_check_mark: 修改无效
Accessor.Offset = 1 读取的是 Input Port Register 1(GPIO7~0),逻辑正确 :white_check_mark: 正确
I2C 总线上是否有冲突? i2cdetect 仅检测到一个设备(0x27),无冲突 :white_check_mark: 正常

:white_check_mark: 解决方案

:white_check_mark: 方案一:【推荐】确认并统一 I2C 地址为 64(0x40)

:white_check_mark: 理想做法是将硬件 PCA9555 的地址引脚 A0-A2 接地(000),使其地址变为 0x40(64d)

修改 root.sr

"Pca9555_IO": {
  "OffsetWidth": 1,
  "AddrWidth": 1,
  "Address": 64,
  "WriteTmout": 100,
  "ReadTmout": 100,
  "HealthStatus": 0
}

:pushpin: 理由:

  • 与系统标准配置一致(如 Pca9555_IO_01010109 使用地址 64)。
  • 避免因非标准地址引发的底层驱动兼容性问题。
  • 符合《CSR配置字典》推荐实践。

:white_check_mark: 方案二:保留地址 39,但验证系统是否支持该地址

若必须使用 0x27 地址(如硬件已固化),请检查以下几点:

  1. 确保 i2c 总线支持该地址范围
    • 查看内核日志 dmesg | grep i2c 是否有 bad address 警告。
  2. 确认 hwproxy 支持非标准地址
    • OpenUBMC 某些版本可能对地址做过滤或限制。
  3. 检查地址是否正确传入芯片实例
    • Pca9555_IO_01 实例最终地址是否还是 39?可通过 resource tree 工具查看运行时属性。

:memo: 可尝试:

# 查看运行时对象地址
busctl introspect bmc.kepler.hwproxy /bmc/kepler/Chips/Pca9555_IO_01

:white_check_mark: 方案三:使用 Scanner 类对象替代 Accessor 初始化(BMC Studio 建议)

根据知识库中 文档7《BMC Studio 使用指导》 提到:

由于 SRUpgrade_1 对象的 WriteProtect 需要从 Pca9555 芯片获取,因此需要在 pca9555 芯片上配置读取器 Scanner 类型对象

:pushpin: 建议改用 Scanner 对象定期扫描寄存器,而非直接用 Accessor 强制读取。

示例:

"Scanner_SlotID": {
  "Chip": "#/Pca9555_IO",
  "Offset": 1,
  "Size": 1,
  "Interval": 5000,
  "Type": 0
},
"Accessor_SoltID": {
  "Chip": "#/Scanner_SlotID",
  "Offset": 0,
  "Size": 1,
  "Mask": 255,
  "Type": 1,
  "Value": 0
}

:white_check_mark: 优势:

  • 更稳定,避免初始化时因时序问题读取失败。
  • 支持防抖和重试机制。

:hammer_and_wrench: 关于 Mask 的说明

您提到的:

“Mask的值是判断获取那个管脚的值吗?比如255就是获取第一组8个GPIO的值?”

:white_check_mark: 解释如下:

  • Mask 不影响读取哪个 GPIO 寄存器(由 Offset 决定)。
  • 读取后,系统会将原始值与 Mask 进行按位与(&)操作,过滤出有效位。
  • 例如:
    • 当前 GPIO 输入值为 0xFE(二进制 11111110
    • Mask: 0xFC11111100),则最终值为 0xFC
    • Mask: 0x01,则仅保留最低位

:light_bulb: 因此 Mask 是一个后处理掩码,不影响通信是否成功。


:compass: 总结与建议

项目 建议
:prohibited: 当前问题根源 硬件 PCA9555 地址为 0x27,但系统更倾向标准地址 0x40(64d)
:white_check_mark: 推荐解决方案 修改硬件或确认使用 Address: 64,与 OpenUBMC 标准配置对齐
:white_check_mark: 备选方案 保留地址 39,但务必验证 hwproxy 是否支持该地址,并使用 Scanner 替代 Accessor
:white_check_mark: Accessor 使用建议 优先采用 Scanner + Accessor 组合模式,更鲁棒
:wrench: 调试建议 使用 busctl 查看运行时对象属性,结合 dmesghwproxy debug 日志深入分析

:paperclip: 参考资料

  • 《CSR配置字典之Pca9555类》: 明确建议使用地址 64
  • 知识图谱中多处实体表明 Pca9555_IO 标准地址为 64
  • BMC Studio 文档建议使用 Scanner 处理 Pca9555 寄存器读取
  • i2ctransfer 实测证明硬件通信正常,问题出在软件栈配置

:white_check_mark: 最终结论:root.sr 的地址配置虽数值正确,但可能因系统对 PCA9555 标准地址的预期不一致而导致访问失败。建议将 Address 改为 64 并重新验证。

修改地址后pca9555芯片可以识别槽位地址。