问题描述
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 配置失败问题分析与解决方案
问题概述
在当前环境中,Scanner 或 Accessor 组件在读取硬件寄存器时出现 **“opcode not supported” 错误 **(SMC completion code: 1),无法正常获取 Value。然而,通过 call Smc_xxx BlockIO Read 命令直接访问相同的 SMC 偏移地址,却能成功读取数据,表明底层硬件通信功能正常。
此外,将 Scanner 的 Type 从 **位读 **(Type=0) 改为 **块读 **(Type=1) 后,可正常获取数据,但失去了 Mask 掩码功能,无法提取特定位字段。
问题定位分析
环境信息
核心矛盾点
| 操作方式 |
是否成功 |
结果 |
call Smc_FanBoardSMC BlockIO Read |
成功 |
返回 [144, 66, 236, 49] |
Scanner + Type=0 (位读) |
失败 |
opcode not supported, SMC completion code: 1 |
Scanner + Type=1 (块读) |
成功 |
Status=0, Value=6016 |
关键问题:相同 Offset 和 Size 配置下,Scanner 位读模式触发了不支持的操作码,而块读和手动调用成功。
根本原因分析
根据提供的知识库和实际行为,可总结以下几点根本原因:
1. SMC 芯片不支持“位读”操作(Type=0)
Type=0 表示使用 **位读模式 **(bit-level read),需要 SMC 实现特定的“位操作指令”。
- SMC_FanBoardSMC_010103 不支持该操作码,因此当 Scanner 发起
Type=0 请求时,芯片返回 completion code: 1(不支持指令)。
- 而
call Smc_xxx BlockIO Read 使用的是 原生块读接口,绕过了 Scanner 的“位读语义”,直接执行底层 SMC 块访问,因此成功。
- 结论:
Smc_FanBoardSMC 硬件/固件层面 不支持位读操作,只支持块读(Type=1)。
2. Scanner 的 Type=0 触发了错误的 SMC 子命令
- 根据 CSR 配置文档 和 知识图谱中
Type 属性定义:
Type=0: 位读/写;Type=1: 块读/写
BlockIO 接口支持块读写,而位操作需额外指令封装。
- 当
Type=0 时,Scanner 框架尝试调用 非 BlockIO 的、更复杂的位操作接口(可能包含 bit-mask & extract 操作),这在 SMC 层未实现。
- 而
Type=1 直接使用 BlockIO,与手动调用一致,故无问题。
3. 多风扇聚合读取偏移不兼容
- 你尝试访问偏移
402656512(0x18000000),用于一次读取多个风扇速度。
- 该偏移报错
opcode not supported,但手动读取同一地址返回 [36,24,0,0,...] 成功。
- 表明:
- 该 SMC 支持从该地址 块读数据
- 但不支持通过位读语义访问它 —— 因为 Scanner 可能试图执行位解析或使用非标准封装。
4. 未启用 Aggregate 扫描
- 当前你使用的是 独立 Scanner 对象扫描单个 Offset
- 成功读取多风扇值(如
402656512)应配合 Scanner.Aggregate 汇聚扫描机制
- 若未配置 Aggregate,Scanner 框架将无法正确处理“位域抽取”逻辑,即使
Type=1 成功读出原始数据,也无法自动 decode 出单个风扇值。
相关知识支持(来自 Context)
| 实体 |
关联说明 |
Smc_FanBoardSMC_0101 |
处理风扇速度监控的 SMC 模块,通过 I2C 通信,存在 I2C Read Fail 问题。 |
Scanner |
周期性扫描硬件,Type=0 为位读,Type=1 为块读。 |
Type 属性 |
在 Scanner 中用于指定读取方式。文档明确说明:位读需器件支持,否则无效。 |
Accessor vs Scanner |
Accessor 用于按需读写,Scanner 用于周期监控。两者均依赖 Chip 的 SMC 操作支持。 |
BMC.Error.Unknown |
多次出现在 Smc_FanBoardSMC 访问失败中,常由 I2C 读失败或 opcode 不支持引起。 |
解决方案建议
方案一:统一使用 Type=1(块读) + 聚合扫描(Aggregate)
推荐做法,符合 SMC 实际能力。
步骤如下:
-
配置 Scanner 使用 Type=1(块读)
"Scanner_Fan1_RSpeed": {
"Chip": "#/Smc_FanBoardSMC",
"Offset": 402657025,
"Size": 4,
"Type": 1,
"Period": 1000,
"Debounce": "None"
}
-
启用 Scanner.Aggregate 实现批量读取与解析
- 将多个风扇速度寄存器集中在一块内存区域(如
402656512)
- 创建一个 Aggregate Scanner 读取整个 Block
- 使用
AggregateOffset 提取各风扇值
"Scanner_Aggregate_FanSpeeds": {
"Chip": "#/Smc_FanBoardSMC",
"Offset": 402656512,
"Size": 16,
"Type": 1,
"Period": 1000,
"AggregateStatus": true
}
"Scanner_Fan1_FSpeed": {
"Chip": "#/Smc_FanBoardSMC",
"AggregateOffset": 0,
"Size": 2,
"Type": 1
}
"Scanner_Fan1_RSpeed": {
"Chip": "#/Smc_FanBoardSMC",
"AggregateOffset": 2,
"Size": 2,
"Type": 1
}
-
在应用层做位解析(若需掩码)
- Aggregate 获取原始数据后,由上层逻辑(Redfish、WebUI)解析具体字段
- 或通过
expr(...) 表达式进行 post-processing
方案二:禁用 Mask,直接读取原始字段
若数据本身是完整整数(如 RPM),无需掩码,则可忽略 Mask 字段。
Type=1 下 Mask 字段无效(见文档),无需设置
- 读取原始
u16 或 u32 数值即可
- 适用于风扇速度、温度等连续型传感器
方案三:自定义 Accessor 实现按需读 + 掩码处理
适用于不需要周期扫描的场景。
"Accessor_ReadFanSpeed": {
"Chip": "#/Smc_FanBoardSMC",
"Offset": 402657025,
"Size": 4,
"Type": 1,
"Mask": 65535
}
- 通过外部触发访问该值
- 安全且可控,不占用周期扫描资源
临时缓解措施
- 防抖优化:如文档所述,可配置
SuccessDebounceCount 和 FailureDebounceCount,避免短暂错误导致误报。
- Nominal Value 回退:配置
NominalValue 作为失效时默认值,保证系统可用性。
- 监控
Status 字段:当 Status ≠ 0 时,表示值不可信,可用于告警判断。
配置最佳实践总结
| 项目 |
推荐配置 |
| SMC 设备类型 |
优先使用块读(Type=1) |
| 批量读取 |
启用 Scanner.Aggregate |
| 掩码需求 |
使用聚合读 + 上层表达式处理 |
| 周期性监控 |
使用 Scanner |
| 写入/控制操作 |
使用 Accessor |
| Offset 编码 |
十进制(JSON 要求) |
| Size 设置 |
与数据类型一致(u8:1, u16:2, u32:4) |
结论与建议
根本原因:Smc_FanBoardSMC 硬件/SMC 固件 不支持 Type=0 位读操作,导致 Scanner 在 Type=0 时返回 opcode not supported。
解决方案:
- 统一使用
Type=1 + Scanner.Aggregate
- 放弃
Mask 在位读中的作用,改由上层逻辑处理
- 验证 SMC 是否真正支持“位操作”命令集,若不支持则不应使用
Type=0
建议反馈至硬件团队:
- 明确
Smc_FanBoardSMC 是否支持 SMC 位操作(Type=0)
- 若不支持,则所有相关 CSR 配置应强制使用
Type=1
- 更新 CSR 模板,规避无效配置
最终目标:实现稳定、高效的传感器数据采集,避免因配置不匹配引发通信失败。
相关链接:
- CPU出错录像测试方式求助
- 风扇型号信息是否有明确的定义标准或文档支撑信息查询和校验
- web上阈值传感器的读值概率性显示为空的问题
- scanner的值与smc的读值不同
- CSR配置字典之Accessor类 | 文档中心 | openUBMC
设置风扇转速Scanner type为1后,将转速Scanner.Value使用同步引用的方式传递给Fan对象后,会报error[emit signal: nesting is not allowed]。并且风扇类型识别会失败。
Smc位读的时候,offset会与上0xfffffc00再加上0x100,目的是将smc对应的整块数据取出来,再在代码里进行掩码运算,详细参考component_drivers的smc部分代码。AtomGit | GitCode - 全球开发者的开源社区,开源代码托管平台
smc报错opcode不支持可能是逻辑不支持这种位读的能力,可以看下两个环境的cpld版本是否一致。
1 个赞