【求助】为什么手动敲命令读cpld(smc)失败了 但是scanner却能读到?

问题描述

"Scanner_PowerGood": {
            "Chip": "#/Smc_ExpBoardSMC",
            "Offset": 469765888,
            "Size": 1,
            "Mask": 255,
            "Type": 0,
            "Period": 100,
            "Debounce": "None",
            "Value": 0
        },

sr文件中定义了一个scanner从cpld的469765888 读取一个字节

我手动执行mdbctl 从469765888 读取1个字节报错了 说是对端的cpld不支持这个命令字

~ ~ # mdbctl call Smc_ExpBoardSMC_0101 bmc.kepler.Chip.BlockIO Read 0 469765888 1
BMC.Error.Unknow: ./opt/bmc/libmc/lualib/mc/context.lua:203: ./opt/bmc/libmc/lualib/sd_bus/object.lua:317: ./opt/bmc/apps/hwproxy/lualib/hwproxy_objects/app_bus.lua:104: ./opt/bmc/apps/hwproxy/lualib/hw_utils/hw_wait_access.lua:101: chip: Smc_ExpBoardSMC_0101, bus: I2c_2, read failed: chip.lua:696: request error, opcode not supported, SMC completion code: 1

~ ~ #

但是为什么scanner能读到呢??
~ ~ # mdbctl lsprop Scanner_PowerGood_0101 | grep -i value
Value=1
NominalValue=0
~ ~ #

主要是两边结果不一致 理论上 两边的结果应该一致才对吧?
mdbctl call Smc_ExpBoardSMC_0101 bmc.kepler.Chip.BlockIO Read 这个读的方法应该没问题的 换别的offset都能读到的

有大佬了解的吗?请帮忙指导下!

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

结论

命令失败的原因不是芯片本身不可读,而是手动使用的块读命令不被该芯片/偏移位置支持,而 Scanner 使用位读能够正常工作。参考社区经验,请根据芯片的实际能力选择正确的读取方式。

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

问题分析

您遇到的现象是:手动使用 mdbctl call Smc_ExpBoardSMC_0101 bmc.kepler.Chip.BlockIO Read 命令时报错 opcode not supported,而同样 Offset 的 Scanner_PowerGood 却能正常读取到值。根本原因在于 读取方式不匹配

1. Scanner 的读取方式

在 SR 配置中,Scanner_PowerGoodType0,表示采用 位读(Bit Read) 方式。根据社区案例中的解释:

“你配置的 Type = 0,是位读,你应该用 bmc.kepler.Chip.BitIO 试试。或者 Scanner 那边 Type 改为 1,用块读的方式看看。”
—— Topic 5695 回复(参见 Document Chunk #2

同样,“CSR 配置字典之 Scanner 类”明确指出 Type 字段:0 代表位读,1 代表块读(参考 Search Result #5)。

2. 手动命令的读取方式

您手动执行的命令是:

mdbctl call Smc_ExpBoardSMC_0101 bmc.kepler.Chip.BlockIO Read ...

BlockIO Read 接口执行的是 块读(Block Read) 操作,而非位读。对于您指定的 Offset(469765888),该 CPLD 或 SMC 芯片可能只支持位读命令,而不支持块读命令,因此返回 opcode not supported(命令字不支持)。

3. 为什么 Scanner 能读到?

Scanner 按照配置的 Type=0 使用位读方式访问芯片,芯片能够正确处理位读请求,所以成功返回了 Value=1。这证实了芯片在该偏移位置确实实现了位读功能。

4. 其他佐证

  • 在同一社区话题中,有用户遇到类似问题:将 Type 从 0 改为 1 后不再报错,但获取到的值不符合预期(Topic 5312,Document Chunk #5)。
  • 另外有说明:“smc 读分两步操作:1、写一条固定的命令通知 cpld 接下来是要读数据;2、读数据。”(Topic 7027 回复,Document Chunk #4)—— 位读和块读使用不同的命令流程,芯片可能仅实现了位读流程。

5. 建议

  • 验证手动位读:用 bmc.kepler.Chip.BitIO 接口代替 BlockIO 进行手动读取,例如:
    mdbctl call Smc_ExpBoardSMC_0101 bmc.kepler.Chip.BitIO Read 0 469765888 1
    
  • 如果需要块读:修改 Scanner 配置中的 Type 为 1,使 Scanner 采用块读方式,这样结果就能与手动块读一致。

结论

命令失败的原因不是芯片本身不可读,而是手动使用的块读命令不被该芯片/偏移位置支持,而 Scanner 使用位读能够正常工作。参考社区经验,请根据芯片的实际能力选择正确的读取方式。

发现使用blkio从469765888读取1字节 会失败 但是使用bitio是可以的

~ ~ # mdbctl call Smc_ExpBoardSMC_0101 bmc.kepler.Chip.BitIO Read 0 469765888 1 0xff
[1]

~ ~ # mdbctl call Smc_ExpBoardSMC_0101 bmc.kepler.Chip.BlockIO Read 0 469765888 1
BMC.Error.Unknow: ./opt/bmc/libmc/lualib/mc/context.lua:203: ./opt/bmc/libmc/lualib/sd_bus/object.lua:317: ./opt/bmc/apps/hwproxy/lualib/hwproxy_objects/app_bus.lua:104: ./opt/bmc/apps/hwproxy/lualib/hw_utils/hw_wait_access.lua:101: chip: Smc_ExpBoardSMC_0101, bus: I2c_2, read failed: chip.lua:696: request error, opcode not supported, SMC completion code: 1

~ ~ #

我之前理解的bitio就是在blkio的基础上再进行一下mask远算 现在看来并不是这么简单。

有大佬知道这个bitio和blkio底层实现有啥区别嘛

更新一下进展:

目前发现 scanner type=0 BitIO的时候 会把469765888= 0x1C000F00 修正为0x1C000D00

image

cpld固件里 只认0x1C000D00 不认0x1C000F00 就出现了当前的问题。

有大佬能帮忙确认下是存在这样的修正机制吗?

针对Smc类型的器件,其位读会进行数据读取然后按照协议里parameter字段对特定位数据做掩码运算后返回,具体可以参考component_drivers/drivers/internal/chip/chip_smc/smc.cpp-代码预览-component_drivers:基于 openUBMC 的硬件设备驱动组件项目 - AtomGit