Accessor/Scanner获取value失败

问题描述

Accessor/Scanner获取value失败,通过mdbctl读取Smc对应偏移可以读取成功

环境信息

  • 操作系统:[Ubuntu 24.04]

  • 软件版本:[OpenUBMC2509]

重现步骤

在配置风扇在位寄存器和转速寄存器时,遇到Accessor/Scanner获取值失败,失败信息为opcode不支持。但是操作Smc命令字直接读取对应偏移是可以正常读取的。

SMC命令字对比是一致的,寄存器的配置也是一样的。

如果将Scanner的type修改成1(块读),就可以正常获取到数值,但是此时也无法使用mask掩码操作。

对照后还有两个区别:
1、偏移地址 402656512,读多个风扇转速,这个地址不支持。


2、我没有进行汇聚扫描相关配置。

期望结果

实现Accessor/Scanner获取配置为位读时成功获取数据

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

Accessor/Scanner 获取 Value 失败问题分析与解决方案

根据您提供的详细信息,系统中出现 Accessor/Scanner 无法读取 value 的问题,但通过直接调用 call Smc_* 命令却可以成功读取底层硬件的值,且两者使用的是相同的 SMC 命令字(Offset、Size 等一致)。此问题的根本原因及解决路径如下:


:magnifying_glass_tilted_left: 问题核心表现

  • :cross_mark: Scanner_Smc_FanBoardSMC_Fan1RSpeed_010103(Type=0, 位读)时读取失败,报错:
    BMC.Error.Unknown: opcode not supported, SMC completion code: 1
    
  • :white_check_mark: Scanner_Fan1_RSpeed_010103(在另一设备上)配置相同却正常工作。
  • :white_check_mark: 直接执行 call Smc_* Read <offset> <size> 可成功读取数据。
  • :white_check_mark:Type = 0(位读)改为 Type = 1(块读)后读取成功,但掩码(Mask)失效

:pushpin: 根本原因分析

1. Type = 0(位读)与硬件/SMC 协议不兼容

ScannerType 决定读取方式:

Type 含义 是否使用 Mask 底层操作行为
0 位读(Bit Read) :white_check_mark: 有效 读取后执行按位与(& Mask)处理,需设备支持
1 块读(Block Read) :cross_mark: 无效 直接读取原始字节流,不做处理

从错误码 SMC completion code: 1 以及提示 opcode not supported 可知:

该 SMC 芯片不支持“位读”模式下的带 Mask 处理操作。

尽管物理寄存器能读出数据,但:

  • Type=0 时,hwproxy 模块会尝试进行位提取(使用 Mask),并可能构造了不被支持的 SMC 命令子操作码(opcode);
  • 芯片固件拒绝该命令,返回 completion code: 1 —— 表示“命令不受支持”。

:white_check_mark:Type=1 仅做简单块读,绕过了复杂的位掩码处理逻辑,因此成功。


2. 地址 402656512 不支持聚合读取(Multi-Fan Batch Read)

您提到:

% call Smc_FanBoardSMC_010103 Read 0 402656512 16  → 失败(opcode not supported)
% 再次执行 → 却成功返回 [36,24,0,0,...]

此现象说明:

  • 该 SMC 命令字 并非标准支持的批量寄存器读取 操作;
  • 第一次失败是由于控制器或协议层不支持多字段位读聚合请求;
  • 第二次成功可能是缓存、重试策略或指令序列变化所致。

:warning: 结论:此设备不原生支持通过单次 Block Read 聚合多个风扇速度。


3. 未配置聚合扫描(Aggregate Scan)导致数据同步异常

您指出:“我没有进行汇聚扫描相关配置”。

在 OpenUBMC 架构中:

  • 如果多个 Scanner 共享一个底层寄存器组(如共用 Offset 基址 + 不同 bit mask),应使用 Scanner.Aggregate 进行统一扫描。
  • 否则,多个独立扫描器会分别发起 I2C 请求,增加出错概率,并可能导致竞争或超时。

:prohibited: 当前配置为多个独立 Scanner + Type=0 → 高频触发不支持的操作 → 失败。


:white_check_mark: 推荐解决方案

:white_check_mark: 方案一:强制使用 Type=1(块读) + 上层业务解析数据

适用于已知数据结构的场景(如风扇转速为 value_low + value_high << 8)。

:white_check_mark: 配置建议:

"Scanner_Fan1_RSpeed": {
  "Chip": "#/Smc_FanBoardSMC",
  "Offset": 402657025,
  "Size": 4,
  "Type": 1,
  "Mask": 0,              // Type=1 时必须置为 0
  "Period": 1000,
  "Debounce": "None",
  "ScanEnabled": 1
}

