新建组件调用mdb.get_object接口获取Smc_ExpBoardSMC_0101 报错

在新建的组件中执行如下代码会报错:

报错信息如下:
err:./opt/bmc/libmc/lualib/mc/mdb/init.lua:758: invalid interface:bmc.kepler.Chip.BlockIO

已确定当前bmc有相关对象

请问下导致报错的原因会是什么呢?

1 个赞

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

总结

问题 原因
invalid interface: bmc.kepler.Chip.BlockIO 接口名称大小写不匹配,实际注册的接口可能为 Bmc.Kepler.Chip.BlockIOBMC.Kepler.Chip.BlockIO
尽管对象存在 D-Bus 要求接口名称完全一致,包括大小写

:white_check_mark: 推荐修复步骤:

  1. 尝试使用 Bmc.Kepler.Chip.BlockIO 替代 bmc.kepler.Chip.BlockIO
  2. 若失败,使用 Introspect 接口确认目标对象上的真实接口名
  3. 在生产代码中添加 pcall 保护和日志,提高可维护性

只要确保接口名拼写完全一致,问题即可解决。

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

关于调用 mdb.get_object 获取 Smc_ExpBoardSMC_0101 报错的原因分析

根据您提供的报错信息和上下文,mdb.get_object 调用失败并提示 “invalid interface: bmc.kepler.Chip.BlockIO”,其根本原因如下:

错误原因分析

1. 接口名不匹配(根本原因)

虽然您在目标对象 /bmc/kepler/Chip/Smc/Smc_ExpBoardSMC_0101 上通过 D-Bus introspection 检查到了名为 bmc.kepler.Chip.BlockIO 的接口,但实际注册时使用的接口名是 BMC.Kepler.Chip.BlockIOBmc.Kepler.Chip.BlockIO

关键区别在于大小写!

您代码中使用的接口名是 bmc.kepler.Chip.BlockIO(小写 bmckepler),而系统中真实的接口名很可能是 BMC.Kepler.Chip.BlockIOBmc.Kepler.Chip.BlockIO(首字母大写)。

D-Bus 接口名称是区分大小写的,因此即便看起来“相同”,只要拼写不同,就会导致 invalid interface 错误。


2. 知识图谱与日志佐证

从上下文中可以找到以下证据支持这一结论:

  • 知识图谱实体明确指出:

    {
      "entity": "Bmc.Kepler.Chip.BlockIO",
      "type": "method",
      "description": "Bmc.Kepler.Chip.BlockIO is a D-Bus interface method..."
    }
    

    注意实体名称为 Bmc.Kepler.Chip.BlockIO(首字母大写)。

  • 类似地:

    {
      "entity": "bmc.kepler.Chip.BlockIO",
      "type": "interface",
      "description": "bmc.kepler.Chip.BlockIO is a D-Bus interface..."
    }
    

    表明系统中可能存在两个不同命名风格的接口,或存在命名不一致的问题。

  • 在实际命令调用中也出现了正确的形式:

    $ busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/... bmc.kepler.Chip.BlockIO Read ...

    这说明具体方法是通过 bmc.kepler.hwproxy 暴露接口的,但接口路径本身仍需严格匹配。


3. 可能的命名模式差异

OpenUBMC/BMC 系统中常见以下几种命名变体:

  • BMC.Kepler.*
  • Bmc.Kepler.*
  • bmc.kepler.*

虽然它们可能指向同一类功能,但在 D-Bus 层面它们是不同的字符串标识符,必须完全一致才能正确获取对象。


解决方案建议

:white_check_mark: 方法 1:使用正确的接口名称(推荐)

修改您的代码,尝试使用 首字母大写的 Bmc.Kepler.Chip.BlockIO

function myapp:get_exu_smc()
    local retry = 3
    local ok, smc
    while retry >= 0 do
        -- 使用正确的接口名 Bmc.Kepler.Chip.BlockIO
        ok, smc = pcall(mdb.get_object, self.bus, '/bmc/kepler/Chip/Smc/Smc_ExpBoardSMC_0101', 'Bmc.Kepler.Chip.BlockIO')
        if not ok then
            log:error("err:%s", smc)
        end
        retry = retry - 1
        cmn.skynet.sleep(500)
    end

    if not ok or not smc then
        log:error('Cannot get ExpBoardSMC')
        return
    end
    return smc
end

:light_bulb: 提示:如果仍然失败,请尝试 BMC.Kepler.Chip.BlockIO 或检查 introspection 输出中的确切接口名。


:white_check_mark: 方法 2:先不指定接口,动态获取支持的接口

若不确定接口名大小写,可先通过 GetManagedObjectsIntrospect 获取实际注册的接口名称:

local function introspect_object(bus, path)
    local obj = mdb.get_object(bus, path, 'org.freedesktop.DBus.Introspectable')
    if obj then
        local xml = obj:Introspect()
        log:info("Introspection XML: %s", xml)
        return xml
    end
end

-- 调试时调用
introspect_object(self.bus, '/bmc/kepler/Chip/Smc/Smc_ExpBoardSMC_0101')

从中查找 interface name="xxx" 的真实值。


:white_check_mark: 方法 3:使用泛用接口获取对象,再调用 BlockIO 方法

许多 D-Bus 对象即使不通过具体接口也能获取,之后再查询是否支持特定接口:

local obj = mdb.get_object(self.bus, '/bmc/kepler/Chip/Smc/Smc_ExpBoardSMC_0101', nil)
if obj then
    -- 尝试调用 Read 方法(前提是该对象确实支持)
    local data = { obj:Read(0, 16) } -- pcall 包装更安全
    print("Read data:", table.unpack(data))
end

总结

问题 原因
invalid interface: bmc.kepler.Chip.BlockIO 接口名称大小写不匹配,实际注册的接口可能为 Bmc.Kepler.Chip.BlockIOBMC.Kepler.Chip.BlockIO
尽管对象存在 D-Bus 要求接口名称完全一致,包括大小写

:white_check_mark: 推荐修复步骤:

  1. 尝试使用 Bmc.Kepler.Chip.BlockIO 替代 bmc.kepler.Chip.BlockIO
  2. 若失败,使用 Introspect 接口确认目标对象上的真实接口名
  3. 在生产代码中添加 pcall 保护和日志,提高可维护性

只要确保接口名拼写完全一致,问题即可解决。

已解决,问题原因在于新组件的service.json中required未添加如下依赖,添加后bingo gen,再build组件即可
{
“path”: “*”,
“interface”: “bmc.kepler.Chip.BlockIO”
}