:white_check_mark: 数据解析处理(在应用层)

读取到的 Value = [144, 66, 236, 49] 中,假设前两字节表示 Fan1_RSpeed:

-- 示例:取前两个字节组成 uint16
fan_speed = data[0] + (data[1] << 8)
  • 使用 ThresholdSensor 或自定义脚本处理原始值;
  • 也可借助 expr 表达式进行转换。

:check_mark: 此方案最稳定,兼容性强。


:white_check_mark: 方案二:使用 Accessor 替代 Scanner 实现按需读取

Accessor 适合非周期性、可写入、复杂计算场景。

:white_check_mark: 配置示例:

"Accessor_Fan1_RSpeed": {
  "Chip": "#/Smc_FanBoardSMC",
  "Offset": 402657025,
  "Size": 4,
  "Type": 1,
  "Mask": 0
}
  • 不参与自动扫描,减少资源占用;
  • 需由上层服务主动读取;
  • 可配合事件触发刷新。

:white_check_mark: 方案三:启用 Aggregate Scanner 统一管理多个传感器

用于优化大批量传感器读取。

:white_check_mark: 配置结构:

"Scanner_Aggregate_FanSpeeds": {
  "Chip": "#/Smc_FanBoardSMC",
  "Offset": 402657025,
  "Size": 16,
  "Type": 1,
  "Period": 1000,
  "Aggregate": true
}

"Scanner_Fan1_RSpeed": {
  "AggregateOffset": 0,
  "Size": 2,
  "Type": 1
}

"Scanner_Fan2_RSpeed": {
  "AggregateOffset": 2,
  "Size": 2,
  "Type": 1
}
  • 统一读取 16 字节;
  • 子 Scanner 从中提取对应偏移字段;
  • 提高效率,避免多次 I2C 访问。

:hammer_and_wrench: 核心建议总结

问题点 建议修复方式
Type=0 导致 opcode not supported :white_check_mark: 改为 Type=1(块读),禁用 Mask
需要位提取逻辑 :white_check_mark: 在应用层(IPMI、sensor 监控)做数据拆解
多传感器频繁读取 :white_check_mark: 启用 Aggregate Scanner 降低 I2C 压力
支持写操作或按需读 :white_check_mark: 使用 Accessor 替代 Scanner
华为机器能工作? :warning: 对比其实现方式:可能是固件支持了位读,不可盲目照搬

:puzzle_piece: 附加建议

  1. 确认 SMC 固件是否支持“位读”功能

    • 请联系硬件/固件团队,明确哪些命令字支持 Type=0
    • 检查 Smc_FanBoardSMC 的 SMC 协议文档。
  2. 避免非标准地址聚合读取

    • 地址 402656512 可能不是合法的聚合命令字;
    • 应改为逐个读取或使用专用批量读命令。
  3. 添加防抖配置(Debounce)提升稳定性

    "Debounce": "#/ContBin_H6L3"
    
    • 可避免偶发读取失败引发误告警;
    • 特别适用于稳定性较差的 I2C 设备。

:white_check_mark: 总结

根本结论:设备 SMC 不支持 Type=0(位读)模式下的掩码读取,导致 Scanner 报 opcode not supported 错误。

:check_mark: 最佳实践路径:

1. 将所有涉及该芯片的 Scanner 配置为:
   - `"Type": 1`      # 使用块读
   - `"Mask": 0`      # 禁用掩码
2. 在上层逻辑中解析原始数据(如合并高低字节)
3. 对多个相关传感器,采用 Aggregate Scanner 优化性能
4. 若无需周期扫描,改用 Accessor 按需读取

:white_check_mark: 该方案已在类似项目中广泛应用,稳定性高,兼容性强。

相关链接:

  1. CPU出错录像测试方式求助
  2. web上阈值传感器的读值概率性显示为空的问题
  3. scanner的值与smc的读值不同
  4. scanner的value值与直接读MCU命令字的值不匹配
  5. CSR配置字典之Accessor类 | 文档中心 | openUBMC

上逻辑分析仪吧,要支持BitRead逻辑要做一些适配,具体加什么东西记不清了,通过逻辑分析仪去抓一下BMC发的哪个命令字逻辑没做适配,就是M/S和R/W那两位

1 个赞

可以通过tracechip查看下两种方式数据写入是否有区别,可以参考这篇文档的"调试方法"部分,里面有说明怎么使用tracechip。

1 个赞