devmon
版本信息
| 项目 | 内容 |
|---|---|
| 组件版本 | 1.2.94 |
| 首发版本 | 1.2.24 |
| 文档作者 | |
| 最后更新 | 2026-08-24 |
1. 组件概述
1.1 组件简介
devmon(Device Monitor)是 openUBMC 的硬件设备抽象与管理框架。它读取 CSR(组件自描述记录),加载与设备 Compatible 匹配的动态驱动,将底层总线、芯片、扫描器、访问器以及部件对象注册为统一的 D-Bus 对象,并负责设备从添加、初始化、启动到停止、卸载的完整生命周期。
组件支持两种构建形态:
- 单架构模式:由
bmc.kepler.devmon同时完成 CSR 解析、驱动加载、拓扑建立和设备对象注册。 - 三层架构模式(
unidev=true):devmon、hwdiscovery和hwproxy分工协作;旧格式 CSR 由发现层和硬件代理层处理,新格式 CSR 仍由 devmon 处理。
1.2 解决什么问题
- 统一硬件抽象:上层组件通过稳定的对象和接口访问硬件,无需理解具体芯片、总线和厂商驱动实现。
- 降低部件适配成本:通过 CSR 描述对象、拓扑和变量,通过
.so驱动实现硬件差异,新部件接入不需要修改 devmon 主流程。 - 支持动态发现和生命周期管理:运行时可按连接器位置添加或移除设备,自动创建和清理对应对象、拓扑及驱动实例。
- 兼容两代 CSR/驱动体系:三层架构根据
FormatVersion在 CSR1/ABI v1 与 CSR2/ABI v2 之间选择处理路径;单架构统一使用 ABI v2。 - 提升可服务性:提供驱动加载记录、访问统计、扫描快照、连接器信息、拓扑信息和关键调试命令,便于快速定界“配置、驱动、发现还是硬件访问”问题。
1.3 核心功能
- CSR 解析与校验:校验
Unit、Objects、连接器位置和可选管理拓扑,完成对象重命名、变量替换、引用与同步关系处理。 - 驱动动态加载:按
Unit.Compatible解析驱动库名,使用dlopen/dlsym加载驱动并调用register_device_driver获取驱动表。 - 设备生命周期管理:依次执行驱动构造、初始化、对象注册和启动;卸载时先停止驱动,再注销设备对象和对象组。
- 对象组分发:为每个
GroupPosition创建ObjectGroup,向其他组件提供对象数据、生命周期 ID 和管理拓扑。 - 单架构/三层架构切换:通过组件选项
unidev选择部署形态,并在三层架构中按对象策略路由到hwdiscovery或hwproxy。 - 调试与一键日志:输出
topology.txt、snapshot.csv、drivers_load_info.csv、connectors.txt等诊断文件,并支持 mdbctl 芯片访问和防抖追踪命令。
1.4 关键术语表
| 术语 | 解释 |
|---|---|
| devmon | Device Monitor,openUBMC 硬件设备抽象与管理框架 |
| CSR | Component Self-Description Record,组件自描述记录;通常以 .sr 文件承载设备、对象和拓扑配置 |
| MDS | Module Description Source,组件描述资源;用于描述可调试接口和命令元数据 |
| Connector | 连接器对象或调用参数集合,提供位置、槽位、系统 ID、总线等发现上下文 |
| GroupPosition | 对象组的唯一位置标识,也是动态添加/删除设备的主键;当前源码不使用 Position 代替该字段 |
| ObjectGroup | 按 GroupPosition 聚合的对象集合,包含对象数据、拓扑和生命周期信息 |
| FormatVersion | CSR 格式版本;三层架构中 < 5.00 走 CSR1/ABI v1,>= 5.00 走 CSR2/ABI v2 |
| ABI | Application Binary Interface,devmon 与动态驱动之间的二进制接口约定 |
| unidev | devmon 构建选项;为 true 时启用 devmon、hwdiscovery、hwproxy 三层架构,默认值为 false |
| hwdiscovery | 三层架构中的硬件发现服务,负责 CSR1 设备发现、连接器和对象组分发 |
| hwproxy | 三层架构中的硬件代理服务,承载 Accessor、Scanner、芯片及防抖等直挂对象 |
| owner | ObjectGroup 中对象数据的归属方;调用 GetObjects 前应先读取 Owners |
1.5 外部交互边界图
服务、接口与对象路径
| 架构/用途 | 服务名 | 根对象路径 | 主要接口或对象组路径 |
|---|---|---|---|
| 通用设备管理入口 | bmc.kepler.devmon | /bmc/dev | bmc.dev |
| 单架构 ObjectGroup | bmc.kepler.devmon | /bmc/dev/ObjectGroup | /bmc/dev/ObjectGroup/<GroupPosition>,接口 bmc.dev.ObjectGroup |
| 三层架构发现入口 | bmc.kepler.hwdiscovery | /bmc/kepler/hwdiscovery | 接口 bmc.dev |
| 三层架构 ObjectGroup | bmc.kepler.hwdiscovery | /bmc/kepler/ObjectGroup | /bmc/kepler/ObjectGroup/<GroupPosition>,接口 bmc.kepler.ObjectGroup |
| 三层架构硬件代理 | bmc.kepler.hwproxy | /bmc/kepler | 芯片、总线、Accessor、Scanner 等对象 |
FormatVersion 与驱动 ABI 选择
| 构建形态 | CSR FormatVersion | 处理路径 | 驱动 ABI/库名 |
|---|---|---|---|
单架构 unidev=false | 任意值 | devmon 本地处理 | 强制 ABI v2,lib<DriverName>.so |
三层架构 unidev=true | < 5.00 | devmon 转发到 hwdiscovery/hwproxy | ABI v1,优先 libCsr1<DriverName>.so,找不到时回退 lib<DriverName>.so |
三层架构 unidev=true | >= 5.00 | devmon 本地处理 | ABI v2,lib<DriverName>.so |
| 任意构建形态 | 字段缺失或无法解析 | 默认按 5.00 处理 | 对应 CSR2/ABI v2 |
三层架构的直挂对象路由规则如下:Connector 路由到 hwdiscovery;Accessor、Scanner、SmcDfxInfo、Median、MidAvg、Cont 和 ContBin 路由到 hwproxy。
2. API 使用说明与示例
2.1 AddDevice
功能说明
从指定 CSR 文件读取配置并添加一个设备。devmon 会规范化 GroupPosition、解析 FormatVersion、校验 CSR、加载驱动、建立对象与拓扑,最后创建 ObjectGroup。
| 属性 | 内容 |
|---|---|
| 接口名 | bmc.dev |
| 服务名 | bmc.kepler.devmon |
| 对象路径 | /bmc/dev |
| 方法名 | AddDevice |
| D-Bus 签名 | 入参 sa{sv},出参为空 |
| 首发版本 | 1.2.24 |
| 废弃状态 | 正常可用 |
参数说明
| 参数名 | 方向 | 类型 | 描述 | 取值范围 |
|---|---|---|---|---|
csr_file | 输入 | String (s) | BMC 文件系统中的 CSR 文件路径 | 文件必须存在、可读,内容必须为合法 JSON |
connector | 输入 | Dict<String, Variant> (a{sv}) | 设备发现上下文 | 至少包含非空 GroupPosition |
GroupPosition | 输入,字典字段 | String 或整数 | 对象组唯一位置;添加和删除设备时使用同一值 | 字符串原样使用;整数转为大写十六进制,至少 2 位且总长度补为偶数,例如 1→01、256→0100 |
SystemId | 输入,字典字段 | U8 | 系统标识 | 可选,默认 1 |
ManagerId | 输入,字典字段 | String | 管理器标识 | 可选,默认 "1" |
ChassisId | 输入,字典字段 | String | 机箱标识 | 可选,默认 "1" |
Slot | 输入,字典字段 | U8 | 槽位号,写入 ObjectGroup 属性 | 可选,默认 0 |
Buses、Position、GroupId、Container 等 | 输入,字典字段 | Variant | 可供 CSR 变量替换、拓扑映射或对象属性使用 | 按目标 CSR 约定填写;Position 不能代替 GroupPosition |
返回值与异常
| 返回值/异常 | 含义 | 触发条件 | 处理建议 |
|---|---|---|---|
| 无返回值 | 请求已完成 | 正常添加,或同位置设备已存在而被跳过 | 结合对象树和日志确认最终状态 |
Failed to read csr file: ... | CSR 文件读取失败 | 路径错误、文件不存在或权限不足 | 检查路径、权限和部署结果 |
Connector Position is not initialized | 缺少有效位置 | 未传 GroupPosition,或其值为空 | 改用非空 GroupPosition;不要只传 Position |
| JSON/类型异常 | CSR 解析失败 | 文件不是合法 JSON 或顶层不是字典 | 使用 jq empty <file> 校验 |
CSR Unit Type/Name/Compatible is empty | Unit 字段不完整 | Unit.Type、Unit.Name 或 Unit.Compatible 缺失/为空 | 补齐对应字段 |
CSR Objects is empty | 对象定义为空 | 缺少 Objects 或无对象 | 至少定义 Unit.Name 对应对象 |
Driver not found / Failed to load driver | 驱动未找到或无法加载 | 库名不匹配、依赖缺失、ABI 不匹配 | 按 3.3 节检查命名、符号和依赖 |
CSR ManagementTopology missing Anchor | 管理拓扑不完整 | 配置了非空 ManagementTopology,但没有 Anchor | 补充 Anchor.Buses,或在不需要拓扑时删除整个 ManagementTopology |
应用场景
- 连接器识别到部件在位后,按 CSR 文件动态加载该部件。
- 开发或定位阶段手工加载测试 CSR,验证驱动、拓扑和对象注册。
- 对同一 CSR 使用不同
GroupPosition和Slot创建多个独立实例。
限制条件
GroupPosition是当前源码实际使用的主键。仓库 README 中使用Position的旧命令不能直接作为当前版本的有效示例。- 相同
GroupPosition已存在时,devmon 记录device already exists, skip add device并跳过重复创建;不会覆盖现有实例。 - 调用成功仅表示方法没有抛出异常;仍应检查 ObjectGroup、驱动加载记录和日志。
- 三层架构且
FormatVersion < 5.00时,请同时确认hwdiscovery、hwproxy服务已经启动。
调试示例
命令行调试
CSR_FILE=/opt/bmc/sr/example.sr
GROUP_POSITION=02
busctl --user call bmc.kepler.devmon /bmc/dev bmc.dev AddDevice 'sa{sv}' "$CSR_FILE" 3 GroupPosition s "$GROUP_POSITION" SystemId y 1 Slot y 2该方法无返回参数,正常情况下 busctl 可能不打印正文。通过以下命令验证:
# 单架构/CSR2
busctl --user tree bmc.kepler.devmon /bmc/dev/ObjectGroup
busctl --user introspect bmc.kepler.devmon /bmc/dev/ObjectGroup/$GROUP_POSITION bmc.dev.ObjectGroup
# 三层架构 CSR1
busctl --user tree bmc.kepler.hwdiscovery /bmc/kepler/ObjectGroup2.2 AddDeviceWithData
功能说明
直接通过 D-Bus 传入 CSR 内容并添加设备,不要求先把 CSR 写入目标文件。csr_data 支持 JSON 字符串或字典变体;后续处理流程与 AddDevice 一致。
| 属性 | 内容 |
|---|---|
| 接口名 | bmc.dev |
| 服务名 | bmc.kepler.devmon |
| 对象路径 | /bmc/dev |
| 方法名 | AddDeviceWithData |
| D-Bus 签名 | 入参 va{sv},出参为空 |
| 首发版本 | 未确认 |
| 废弃状态 | 正常可用 |
参数说明
| 参数名 | 方向 | 类型 | 描述 | 取值范围 |
|---|---|---|---|---|
csr_data | 输入 | Variant (v) | CSR 数据 | 变体内必须是 JSON String 或 Dict;其他类型拒绝 |
connector | 输入 | a{sv} | 连接器上下文 | 与 2.1 节相同,必须包含有效 GroupPosition |
返回值与异常
| 返回值/异常 | 含义 | 触发条件 | 处理建议 |
|---|---|---|---|
| 无返回值 | 请求已完成 | 正常添加或重复位置被跳过 | 检查 ObjectGroup 和日志 |
invalid csr_data type, expected string or dict | 变体类型不支持 | 传入数字、数组、布尔值等 | 将 CSR 编码为紧凑 JSON 字符串或字典 |
| 其他 CSR/驱动异常 | 与 AddDevice 相同 | CSR 校验、拓扑或驱动加载失败 | 参照 2.1 节和第 5 章排查 |
应用场景
- 自动化测试不落盘地注入 CSR。
- 业务组件已经持有 CSR JSON,希望直接动态添加设备。
- 对修改后的 CSR 快速试验,避免反复更新目标文件。
限制条件
- 通过 shell 传长 JSON 时容易受到引号和换行影响,建议先用
jq -c压缩。 - CSR 数据中若缺少
FormatVersion,按5.00处理。 - 三层架构 CSR1 转发时,devmon 会把 CSR 规范化为 JSON 字符串后发送给 hwdiscovery。
调试示例
命令行调试
CSR_FILE=/opt/bmc/sr/example.sr
GROUP_POSITION=03
CSR_JSON=$(jq -c . "$CSR_FILE")
busctl --user call bmc.kepler.devmon /bmc/dev bmc.dev AddDeviceWithData 'va{sv}' s "$CSR_JSON" 3 GroupPosition s "$GROUP_POSITION" SystemId y 1 Slot y 32.3 RemoveDevice
功能说明
按 GroupPosition 卸载设备。devmon 先停止驱动,再注销本位置拥有的设备对象,清理对象数据、拓扑、直挂服务对象、格式版本和 ObjectGroup。三层架构 CSR1 设备会转发给 hwdiscovery 做级联清理。
| 属性 | 内容 |
|---|---|
| 接口名 | bmc.dev |
| 服务名 | bmc.kepler.devmon |
| 对象路径 | /bmc/dev |
| 方法名 | RemoveDevice |
| D-Bus 签名 | 入参 a{sv},出参为空 |
| 首发版本 | 1.2.28 |
| 废弃状态 | 正常可用 |
参数说明
| 参数名 | 方向 | 类型 | 描述 | 取值范围 |
|---|---|---|---|---|
connector | 输入 | a{sv} | 用于定位待卸载设备 | 应包含与添加时一致的 GroupPosition |
GroupPosition | 输入,字典字段 | String 或整数 | 待卸载对象组位置 | 规范化规则与 AddDevice 相同 |
返回值与异常
| 返回值/异常 | 含义 | 触发条件 | 处理建议 |
|---|---|---|---|
| 无返回值 | 卸载流程结束 | 正常卸载;位置不存在;或未提供有效位置而直接返回 | 通过对象树、日志确认是否真的删除 |
| 驱动停止/对象注销日志 | 局部清理异常 | 驱动或对象正在被其他流程使用 | 收集 app.log 和 dump,确认是否残留对象 |
应用场景
- 部件拔出后清理对象和驱动实例。
- 修改 CSR 或驱动前,先卸载旧实例再重新添加。
- 自动化测试结束时恢复环境。
限制条件
- 该方法对“缺少
GroupPosition”采取静默返回,不会抛出参数异常;因此调用方必须自行保证字段存在。 - 不存在的位置通常也不会产生业务异常。
- 卸载与添加使用的
GroupPosition必须完全一致;字符串值不会自动转换大小写或格式。
调试示例
命令行调试
GROUP_POSITION=02
busctl --user call bmc.kepler.devmon /bmc/dev bmc.dev RemoveDevice 'a{sv}' 1 GroupPosition s "$GROUP_POSITION"
# 确认对象组已消失
busctl --user tree bmc.kepler.devmon /bmc/dev/ObjectGroup2.4 ObjectGroup.GetObjects
功能说明
获取指定 owner 在一个对象组中的对象数据。返回位置、对象列表和生命周期 ID。每个对象包含类名、对象名、属性 JSON 和扩展属性 JSON。
| 属性 | 单架构/CSR2 | 三层架构 CSR1 |
|---|---|---|
| 服务名 | bmc.kepler.devmon | bmc.kepler.hwdiscovery |
| 对象路径 | /bmc/dev/ObjectGroup/<Position> | /bmc/kepler/ObjectGroup/<Position> |
| 接口名 | bmc.dev.ObjectGroup | bmc.kepler.ObjectGroup |
| 方法名 | GetObjects | GetObjects |
| D-Bus 签名 | 入参 a{ss}s,出参 sa(ssss)u | 入参 a{ss}s,出参 sa(ssss)u |
| 首发版本 | 1.2.41 | 1.2.41 |
| 废弃状态 | 正常可用 | 正常可用 |
参数说明
| 参数名 | 方向 | 类型 | 描述 | 取值范围 |
|---|---|---|---|---|
context | 输入 | Dict<String, String> (a{ss}) | 资源协作预留上下文 | 调试时可传空字典 0 |
owner | 输入 | String (s) | 请求的对象归属方 | 应从 ObjectGroup 的 Owners 属性中选择 |
Position | 输出 | String | 对象组位置 | 与路径末段一致 |
Objects | 输出 | Array<Tuple<String,String,String,String>> | 对象列表:ClassName、ObjectName、ObjectProps、ObjectExtends | JSON 字符串由调用方解析 |
LifeCycleId | 输出 | U32 | 对象组生命周期标识 | 对象集合发生更新时用于识别版本变化 |
返回值与异常
| 返回值/现象 | 含义 | 触发条件 | 处理建议 |
|---|---|---|---|
Objects 非空 | 找到该 owner 的对象 | owner 匹配且对象已保存 | 解析属性和扩展 JSON |
Objects 为空 | 当前 owner 无对象 | owner 拼写错误、对象尚未发现或该 owner 不拥有数据 | 先读取 Owners,再确认发现完成 |
Unknown object | ObjectGroup 不存在 | 路径选错、设备未添加或已卸载 | 按架构选择正确服务和路径 |
应用场景
- 上层组件读取动态发现对象并构建自身资源模型。
- 比较
LifeCycleId判断是否需要刷新缓存。 - 调试 CSR 解析后的对象名、属性和扩展信息。
限制条件
owner不匹配时不会自动回退到其他 owner。- 单架构与三层架构的服务名、路径和接口不同。
- 返回的属性是 JSON 字符串,不是 D-Bus 字典;脚本需要二次解析。
调试示例
命令行调试
GROUP_POSITION=02
# 单架构/CSR2:先读取 Owners
busctl --user get-property bmc.kepler.devmon /bmc/dev/ObjectGroup/$GROUP_POSITION bmc.dev.ObjectGroup Owners
OWNER=<从Owners中选择一个值>
busctl --user call bmc.kepler.devmon /bmc/dev/ObjectGroup/$GROUP_POSITION bmc.dev.ObjectGroup GetObjects 'a{ss}s' 0 "$OWNER"
# 三层架构 CSR1
busctl --user call bmc.kepler.hwdiscovery /bmc/kepler/ObjectGroup/$GROUP_POSITION bmc.kepler.ObjectGroup GetObjects 'a{ss}s' 0 "$OWNER"2.5 ObjectGroup.GetTopology
功能说明
获取对象组的管理拓扑。单架构接口返回 JSON 字符串;三层架构接口将拓扑字典序列化后放入 D-Bus String 中,因此命令行显示可能包含转义字符序列。
| 属性 | 单架构/CSR2 | 三层架构 CSR1 |
|---|---|---|
| 服务名 | bmc.kepler.devmon | bmc.kepler.hwdiscovery |
| 对象路径 | /bmc/dev/ObjectGroup/<Position> | /bmc/kepler/ObjectGroup/<Position> |
| 接口名 | bmc.dev.ObjectGroup | bmc.kepler.ObjectGroup |
| 方法名 | GetTopology | GetTopology |
| D-Bus 签名 | 入参 a{ss},出参 s | 入参 a{ss},出参 s(二进制序列化内容) |
| 首发版本 | 未确认 | 未确认 |
| 废弃状态 | 正常可用 | 正常可用 |
参数说明
| 参数名 | 方向 | 类型 | 描述 | 取值范围 |
|---|---|---|---|---|
context | 输入 | a{ss} | 资源协作预留上下文 | 调试时传空字典 |
topology | 输出 | String | 对象组拓扑 | 单架构为 JSON;三层架构需要使用框架反序列化能力解析 |
返回值与异常
| 返回值/现象 | 含义 | 触发条件 | 处理建议 |
|---|---|---|---|
{} 或最小拓扑 | 该 CSR 没有有效管理拓扑 | ManagementTopology 省略、映射为空或没有可达节点 | 只需要纯设备对象时可接受;需要总线拓扑时检查 Anchor/Buses |
| 非空拓扑 | 拓扑已建立 | Anchor 与 Connector.Buses 映射成功 | 结合 topology.txt 验证 |
Unknown object | 对象组路径错误 | 架构判断错误或添加失败 | 检查服务和 ObjectGroup 树 |
应用场景
- 上层组件读取总线、芯片和部件之间的层级关系。
- 比对 CSR 预期拓扑与运行时实际拓扑。
- 定位 Anchor、Buses 或对象重命名问题。
限制条件
- 三层架构结果不是可直接阅读的 JSON;不要仅凭
busctl终端显示判定数据损坏。 - 配置管理拓扑时,
ManagementTopology.Anchor必须存在;涉及总线映射时应提供Anchor.Buses。
调试示例
命令行调试
GROUP_POSITION=02
# 单架构/CSR2
busctl --user call bmc.kepler.devmon /bmc/dev/ObjectGroup/$GROUP_POSITION bmc.dev.ObjectGroup GetTopology 'a{ss}' 0
# 三层架构 CSR1
busctl --user call bmc.kepler.hwdiscovery /bmc/kepler/ObjectGroup/$GROUP_POSITION bmc.kepler.ObjectGroup GetTopology 'a{ss}' 02.6 ObjectGroup.GetBinaryObjects(三层架构)
功能说明
获取三层架构 ObjectGroup 的二进制对象数据。与 GetObjects 相比,属性和扩展属性直接序列化为二进制数组,避免 JSON 双重编解码,适合框架内部高效传输。
| 属性 | 内容 |
|---|---|
| 接口名 | bmc.kepler.ObjectGroup |
| 服务名 | bmc.kepler.hwdiscovery |
| 对象路径 | /bmc/kepler/ObjectGroup/<Position> |
| 方法名 | GetBinaryObjects |
| D-Bus 签名 | 入参 a{ss}s,出参 sa(ssayay)u |
| 首发版本 | 1.2.41 |
| 废弃状态 | 正常可用 |
参数说明
| 参数名 | 方向 | 类型 | 描述 | 取值范围 |
|---|---|---|---|---|
context | 输入 | a{ss} | 预留上下文 | 调试时传空字典 |
owner | 输入 | String | 对象 owner | 从 Owners 属性选择 |
Objects | 输出 | a(ssayay) | ClassName、ObjectName、属性二进制数组、扩展属性二进制数组 | 需使用 mc D-Bus 反序列化格式解析 |
返回值与异常
与 GetObjects 相同;owner 不匹配时对象数组为空。
应用场景
- devmon 在三层架构中高效获取 hwdiscovery 分发的对象数据。
- 性能敏感的框架内部对象同步。
限制条件
- 仅三层架构的
bmc.kepler.ObjectGroup提供该方法。 - 二进制数组不是 UTF-8 JSON,普通 shell 不适合做语义解析。
调试示例
命令行调试
GROUP_POSITION=02
OWNER=<从Owners中选择一个值>
busctl --user call bmc.kepler.hwdiscovery /bmc/kepler/ObjectGroup/$GROUP_POSITION bmc.kepler.ObjectGroup GetBinaryObjects 'a{ss}s' 0 "$OWNER"2.7 ObjectGroup 属性
| 属性 | 类型 | 含义 | 调试建议 |
|---|---|---|---|
Position | String | 规范化后的 GroupPosition | 应与对象路径末段一致 |
Owners | String[] | 当前对象组可查询的 owner 列表 | 调用 GetObjects 前先读取 |
OnlineTimestamp | U64 | 相对组件启动时刻的上线时间,单位毫秒 | 用于判断对象组何时创建 |
Slot | U8 | 添加时 Connector 中的槽位号,缺省为 0 | 与实际硬件槽位核对 |
GROUP_POSITION=02
busctl --user get-property bmc.kepler.devmon /bmc/dev/ObjectGroup/$GROUP_POSITION bmc.dev.ObjectGroup Position
busctl --user get-property bmc.kepler.devmon /bmc/dev/ObjectGroup/$GROUP_POSITION bmc.dev.ObjectGroup Owners
busctl --user get-property bmc.kepler.devmon /bmc/dev/ObjectGroup/$GROUP_POSITION bmc.dev.ObjectGroup OnlineTimestamp
busctl --user get-property bmc.kepler.devmon /bmc/dev/ObjectGroup/$GROUP_POSITION bmc.dev.ObjectGroup Slot3. 组件扩展案例
3.1 扩展能力概述
devmon 的主要扩展方式包括:
- 新增设备驱动:实现
driver_abi.h规定的驱动回调并构建动态库。 - 新增 CSR 配置:通过
Unit、Objects、ManagementTopology和 Connector 变量描述设备实例。 - 新增设备类或接口模型:在对应应用的 MDS/schema 中定义类、接口和属性,供 devmon 反射注册。
- 扩展三层架构直挂对象策略:框架开发者可在策略表中增加路由到 hwdiscovery/hwproxy 的类;该修改属于 devmon 核心开发,不属于普通产品配置。
- 扩展调试能力:在
mds/model.json中为芯片或扫描器接口配置 mdbctl 命令元数据。
下面以“新增 Example,Driver 设备驱动并由 CSR 动态加载”为例。
3.2 扩展点说明
| 扩展点 | 位置/入口 | 作用 | 触发时机 |
|---|---|---|---|
| 驱动 ABI | include/devmon/driver_abi.h | 约定构造、初始化、启动、停止和 dump 回调 | 加载 .so 后调用 register_device_driver |
| 驱动库目录 | /opt/bmc/drivers/ | devmon 搜索动态驱动的位置 | 首次解析相应 Compatible 时 |
CSR Unit.Compatible | .sr 文件 | 决定驱动名和候选库名 | AddDevice/自动发现解析 CSR 时 |
CSR Unit.Type | .sr 文件 | 指定设备类;应与驱动表中的 device_name 对应 | 驱动实例化时 |
CSR Objects | .sr 文件 | 定义要注册的对象及属性 | CSR 解析阶段 |
CSR ManagementTopology | .sr 文件 | 定义总线/芯片层级和 Anchor 映射 | 需要管理拓扑时 |
| Connector 字典 | D-Bus 调用或发现流程 | 提供 GroupPosition、SystemId、Slot、Buses 等变量 | 每次添加设备时 |
驱动库命名规则
Unit.Compatible 中的逗号会被替换为下划线。例如:
"Compatible": ["Example,Driver"]对应 DriverName 为 Example_Driver:
| ABI | 搜索顺序 |
|---|---|
| ABI v2 | /opt/bmc/drivers/libExample_Driver.so |
| ABI v1 | /opt/bmc/drivers/libCsr1Example_Driver.so,失败后回退 /opt/bmc/drivers/libExample_Driver.so |
3.3 二次开发指导
步骤一:实现驱动回调
驱动至少实现构造、初始化、启动和停止回调;需要一键日志内容时再实现 dump。
| 回调 | 作用 | 返回要求 |
|---|---|---|
ctor(service, object_name) | 创建一个设备驱动实例 | 成功返回非空 driver_handle_t |
init(handle, csr_object, connector) | 读取 CSR 对象和 Connector,初始化实例 | 成功返回 STATUS_OK |
start(handle) | 启动设备访问、扫描或订阅 | 成功返回 STATUS_OK |
stop(handle) | 停止任务并释放运行时资源 | 成功返回 STATUS_OK |
dump(handle) | 返回诊断文本 | 返回指针由驱动持有,调用方不得释放;同线程下一次 dump 前必须保持有效 |
driver_handle_t虽然是void *,但实际对象必须满足 devmon/引擎对驱动实例的使用约定。不要把任意裸数据指针当作完整设备实例返回。
步骤二:导出驱动表
下面代码展示 ABI 注册骨架。回调实现由具体设备驱动提供。
#include <devmon/driver_abi.h>
extern driver_handle_t example_ctor(void* service, const char* object_name);
extern status_t example_init(driver_handle_t handle, void* csr_object, void* connector);
extern status_t example_start(driver_handle_t handle);
extern status_t example_stop(driver_handle_t handle);
extern const char* example_dump(driver_handle_t handle);
static device_driver_t kDrivers[] = {
{
"ExampleDevice",
example_ctor,
example_init,
example_start,
example_stop,
example_dump,
},
};
extern "C" status_t register_device_driver(device_driver_t** drivers, uint8_t* count)
{
if (drivers == nullptr || count == nullptr) {
return STATUS_INVALID_ARG;
}
*drivers = kDrivers;
*count = static_cast<uint8_t>(sizeof(kDrivers) / sizeof(kDrivers[0]));
return STATUS_OK;
}状态码定义如下:
| 状态码 | 数值 | 含义 |
|---|---|---|
STATUS_OK | 0 | 成功 |
STATUS_ERROR | 1 | 通用错误 |
STATUS_NOT_FOUND | 2 | 目标不存在 |
STATUS_INVALID_ARG | 3 | 参数非法 |
STATUS_NOT_IMPLEMENTED | 4 | 功能未实现 |
STATUS_TIMEOUT | 5 | 操作超时 |
STATUS_BUSY | 6 | 资源忙 |
STATUS_NO_MEMORY | 7 | 内存不足 |
步骤三:编写 CSR
{
"FormatVersion": "5.00",
"Unit": {
"Type": "ExampleDevice",
"Name": "ExampleDevice_1",
"Compatible": [
"Example,Driver"
]
},
"Objects": {
"ExampleDevice_1": {
"SystemId": "${SystemId}",
"Slot": "${Slot}"
}
},
"ManagementTopology": {
"Anchor": {
"Buses": []
}
}
}配置要点:
Unit.Type应与驱动表中的device_name一致。Unit.Name必须非空,并应在Objects中存在同名对象。Unit.Compatible决定动态库名;可配置多个候选,devmon 按顺序尝试。GroupPosition不写在 CSR 中,而是在 Connector/D-Bus 调用中传入。- 不需要管理拓扑的纯设备 CSR 可以省略整个
ManagementTopology;一旦配置非空管理拓扑,必须包含Anchor。涉及总线映射时应配置Anchor.Buses,并在 Connector 中提供对应Buses。
步骤四:构建并部署驱动
使用驱动工程自身的构建系统生成共享库,并部署到 devmon 配置的驱动目录:
install -m 0755 libExample_Driver.so /opt/bmc/drivers/libExample_Driver.so部署前检查:
# 必须导出 C 符号
readelf -Ws /opt/bmc/drivers/libExample_Driver.so | grep ' register_device_driver
#### 步骤五:添加设备并验证
```bash
jq empty /opt/bmc/sr/example.sr
busctl --user call bmc.kepler.devmon /bmc/dev bmc.dev AddDevice 'sa{sv}' /opt/bmc/sr/example.sr 3 GroupPosition s 0E SystemId y 1 Slot y 14
busctl --user tree bmc.kepler.devmon /bmc/dev/ObjectGroup
busctl --user introspect bmc.kepler.devmon /bmc/dev/ObjectGroup/0E bmc.dev.ObjectGroup
grep -E 'Example_Driver|AddDevice done|Failed to load driver|Driver not found' /var/log/app.log | tail -50步骤六:卸载并确认清理
busctl --user call bmc.kepler.devmon /bmc/dev bmc.dev RemoveDevice 'a{sv}' 1 GroupPosition s 0E
! busctl --user tree bmc.kepler.devmon /bmc/dev/ObjectGroup | grep -q '/0E
#### 示例代码验证方法
1. `readelf` 能找到全局符号 `register_device_driver`。
2. `ldd` 不出现 `not found`。
3. `AddDevice` 返回码为 0,日志出现 `Trying to load driver from`、`Loaded driver` 和 `AddDevice done pos=0E`。
4. `/bmc/dev/ObjectGroup/0E` 存在,属性和 owner 符合 CSR 预期。
5. 一键日志中的 `drivers_load_info.csv` 显示该驱动 `Load_status=success`。
6. `RemoveDevice` 后 ObjectGroup 和本位置设备对象消失,驱动 `stop` 已执行。
#### 注意事项
- 驱动库文件名、`Compatible` 归一化名称和 ABI 必须一致。
- `register_device_driver` 必须使用 `extern "C"`,避免 C++ 名字改编导致 `dlsym` 失败。
- `register_device_driver` 返回的驱动表及其中字符串、函数指针必须在库生命周期内持续有效。
- `dump` 返回的是借用指针,调用方会立即复制;驱动不得返回已经释放的临时字符串地址。
- 驱动的 `stop` 应可重复、安全地终止线程、定时器和 I/O,避免卸载残留。
- 多实例驱动不得用未加锁的全局可变状态保存单个设备上下文。
- 修改驱动后应先卸载旧设备;已缓存的动态库通常需要重启组件或使用全新版本/环境才能确保重新加载。
- 单架构始终使用 ABI v2;不要因为 CSR 的 `FormatVersion` 小于 5 就部署只有 `libCsr1*.so` 的驱动。
## 4. 日志说明
### 4.1 一键日志收集
系统一键日志通常把运行日志放在 `LogDump`,把组件 dump 放在 `AppDump/<服务名>`。不同版本的收集器可能额外增加实例目录,定位时应优先按文件名搜索。
| 文件路径/文件名 | 产生方 | 内容说明 |
| :--- | :--- | :--- |
| `LogDump/app.log` | 系统日志收集 | devmon、hwdiscovery、hwproxy 的运行日志;目标机实时文件通常为 `/var/log/app.log` |
| `AppDump/devmon/topology.txt` | devmon | 当前设备拓扑和对象层级 |
| `AppDump/devmon/snapshot.csv` | devmon | Scanner/Accessor 运行快照,包括周期、状态、成功/失败计数、值和错误信息 |
| `AppDump/devmon/drivers_load_info.csv` | devmon | 驱动库加载状态、耗时、设备数和错误信息 |
| `AppDump/devmon/chips_access_statistic.csv` | devmon | 芯片读写成功/失败次数、访问耗时和错误记录;Release 构建可能不生成 |
| `AppDump/hwproxy/topology.txt` | hwproxy | 三层架构硬件代理对象拓扑 |
| `AppDump/hwproxy/snapshot.csv` | hwproxy | 三层架构 Accessor/Scanner 快照 |
| `AppDump/hwproxy/smc_dfx_info.txt` | hwproxy | SmcDfxInfo 配置和最近数据 |
| `AppDump/hwproxy/chips_access_statistic.csv` | hwproxy | 三层架构芯片访问统计;Release 构建可能不生成 |
| `AppDump/hwdiscovery/connectors.txt` | hwdiscovery | Connector 树、位置、源路径、在位状态、识别方式等 |
| `AppDump/hwdiscovery/root.sr` | hwdiscovery | 当前使用的根 CSR;源文件不可用时该文件可能缺失并记录告警 |
| `AppDump/hwdiscovery/platform.sr` | hwdiscovery | 当前平台 CSR |
| `AppDump/hwdiscovery/<Connector>.sr` / `.bin` | hwdiscovery | 各 Connector 的实际 CSR/二进制源文件副本 |
| `AppDump/hwdiscovery/<Connector>_soft.sr` | hwdiscovery | Connector 关联的软件 CSR(存在时) |
| `AppDump/hwdiscovery/<Connector>.bin` | hwdiscovery | 满足条件的 EEPROM 备份,单次最多复制 65 个 |
| `/var/log/box_info/basic_info`、`/var/log/box_info/JBOG1/cpld_info` | devmon 特定对象 | JBOG 相关运行信息;仅对应对象和场景存在时生成 |
快速查找:
```bash
find dump_info -type f \( -name app.log -o -name topology.txt -o -name snapshot.csv -o -name drivers_load_info.csv -o -name chips_access_statistic.csv -o -name connectors.txt -o -name smc_dfx_info.txt \) -print4.2 关键日志信息
| 日志片段 | 日志级别 | 含义解读 | 建议处理动作 |
|---|---|---|---|
architecture mode: single | INFO | 当前为单架构 | 使用 /bmc/dev/ObjectGroup,驱动按 ABI v2 检查 |
architecture mode: three-layer | INFO | 当前为三层架构 | 同时检查 devmon、hwdiscovery、hwproxy |
Service: ... initialization completed | INFO | 服务配置和基础初始化完成 | 继续确认 root 对象及启动日志 |
devmon root object created at /bmc/dev | INFO | devmon 根对象已注册 | 可执行 busctl introspect |
Starting device manager service: ... | INFO | devmon 服务进入启动阶段 | 无 |
hwproxy root object created and registered | INFO | hwproxy 根对象完成 | 三层架构硬件代理可用 |
hwproxy service started | INFO | hwproxy 已启动 | 无 |
Starting discovery service: ... | INFO | hwdiscovery 已启动 | 等待异步 CSR 全量发现完成 |
devmon started | INFO | 应用启动完成 | 无 |
AddDevice forward to hwdiscovery pos=... | INFO | CSR1 请求被转发到发现层 | 到 hwdiscovery 日志继续跟踪 |
RemoveDevice forward to hwdiscovery pos=... | INFO | CSR1 卸载被转发 | 检查子 position 是否级联清理 |
position: ..., device already exists, skip add device | WARN | 同一位置已存在,重复添加被忽略 | 先 RemoveDevice,或使用新 GroupPosition |
Trying to load driver from: ... | INFO | 正在尝试加载候选动态库 | 核对库路径和 ABI |
Loaded driver ...@abi_v1/abi_v2 from ... | INFO | 驱动加载并缓存成功 | 继续确认 init/start 和对象创建 |
AddDevice done pos=... | NOTICE | 本地添加流程完成 | 检查 ObjectGroup 和对象属性 |
Failed to read csr file: ... | ERROR/异常 | CSR 文件无法读取 | 检查路径、权限和部署 |
invalid csr_data type, expected string or dict | ERROR/异常 | AddDeviceWithData 的变体类型错误 | 改传 JSON 字符串或字典 |
Connector Position is not initialized | ERROR/异常 | 缺少有效 GroupPosition | 修改调用参数 |
failed to parse FormatVersion ... using default 5 | WARN | FormatVersion 非法,已回退 5.00 | 修正版本格式,避免路由与预期不一致 |
CSR Unit Type is empty | ERROR/异常 | Unit.Type 为空 | 补齐设备类 |
CSR Unit Name is empty | ERROR/异常 | Unit.Name 为空 | 补齐实例名 |
CSR Unit Compatible is empty | ERROR/异常 | Unit.Compatible 为空 | 补齐驱动候选 |
CSR Objects is empty | ERROR/异常 | CSR 没有对象定义 | 补齐 Objects |
unit object not found in csr | ERROR | Unit.Name 对应对象不存在 | 确保 Objects 含同名键 |
CSR ManagementTopology missing Anchor | ERROR/异常 | 非空管理拓扑缺少 Anchor | 配置 Anchor.Buses 或删除管理拓扑 |
Failed to load driver: ... | ERROR/异常 | dlopen 失败 | 用 ldd、架构、权限和库名排查 |
Failed to get export_device_driver function: ... | ERROR/异常 | 缺少 register_device_driver 导出符号 | 检查 extern "C" 和 readelf -Ws |
Failed to get device driver manager: ... | ERROR/异常 | 注册函数返回非 0 | 修正注册函数参数和返回值 |
Driver not found: ... | ERROR/异常 | 所有 Compatible 候选都失败 | 核对 Compatible、库名和 ABI |
create devices object failed / failed to create device | ERROR | 驱动实例或对象注册失败 | 查看前序驱动/CSR日志和异常堆栈 |
root topology object missing, dumping aborted | ERROR | devmon 拓扑根对象缺失,访问统计无法导出 | 检查启动完整性和异常重启 |
dump artifact unavailable: ... | WARN | 一键日志找不到某个 CSR/备份源文件 | 核对源路径;不一定代表运行故障 |
Drivers load info dumped to ... | INFO | 驱动加载记录导出成功 | 查看 CSV |
connectors dump success | NOTICE | Connector dump 完成 | 查看 connectors.txt 和 CSR 副本 |
默认日志级别为 notice。三层架构中 default、hwdiscovery、hwproxy 日志域均默认使用 notice。
4.3 调试日志与南向追踪
进入 mdbctl:
mdbctl
% lsmc
% attach hwproxy
% lscmd常用命令:
# 设置调试级别和输出类型;具体模块先通过 lsmc 确认
% dloglevel debug 2
% dlogtype file
# 芯片访问追踪
% tracechip <ChipObjectName> start
% tracechip <ChipObjectName> stop
# Scanner 防抖追踪
% tracedebounce <ScannerObjectName> start
% tracedebounce <ScannerObjectName> stop读取块设备/EEPROM 的示例:
busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Eeprom/<ObjectName> bmc.kepler.Chip.BlockIO Read 'a{ss}uu' 0 <Offset> <Length>正常响应类型为 ay,后跟读取长度和二进制数据。该命令仅适用于目标对象确实暴露 bmc.kepler.Chip.BlockIO 接口的三层架构环境。
5. 问题定界指南
5.1 典型问题定界
| 现象描述 | 是否为本组件问题 | 判断依据 | 关键证据收集方法 |
|---|---|---|---|
bmc.kepler.devmon 服务不存在 | 通常是部署、依赖或启动问题,可能属于 devmon 集成问题 | busctl --user list 无服务名,systemd 状态异常 | systemctl status devmon、journalctl -u devmon、/var/log/app.log |
AddDevice 报 Connector Position is not initialized | 是,属于调用参数问题 | 当前接口只从 GroupPosition 生成对象组位置 | 保存完整 busctl 命令和 D-Bus 异常 |
| AddDevice 无输出,但对象已创建 | 否,属于 void 方法正常表现 | 方法没有返回参数,ObjectGroup 和成功日志存在 | echo $?、对象树、AddDevice done |
| 重复添加后对象未刷新 | 否,属于接口幂等/防重复行为 | 日志出现 device already exists, skip add device | 搜索该日志;先卸载再加载 |
| CSR 校验错误 | 通常是 CSR 配置问题 | Unit/Objects/Anchor 日志明确指出缺失字段 | 原始 CSR、jq 结果、关键错误日志 |
Failed to load driver | 可能是驱动包或依赖问题 | dlopen 失败,未进入驱动注册 | 驱动路径、file、ldd、readelf、drivers_load_info.csv |
Failed to get export_device_driver function | 是驱动 ABI 接口问题 | 动态库缺少导出符号 | readelf -Ws <so> |
GetObjects 返回空数组 | 不一定 | owner 不匹配、发现未完成或 CSR 没有该 owner 数据 | 读取 Owners、connectors.txt、ObjectGroup 属性和 app.log |
Unknown object /bmc/dev/ObjectGroup/... | 不一定 | 可能选错单架构/三层架构路径,或设备添加失败 | 查看架构日志和两个 ObjectGroup 根路径 |
| 三层架构 CSR1 不加载 | 可能是发现链路问题 | devmon 已转发,但 hwdiscovery/hwproxy 未就绪或 CSR1 驱动缺失 | 三个服务状态、转发日志、connectors.txt、ABI v1 驱动 |
| 对象存在但芯片读取失败 | 可能属于驱动、总线或硬件问题 | 对象注册成功,不代表底层总线可访问 | tracechip、chips_access_statistic.csv、硬件代理日志 |
一键日志没有 chips_access_statistic.csv | 不一定 | Release 构建可不输出该统计 | 核对构建类型和其他 dump 文件 |
| devmon 周期性重启 | 是或依赖问题 | systemd 配置 Restart=always,崩溃后会自动拉起 | NRestarts、coredump、journal、MemoryCurrent、依赖版本 |
| 仅某个位置卸载后其他共享总线对象消失 | 可能是对象归属/版本问题 | 卸载逻辑应只注销本 position 拥有的对象 | 记录卸载前后对象树、版本、app.log 和 CSR |
5.2 错误码速查表
D-Bus/解析错误
| 错误/日志 | 含义 | 可能原因 | 排查建议 |
|---|---|---|---|
org.freedesktop.DBus.Error.ServiceUnknown | D-Bus 服务不存在 | devmon 未启动、服务未注册或环境变量/总线不正确 | 检查 systemd、用户 D-Bus 会话和服务列表 |
org.freedesktop.DBus.Error.UnknownObject | 对象路径不存在 | 路径选错、设备未加载、已卸载 | 按架构重新 busctl tree |
org.freedesktop.DBus.Error.UnknownInterface | 接口名错误 | 混用了 bmc.dev.ObjectGroup 与 bmc.kepler.ObjectGroup | 先 busctl introspect |
InvalidArgs / 签名不匹配 | D-Bus 参数格式错误 | 字典数量、Variant 类型或签名不正确 | 对照第 2 章逐项检查 |
Connector Position is not initialized | 无有效位置 | GroupPosition 缺失/空 | 传 GroupPosition |
invalid csr_data type... | CSR 变体类型错误 | AddDeviceWithData 传了非 string/dict | 用 s "$CSR_JSON" |
CSR Unit ... is empty | Unit 字段为空 | CSR 不完整 | 补齐 Unit |
CSR Objects is empty | Objects 为空 | CSR 不完整 | 添加对象定义 |
CSR ManagementTopology missing Anchor | 拓扑缺 Anchor | 非空拓扑不完整 | 补 Anchor/Buses |
Driver not found | 驱动候选全部失败 | Compatible、文件名、ABI 或部署错误 | 依次核对候选库 |
驱动 ABI 状态码
| 错误码 | 含义 | 可能原因 | 排查建议 |
|---|---|---|---|
0 STATUS_OK | 成功 | 正常 | 无 |
1 STATUS_ERROR | 通用错误 | 驱动内部失败 | 查看驱动日志和 dump |
2 STATUS_NOT_FOUND | 目标不存在 | 芯片、通道或资源不存在 | 核对 CSR 和硬件在位 |
3 STATUS_INVALID_ARG | 参数非法 | CSR/Connector 值不支持 | 打印输入并校验类型/范围 |
4 STATUS_NOT_IMPLEMENTED | 未实现 | 驱动不支持该操作 | 使用替代能力或补充实现 |
5 STATUS_TIMEOUT | 超时 | 总线无响应、设备忙 | tracechip,检查链路和时序 |
6 STATUS_BUSY | 资源忙 | 并发访问或状态机未就绪 | 降低并发、稍后重试 |
7 STATUS_NO_MEMORY | 内存不足 | 分配失败或泄漏 | 检查 MemoryCurrent、coredump 和长期增长 |
5.3 调试方法
开启调试日志
先确认当前服务和日志域,再用 mdbctl 调整级别:
mdbctl
% lsmc
% attach devmon
% dloglevel debug 2
% dlogtype file三层架构需要分别对 devmon、hwdiscovery、hwproxy 检查或设置。定位完成后恢复默认级别,避免长期产生大量日志。
分层排查步骤
1. 确认进程和资源限制
systemctl status devmon --no-pager
systemctl show devmon -p ActiveState -p SubState -p NRestarts -p MemoryCurrent -p MemoryMax
journalctl -u devmon -b --no-pager | tail -200目标 service 配置为 User=root、Restart=always、MemoryMax=150M,工作目录 /opt/bmc/apps/devmon,执行文件 /opt/bmc/apps/devmon/devmon。
2. 确认 D-Bus 服务和架构
busctl --user list | grep -E 'bmc\.kepler\.(devmon|hwdiscovery|hwproxy)'
grep -E 'architecture mode:|devmon started|Starting discovery service|hwproxy service started' /var/log/app.log | tail -503. 确认根接口
busctl --user introspect bmc.kepler.devmon /bmc/dev bmc.dev应至少看到 AddDevice、AddDeviceWithData 和 RemoveDevice。
4. 校验 CSR
CSR_FILE=/opt/bmc/sr/example.sr
jq empty "$CSR_FILE"
jq '{FormatVersion, Unit, ObjectNames:(.Objects|keys), ManagementTopology}' "$CSR_FILE"检查:
Unit.Type、Unit.Name、Unit.Compatible非空;Objects非空,且含Unit.Name对应对象;- 配置了
ManagementTopology时含Anchor; - 需要总线映射时
Anchor.Buses和 Connector 的Buses数量/顺序匹配; FormatVersion与部署驱动 ABI 一致。
5. 校验驱动
DRIVER=/opt/bmc/drivers/libExample_Driver.so
file "$DRIVER"
readelf -Ws "$DRIVER" | grep ' register_device_driver
##### 6. 跟踪一次 AddDevice
```bash
MARK=$(date '+%Y-%m-%d %H:%M:%S')
# 执行第 2 章命令后:
tail -n 500 /var/log/app.log | grep -E 'AddDevice|GroupPosition|FormatVersion|driver|CSR|position:'判断顺序:参数规范化 → FormatVersion 路由 → CSR 校验 → 驱动加载 → 对象创建 → ObjectGroup → 成功日志。
7. 检查对象组
# 单架构/CSR2
busctl --user tree bmc.kepler.devmon /bmc/dev/ObjectGroup
# 三层架构 CSR1
busctl --user tree bmc.kepler.hwdiscovery /bmc/kepler/ObjectGroup若路径存在但 GetObjects 为空,先读 Owners;若路径根本不存在,回到 CSR/驱动/转发日志。
8. 检查一键日志证据
find dump_info -type f -name drivers_load_info.csv -exec sh -c 'echo "===== $1 ====="; cat "$1"' sh {} \;
find dump_info -type f -name connectors.txt -exec sh -c 'echo "===== $1 ====="; sed -n "1,240p" "$1"' sh {} \;9. 检查硬件访问
- 在 mdbctl 中
attach hwproxy。 - 使用
tracechip追踪目标芯片。 - 对 Scanner 使用
tracedebounce。 - 查看
chips_access_statistic.csv的失败计数和 Error_Recording。 - 对暴露 BlockIO 的对象执行
Read,区分“对象创建成功”与“底层读写成功”。
复现问题方法
下面流程可复现和隔离“最小 CSR 加载失败”问题:
- 准备一个只包含单个
Unit和同名Objects的 CSR,使用FormatVersion=5.00,并部署匹配的 ABI v2 驱动。 - 选择未使用的
GroupPosition,如EE。 - 记录调用前
systemctl show、D-Bus 对象树和 app.log 末尾。 - 调用
AddDevice。 - 检查返回码、驱动加载日志和
/bmc/dev/ObjectGroup/EE。 - 调用
GetObjects/GetTopology,保存完整响应。 - 调用
RemoveDevice,确认对象清理。
预期现象:驱动加载成功、出现 AddDevice done pos=EE、ObjectGroup 可查询,卸载后路径消失。若最小 CSR 成功而业务 CSR 失败,问题主要落在业务 CSR、目标驱动或拓扑映射;若最小 CSR 也失败,优先检查组件部署、ABI 和依赖环境。
6. 常见问题解答
Q1:Connector 里传了 Position,为什么仍报位置未初始化?
- 问题描述:旧示例使用
Position,当前代码抛出Connector Position is not initialized。 - 一句话答案:当前动态添加/删除接口必须传
GroupPosition。 - 根因说明:源码从
GroupPosition生成对象组位置,Position只是其他业务字段,不能替代。 - 解决方案:把调用参数改为
GroupPosition s <value>。 - 规避方案:所有新脚本统一使用本文命令模板。
- 适用版本:devmon 1.2.94。
Q2:数值 GroupPosition 最终会变成什么?
- 问题描述:调用传整数后,对象路径不是十进制数字。
- 一句话答案:整数会转为大写十六进制,至少 2 位并补成偶数长度。
- 根因说明:位置用于层级拼接和对象组命名,需要稳定的十六进制表示。
- 解决方案:例如
1→01、15→0F、256→0100;希望完全控制格式时直接传字符串。 - 规避方案:添加和删除时使用同一种表示。
- 适用版本:devmon 1.2.94。
Q3:同一 GroupPosition 再次 AddDevice 会覆盖旧设备吗?
- 问题描述:修改 CSR 后重复调用,运行对象没有变化。
- 一句话答案:不会覆盖,重复位置会直接跳过。
- 根因说明:devmon 在解析和创建前检查 position 是否已存在,防止重复实例。
- 解决方案:先
RemoveDevice,再重新AddDevice。 - 规避方案:更新流程显式执行卸载—确认清理—重新加载。
- 适用版本:devmon 1.2.94。
Q4:如何判断当前应使用哪个 ObjectGroup 路径?
- 问题描述:访问
/bmc/dev/ObjectGroup或/bmc/kepler/ObjectGroup时出现 UnknownObject。 - 一句话答案:单架构/CSR2 使用前者,三层架构 CSR1 使用后者。
- 根因说明:三层架构把旧格式 CSR 的发现结果放在 hwdiscovery 服务。
- 解决方案:查看
architecture mode和 CSRFormatVersion,再执行对应busctl tree。 - 规避方案:脚本先探测两个服务和根路径。
- 适用版本:支持 unidev 的 devmon 版本,本文以 1.2.94 为准。
附录
附录 A 修订记录
| 版本 | 日期 | 修订人 | 修订内容 |
|---|---|---|---|
| 1.2.94 | 2026-08-24 | 创建 devmon 组件说明,补充组件概述、D-Bus API、驱动/CSR 扩展、日志、问题定界和 FAQ |
不应存在 “not found” 依赖
ldd /opt/bmc/drivers/libExample_Driver.so
#### 步骤五:添加设备并验证
__BACKTICK_PLACEHOLDER_307__
#### 步骤六:卸载并确认清理
__BACKTICK_PLACEHOLDER_308__
#### 示例代码验证方法
1. __BACKTICK_PLACEHOLDER_309__ 能找到全局符号 __BACKTICK_PLACEHOLDER_310__。
2. __BACKTICK_PLACEHOLDER_311__ 不出现 __BACKTICK_PLACEHOLDER_312__。
3. __BACKTICK_PLACEHOLDER_313__ 返回码为 0,日志出现 __BACKTICK_PLACEHOLDER_314__、__BACKTICK_PLACEHOLDER_315__ 和 __BACKTICK_PLACEHOLDER_316__。
4. __BACKTICK_PLACEHOLDER_317__ 存在,属性和 owner 符合 CSR 预期。
5. 一键日志中的 __BACKTICK_PLACEHOLDER_318__ 显示该驱动 __BACKTICK_PLACEHOLDER_319__。
6. __BACKTICK_PLACEHOLDER_320__ 后 ObjectGroup 和本位置设备对象消失,驱动 __BACKTICK_PLACEHOLDER_321__ 已执行。
#### 注意事项
- 驱动库文件名、__BACKTICK_PLACEHOLDER_322__ 归一化名称和 ABI 必须一致。
- __BACKTICK_PLACEHOLDER_323__ 必须使用 __BACKTICK_PLACEHOLDER_324__,避免 C++ 名字改编导致 __BACKTICK_PLACEHOLDER_325__ 失败。
- __BACKTICK_PLACEHOLDER_326__ 返回的驱动表及其中字符串、函数指针必须在库生命周期内持续有效。
- __BACKTICK_PLACEHOLDER_327__ 返回的是借用指针,调用方会立即复制;驱动不得返回已经释放的临时字符串地址。
- 驱动的 __BACKTICK_PLACEHOLDER_328__ 应可重复、安全地终止线程、定时器和 I/O,避免卸载残留。
- 多实例驱动不得用未加锁的全局可变状态保存单个设备上下文。
- 修改驱动后应先卸载旧设备;已缓存的动态库通常需要重启组件或使用全新版本/环境才能确保重新加载。
- 单架构始终使用 ABI v2;不要因为 CSR 的 __BACKTICK_PLACEHOLDER_329__ 小于 5 就部署只有 __BACKTICK_PLACEHOLDER_330__ 的驱动。
## 4. 日志说明
### 4.1 一键日志收集
系统一键日志通常把运行日志放在 __BACKTICK_PLACEHOLDER_331__,把组件 dump 放在 __BACKTICK_PLACEHOLDER_332__。不同版本的收集器可能额外增加实例目录,定位时应优先按文件名搜索。
| 文件路径/文件名 | 产生方 | 内容说明 |
| :--- | :--- | :--- |
| __BACKTICK_PLACEHOLDER_333__ | 系统日志收集 | devmon、hwdiscovery、hwproxy 的运行日志;目标机实时文件通常为 __BACKTICK_PLACEHOLDER_334__ |
| __BACKTICK_PLACEHOLDER_335__ | devmon | 当前设备拓扑和对象层级 |
| __BACKTICK_PLACEHOLDER_336__ | devmon | Scanner/Accessor 运行快照,包括周期、状态、成功/失败计数、值和错误信息 |
| __BACKTICK_PLACEHOLDER_337__ | devmon | 驱动库加载状态、耗时、设备数和错误信息 |
| __BACKTICK_PLACEHOLDER_338__ | devmon | 芯片读写成功/失败次数、访问耗时和错误记录;Release 构建可能不生成 |
| __BACKTICK_PLACEHOLDER_339__ | hwproxy | 三层架构硬件代理对象拓扑 |
| __BACKTICK_PLACEHOLDER_340__ | hwproxy | 三层架构 Accessor/Scanner 快照 |
| __BACKTICK_PLACEHOLDER_341__ | hwproxy | SmcDfxInfo 配置和最近数据 |
| __BACKTICK_PLACEHOLDER_342__ | hwproxy | 三层架构芯片访问统计;Release 构建可能不生成 |
| __BACKTICK_PLACEHOLDER_343__ | hwdiscovery | Connector 树、位置、源路径、在位状态、识别方式等 |
| __BACKTICK_PLACEHOLDER_344__ | hwdiscovery | 当前使用的根 CSR;源文件不可用时该文件可能缺失并记录告警 |
| __BACKTICK_PLACEHOLDER_345__ | hwdiscovery | 当前平台 CSR |
| __BACKTICK_PLACEHOLDER_346__ / __BACKTICK_PLACEHOLDER_347__ | hwdiscovery | 各 Connector 的实际 CSR/二进制源文件副本 |
| __BACKTICK_PLACEHOLDER_348__ | hwdiscovery | Connector 关联的软件 CSR(存在时) |
| __BACKTICK_PLACEHOLDER_349__ | hwdiscovery | 满足条件的 EEPROM 备份,单次最多复制 65 个 |
| __BACKTICK_PLACEHOLDER_350__、__BACKTICK_PLACEHOLDER_351__ | devmon 特定对象 | JBOG 相关运行信息;仅对应对象和场景存在时生成 |
快速查找:
__BACKTICK_PLACEHOLDER_352__
### 4.2 关键日志信息
| 日志片段 | 日志级别 | 含义解读 | 建议处理动作 |
| :--- | :--- | :--- | :--- |
| __BACKTICK_PLACEHOLDER_353__ | INFO | 当前为单架构 | 使用 __BACKTICK_PLACEHOLDER_354__,驱动按 ABI v2 检查 |
| __BACKTICK_PLACEHOLDER_355__ | INFO | 当前为三层架构 | 同时检查 devmon、hwdiscovery、hwproxy |
| __BACKTICK_PLACEHOLDER_356__ | INFO | 服务配置和基础初始化完成 | 继续确认 root 对象及启动日志 |
| __BACKTICK_PLACEHOLDER_357__ | INFO | devmon 根对象已注册 | 可执行 __BACKTICK_PLACEHOLDER_358__ |
| __BACKTICK_PLACEHOLDER_359__ | INFO | devmon 服务进入启动阶段 | 无 |
| __BACKTICK_PLACEHOLDER_360__ | INFO | hwproxy 根对象完成 | 三层架构硬件代理可用 |
| __BACKTICK_PLACEHOLDER_361__ | INFO | hwproxy 已启动 | 无 |
| __BACKTICK_PLACEHOLDER_362__ | INFO | hwdiscovery 已启动 | 等待异步 CSR 全量发现完成 |
| __BACKTICK_PLACEHOLDER_363__ | INFO | 应用启动完成 | 无 |
| __BACKTICK_PLACEHOLDER_364__ | INFO | CSR1 请求被转发到发现层 | 到 hwdiscovery 日志继续跟踪 |
| __BACKTICK_PLACEHOLDER_365__ | INFO | CSR1 卸载被转发 | 检查子 position 是否级联清理 |
| __BACKTICK_PLACEHOLDER_366__ | WARN | 同一位置已存在,重复添加被忽略 | 先 RemoveDevice,或使用新 GroupPosition |
| __BACKTICK_PLACEHOLDER_367__ | INFO | 正在尝试加载候选动态库 | 核对库路径和 ABI |
| __BACKTICK_PLACEHOLDER_368__ | INFO | 驱动加载并缓存成功 | 继续确认 init/start 和对象创建 |
| __BACKTICK_PLACEHOLDER_369__ | NOTICE | 本地添加流程完成 | 检查 ObjectGroup 和对象属性 |
| __BACKTICK_PLACEHOLDER_370__ | ERROR/异常 | CSR 文件无法读取 | 检查路径、权限和部署 |
| __BACKTICK_PLACEHOLDER_371__ | ERROR/异常 | AddDeviceWithData 的变体类型错误 | 改传 JSON 字符串或字典 |
| __BACKTICK_PLACEHOLDER_372__ | ERROR/异常 | 缺少有效 GroupPosition | 修改调用参数 |
| __BACKTICK_PLACEHOLDER_373__ | WARN | FormatVersion 非法,已回退 5.00 | 修正版本格式,避免路由与预期不一致 |
| __BACKTICK_PLACEHOLDER_374__ | ERROR/异常 | __BACKTICK_PLACEHOLDER_375__ 为空 | 补齐设备类 |
| __BACKTICK_PLACEHOLDER_376__ | ERROR/异常 | __BACKTICK_PLACEHOLDER_377__ 为空 | 补齐实例名 |
| __BACKTICK_PLACEHOLDER_378__ | ERROR/异常 | __BACKTICK_PLACEHOLDER_379__ 为空 | 补齐驱动候选 |
| __BACKTICK_PLACEHOLDER_380__ | ERROR/异常 | CSR 没有对象定义 | 补齐 Objects |
| __BACKTICK_PLACEHOLDER_381__ | ERROR | __BACKTICK_PLACEHOLDER_382__ 对应对象不存在 | 确保 Objects 含同名键 |
| __BACKTICK_PLACEHOLDER_383__ | ERROR/异常 | 非空管理拓扑缺少 Anchor | 配置 __BACKTICK_PLACEHOLDER_384__ 或删除管理拓扑 |
| __BACKTICK_PLACEHOLDER_385__ | ERROR/异常 | __BACKTICK_PLACEHOLDER_386__ 失败 | 用 __BACKTICK_PLACEHOLDER_387__、架构、权限和库名排查 |
| __BACKTICK_PLACEHOLDER_388__ | ERROR/异常 | 缺少 __BACKTICK_PLACEHOLDER_389__ 导出符号 | 检查 __BACKTICK_PLACEHOLDER_390__ 和 __BACKTICK_PLACEHOLDER_391__ |
| __BACKTICK_PLACEHOLDER_392__ | ERROR/异常 | 注册函数返回非 0 | 修正注册函数参数和返回值 |
| __BACKTICK_PLACEHOLDER_393__ | ERROR/异常 | 所有 Compatible 候选都失败 | 核对 Compatible、库名和 ABI |
| __BACKTICK_PLACEHOLDER_394__ / __BACKTICK_PLACEHOLDER_395__ | ERROR | 驱动实例或对象注册失败 | 查看前序驱动/CSR日志和异常堆栈 |
| __BACKTICK_PLACEHOLDER_396__ | ERROR | devmon 拓扑根对象缺失,访问统计无法导出 | 检查启动完整性和异常重启 |
| __BACKTICK_PLACEHOLDER_397__ | WARN | 一键日志找不到某个 CSR/备份源文件 | 核对源路径;不一定代表运行故障 |
| __BACKTICK_PLACEHOLDER_398__ | INFO | 驱动加载记录导出成功 | 查看 CSV |
| __BACKTICK_PLACEHOLDER_399__ | NOTICE | Connector dump 完成 | 查看 connectors.txt 和 CSR 副本 |
默认日志级别为 __BACKTICK_PLACEHOLDER_400__。三层架构中 __BACKTICK_PLACEHOLDER_401__、__BACKTICK_PLACEHOLDER_402__、__BACKTICK_PLACEHOLDER_403__ 日志域均默认使用 __BACKTICK_PLACEHOLDER_404__。
### 4.3 调试日志与南向追踪
进入 mdbctl:
__BACKTICK_PLACEHOLDER_405__
常用命令:
__BACKTICK_PLACEHOLDER_406__
读取块设备/EEPROM 的示例:
__BACKTICK_PLACEHOLDER_407__
正常响应类型为 __BACKTICK_PLACEHOLDER_408__,后跟读取长度和二进制数据。该命令仅适用于目标对象确实暴露 __BACKTICK_PLACEHOLDER_409__ 接口的三层架构环境。
## 5. 问题定界指南
### 5.1 典型问题定界
| 现象描述 | 是否为本组件问题 | 判断依据 | 关键证据收集方法 |
| :--- | :--- | :--- | :--- |
| __BACKTICK_PLACEHOLDER_410__ 服务不存在 | 通常是部署、依赖或启动问题,可能属于 devmon 集成问题 | __BACKTICK_PLACEHOLDER_411__ 无服务名,systemd 状态异常 | __BACKTICK_PLACEHOLDER_412__、__BACKTICK_PLACEHOLDER_413__、__BACKTICK_PLACEHOLDER_414__ |
| AddDevice 报 __BACKTICK_PLACEHOLDER_415__ | 是,属于调用参数问题 | 当前接口只从 __BACKTICK_PLACEHOLDER_416__ 生成对象组位置 | 保存完整 busctl 命令和 D-Bus 异常 |
| AddDevice 无输出,但对象已创建 | 否,属于 void 方法正常表现 | 方法没有返回参数,ObjectGroup 和成功日志存在 | __BACKTICK_PLACEHOLDER_417__、对象树、__BACKTICK_PLACEHOLDER_418__ |
| 重复添加后对象未刷新 | 否,属于接口幂等/防重复行为 | 日志出现 __BACKTICK_PLACEHOLDER_419__ | 搜索该日志;先卸载再加载 |
| CSR 校验错误 | 通常是 CSR 配置问题 | Unit/Objects/Anchor 日志明确指出缺失字段 | 原始 CSR、__BACKTICK_PLACEHOLDER_420__ 结果、关键错误日志 |
| __BACKTICK_PLACEHOLDER_421__ | 可能是驱动包或依赖问题 | __BACKTICK_PLACEHOLDER_422__ 失败,未进入驱动注册 | 驱动路径、__BACKTICK_PLACEHOLDER_423__、__BACKTICK_PLACEHOLDER_424__、__BACKTICK_PLACEHOLDER_425__、drivers_load_info.csv |
| __BACKTICK_PLACEHOLDER_426__ | 是驱动 ABI 接口问题 | 动态库缺少导出符号 | __BACKTICK_PLACEHOLDER_427__ |
| __BACKTICK_PLACEHOLDER_428__ 返回空数组 | 不一定 | owner 不匹配、发现未完成或 CSR 没有该 owner 数据 | 读取 __BACKTICK_PLACEHOLDER_429__、connectors.txt、ObjectGroup 属性和 app.log |
| __BACKTICK_PLACEHOLDER_430__ | 不一定 | 可能选错单架构/三层架构路径,或设备添加失败 | 查看架构日志和两个 ObjectGroup 根路径 |
| 三层架构 CSR1 不加载 | 可能是发现链路问题 | devmon 已转发,但 hwdiscovery/hwproxy 未就绪或 CSR1 驱动缺失 | 三个服务状态、转发日志、connectors.txt、ABI v1 驱动 |
| 对象存在但芯片读取失败 | 可能属于驱动、总线或硬件问题 | 对象注册成功,不代表底层总线可访问 | tracechip、chips_access_statistic.csv、硬件代理日志 |
| 一键日志没有 __BACKTICK_PLACEHOLDER_431__ | 不一定 | Release 构建可不输出该统计 | 核对构建类型和其他 dump 文件 |
| devmon 周期性重启 | 是或依赖问题 | systemd 配置 __BACKTICK_PLACEHOLDER_432__,崩溃后会自动拉起 | __BACKTICK_PLACEHOLDER_433__、coredump、journal、MemoryCurrent、依赖版本 |
| 仅某个位置卸载后其他共享总线对象消失 | 可能是对象归属/版本问题 | 卸载逻辑应只注销本 position 拥有的对象 | 记录卸载前后对象树、版本、app.log 和 CSR |
### 5.2 错误码速查表
#### D-Bus/解析错误
| 错误/日志 | 含义 | 可能原因 | 排查建议 |
| :--- | :--- | :--- | :--- |
| __BACKTICK_PLACEHOLDER_434__ | D-Bus 服务不存在 | devmon 未启动、服务未注册或环境变量/总线不正确 | 检查 systemd、用户 D-Bus 会话和服务列表 |
| __BACKTICK_PLACEHOLDER_435__ | 对象路径不存在 | 路径选错、设备未加载、已卸载 | 按架构重新 __BACKTICK_PLACEHOLDER_436__ |
| __BACKTICK_PLACEHOLDER_437__ | 接口名错误 | 混用了 __BACKTICK_PLACEHOLDER_438__ 与 __BACKTICK_PLACEHOLDER_439__ | 先 __BACKTICK_PLACEHOLDER_440__ |
| __BACKTICK_PLACEHOLDER_441__ / 签名不匹配 | D-Bus 参数格式错误 | 字典数量、Variant 类型或签名不正确 | 对照第 2 章逐项检查 |
| __BACKTICK_PLACEHOLDER_442__ | 无有效位置 | GroupPosition 缺失/空 | 传 __BACKTICK_PLACEHOLDER_443__ |
| __BACKTICK_PLACEHOLDER_444__ | CSR 变体类型错误 | AddDeviceWithData 传了非 string/dict | 用 __BACKTICK_PLACEHOLDER_445__ |
| __BACKTICK_PLACEHOLDER_446__ | Unit 字段为空 | CSR 不完整 | 补齐 Unit |
| __BACKTICK_PLACEHOLDER_447__ | Objects 为空 | CSR 不完整 | 添加对象定义 |
| __BACKTICK_PLACEHOLDER_448__ | 拓扑缺 Anchor | 非空拓扑不完整 | 补 Anchor/Buses |
| __BACKTICK_PLACEHOLDER_449__ | 驱动候选全部失败 | Compatible、文件名、ABI 或部署错误 | 依次核对候选库 |
#### 驱动 ABI 状态码
| 错误码 | 含义 | 可能原因 | 排查建议 |
| :--- | :--- | :--- | :--- |
| 0 __BACKTICK_PLACEHOLDER_450__ | 成功 | 正常 | 无 |
| 1 __BACKTICK_PLACEHOLDER_451__ | 通用错误 | 驱动内部失败 | 查看驱动日志和 dump |
| 2 __BACKTICK_PLACEHOLDER_452__ | 目标不存在 | 芯片、通道或资源不存在 | 核对 CSR 和硬件在位 |
| 3 __BACKTICK_PLACEHOLDER_453__ | 参数非法 | CSR/Connector 值不支持 | 打印输入并校验类型/范围 |
| 4 __BACKTICK_PLACEHOLDER_454__ | 未实现 | 驱动不支持该操作 | 使用替代能力或补充实现 |
| 5 __BACKTICK_PLACEHOLDER_455__ | 超时 | 总线无响应、设备忙 | tracechip,检查链路和时序 |
| 6 __BACKTICK_PLACEHOLDER_456__ | 资源忙 | 并发访问或状态机未就绪 | 降低并发、稍后重试 |
| 7 __BACKTICK_PLACEHOLDER_457__ | 内存不足 | 分配失败或泄漏 | 检查 MemoryCurrent、coredump 和长期增长 |
### 5.3 调试方法
#### 开启调试日志
先确认当前服务和日志域,再用 mdbctl 调整级别:
__BACKTICK_PLACEHOLDER_458__
三层架构需要分别对 __BACKTICK_PLACEHOLDER_459__、__BACKTICK_PLACEHOLDER_460__、__BACKTICK_PLACEHOLDER_461__ 检查或设置。定位完成后恢复默认级别,避免长期产生大量日志。
#### 分层排查步骤
##### 1. 确认进程和资源限制
__BACKTICK_PLACEHOLDER_462__
目标 service 配置为 __BACKTICK_PLACEHOLDER_463__、__BACKTICK_PLACEHOLDER_464__、__BACKTICK_PLACEHOLDER_465__,工作目录 __BACKTICK_PLACEHOLDER_466__,执行文件 __BACKTICK_PLACEHOLDER_467__。
##### 2. 确认 D-Bus 服务和架构
__BACKTICK_PLACEHOLDER_468__
##### 3. 确认根接口
__BACKTICK_PLACEHOLDER_469__
应至少看到 __BACKTICK_PLACEHOLDER_470__、__BACKTICK_PLACEHOLDER_471__ 和 __BACKTICK_PLACEHOLDER_472__。
##### 4. 校验 CSR
__BACKTICK_PLACEHOLDER_473__
检查:
- __BACKTICK_PLACEHOLDER_474__、__BACKTICK_PLACEHOLDER_475__、__BACKTICK_PLACEHOLDER_476__ 非空;
- __BACKTICK_PLACEHOLDER_477__ 非空,且含 __BACKTICK_PLACEHOLDER_478__ 对应对象;
- 配置了 __BACKTICK_PLACEHOLDER_479__ 时含 __BACKTICK_PLACEHOLDER_480__;
- 需要总线映射时 __BACKTICK_PLACEHOLDER_481__ 和 Connector 的 __BACKTICK_PLACEHOLDER_482__ 数量/顺序匹配;
- __BACKTICK_PLACEHOLDER_483__ 与部署驱动 ABI 一致。
##### 5. 校验驱动
__BACKTICK_PLACEHOLDER_484__
##### 6. 跟踪一次 AddDevice
__BACKTICK_PLACEHOLDER_485__
判断顺序:参数规范化 → FormatVersion 路由 → CSR 校验 → 驱动加载 → 对象创建 → ObjectGroup → 成功日志。
##### 7. 检查对象组
__BACKTICK_PLACEHOLDER_486__
若路径存在但 __BACKTICK_PLACEHOLDER_487__ 为空,先读 __BACKTICK_PLACEHOLDER_488__;若路径根本不存在,回到 CSR/驱动/转发日志。
##### 8. 检查一键日志证据
__BACKTICK_PLACEHOLDER_489__
##### 9. 检查硬件访问
- 在 mdbctl 中 __BACKTICK_PLACEHOLDER_490__。
- 使用 __BACKTICK_PLACEHOLDER_491__ 追踪目标芯片。
- 对 Scanner 使用 __BACKTICK_PLACEHOLDER_492__。
- 查看 __BACKTICK_PLACEHOLDER_493__ 的失败计数和 Error_Recording。
- 对暴露 BlockIO 的对象执行 __BACKTICK_PLACEHOLDER_494__,区分“对象创建成功”与“底层读写成功”。
#### 复现问题方法
下面流程可复现和隔离“最小 CSR 加载失败”问题:
1. 准备一个只包含单个 __BACKTICK_PLACEHOLDER_495__ 和同名 __BACKTICK_PLACEHOLDER_496__ 的 CSR,使用 __BACKTICK_PLACEHOLDER_497__,并部署匹配的 ABI v2 驱动。
2. 选择未使用的 __BACKTICK_PLACEHOLDER_498__,如 __BACKTICK_PLACEHOLDER_499__。
3. 记录调用前 __BACKTICK_PLACEHOLDER_500__、D-Bus 对象树和 app.log 末尾。
4. 调用 __BACKTICK_PLACEHOLDER_501__。
5. 检查返回码、驱动加载日志和 __BACKTICK_PLACEHOLDER_502__。
6. 调用 __BACKTICK_PLACEHOLDER_503__/__BACKTICK_PLACEHOLDER_504__,保存完整响应。
7. 调用 __BACKTICK_PLACEHOLDER_505__,确认对象清理。
预期现象:驱动加载成功、出现 __BACKTICK_PLACEHOLDER_506__、ObjectGroup 可查询,卸载后路径消失。若最小 CSR 成功而业务 CSR 失败,问题主要落在业务 CSR、目标驱动或拓扑映射;若最小 CSR 也失败,优先检查组件部署、ABI 和依赖环境。
## 6. 常见问题解答
### Q1:Connector 里传了 Position,为什么仍报位置未初始化?
- **问题描述**:旧示例使用 __BACKTICK_PLACEHOLDER_507__,当前代码抛出 __BACKTICK_PLACEHOLDER_508__。
- **一句话答案**:当前动态添加/删除接口必须传 __BACKTICK_PLACEHOLDER_509__。
- **根因说明**:源码从 __BACKTICK_PLACEHOLDER_510__ 生成对象组位置,__BACKTICK_PLACEHOLDER_511__ 只是其他业务字段,不能替代。
- **解决方案**:把调用参数改为 __BACKTICK_PLACEHOLDER_512__。
- **规避方案**:所有新脚本统一使用本文命令模板。
- **适用版本**:devmon 1.2.94。
### Q2:数值 GroupPosition 最终会变成什么?
- **问题描述**:调用传整数后,对象路径不是十进制数字。
- **一句话答案**:整数会转为大写十六进制,至少 2 位并补成偶数长度。
- **根因说明**:位置用于层级拼接和对象组命名,需要稳定的十六进制表示。
- **解决方案**:例如 __BACKTICK_PLACEHOLDER_513__、__BACKTICK_PLACEHOLDER_514__、__BACKTICK_PLACEHOLDER_515__;希望完全控制格式时直接传字符串。
- **规避方案**:添加和删除时使用同一种表示。
- **适用版本**:devmon 1.2.94。
### Q3:同一 GroupPosition 再次 AddDevice 会覆盖旧设备吗?
- **问题描述**:修改 CSR 后重复调用,运行对象没有变化。
- **一句话答案**:不会覆盖,重复位置会直接跳过。
- **根因说明**:devmon 在解析和创建前检查 position 是否已存在,防止重复实例。
- **解决方案**:先 __BACKTICK_PLACEHOLDER_516__,再重新 __BACKTICK_PLACEHOLDER_517__。
- **规避方案**:更新流程显式执行卸载—确认清理—重新加载。
- **适用版本**:devmon 1.2.94。
### Q4:如何判断当前应使用哪个 ObjectGroup 路径?
- **问题描述**:访问 __BACKTICK_PLACEHOLDER_518__ 或 __BACKTICK_PLACEHOLDER_519__ 时出现 UnknownObject。
- **一句话答案**:单架构/CSR2 使用前者,三层架构 CSR1 使用后者。
- **根因说明**:三层架构把旧格式 CSR 的发现结果放在 hwdiscovery 服务。
- **解决方案**:查看 __BACKTICK_PLACEHOLDER_520__ 和 CSR __BACKTICK_PLACEHOLDER_521__,再执行对应 __BACKTICK_PLACEHOLDER_522__。
- **规避方案**:脚本先探测两个服务和根路径。
- **适用版本**:支持 unidev 的 devmon 版本,本文以 1.2.94 为准。
## 附录
### 附录 A 修订记录
| 版本 | 日期 | 修订人 | 修订内容 |
| :--- | :--- | :--- | :--- |
| 1.2.94 | 2026-08-24 | | 创建 devmon 组件说明,补充组件概述、D-Bus API、驱动/CSR 扩展、日志、问题定界和 FAQ |示例代码验证方法
- BACKTICK_PLACEHOLDER_309 能找到全局符号 BACKTICK_PLACEHOLDER_310。
- BACKTICK_PLACEHOLDER_311 不出现 BACKTICK_PLACEHOLDER_312。
- BACKTICK_PLACEHOLDER_313 返回码为 0,日志出现 BACKTICK_PLACEHOLDER_314、BACKTICK_PLACEHOLDER_315 和 BACKTICK_PLACEHOLDER_316。
- BACKTICK_PLACEHOLDER_317 存在,属性和 owner 符合 CSR 预期。
- 一键日志中的 BACKTICK_PLACEHOLDER_318 显示该驱动 BACKTICK_PLACEHOLDER_319。
- BACKTICK_PLACEHOLDER_320 后 ObjectGroup 和本位置设备对象消失,驱动 BACKTICK_PLACEHOLDER_321 已执行。
注意事项
- 驱动库文件名、BACKTICK_PLACEHOLDER_322 归一化名称和 ABI 必须一致。
- BACKTICK_PLACEHOLDER_323 必须使用 BACKTICK_PLACEHOLDER_324,避免 C++ 名字改编导致 BACKTICK_PLACEHOLDER_325 失败。
- BACKTICK_PLACEHOLDER_326 返回的驱动表及其中字符串、函数指针必须在库生命周期内持续有效。
- BACKTICK_PLACEHOLDER_327 返回的是借用指针,调用方会立即复制;驱动不得返回已经释放的临时字符串地址。
- 驱动的 BACKTICK_PLACEHOLDER_328 应可重复、安全地终止线程、定时器和 I/O,避免卸载残留。
- 多实例驱动不得用未加锁的全局可变状态保存单个设备上下文。
- 修改驱动后应先卸载旧设备;已缓存的动态库通常需要重启组件或使用全新版本/环境才能确保重新加载。
- 单架构始终使用 ABI v2;不要因为 CSR 的 BACKTICK_PLACEHOLDER_329 小于 5 就部署只有 BACKTICK_PLACEHOLDER_330 的驱动。
4. 日志说明
4.1 一键日志收集
系统一键日志通常把运行日志放在 BACKTICK_PLACEHOLDER_331,把组件 dump 放在 BACKTICK_PLACEHOLDER_332。不同版本的收集器可能额外增加实例目录,定位时应优先按文件名搜索。
| 文件路径/文件名 | 产生方 | 内容说明 |
|---|---|---|
| BACKTICK_PLACEHOLDER_333 | 系统日志收集 | devmon、hwdiscovery、hwproxy 的运行日志;目标机实时文件通常为 BACKTICK_PLACEHOLDER_334 |
| BACKTICK_PLACEHOLDER_335 | devmon | 当前设备拓扑和对象层级 |
| BACKTICK_PLACEHOLDER_336 | devmon | Scanner/Accessor 运行快照,包括周期、状态、成功/失败计数、值和错误信息 |
| BACKTICK_PLACEHOLDER_337 | devmon | 驱动库加载状态、耗时、设备数和错误信息 |
| BACKTICK_PLACEHOLDER_338 | devmon | 芯片读写成功/失败次数、访问耗时和错误记录;Release 构建可能不生成 |
| BACKTICK_PLACEHOLDER_339 | hwproxy | 三层架构硬件代理对象拓扑 |
| BACKTICK_PLACEHOLDER_340 | hwproxy | 三层架构 Accessor/Scanner 快照 |
| BACKTICK_PLACEHOLDER_341 | hwproxy | SmcDfxInfo 配置和最近数据 |
| BACKTICK_PLACEHOLDER_342 | hwproxy | 三层架构芯片访问统计;Release 构建可能不生成 |
| BACKTICK_PLACEHOLDER_343 | hwdiscovery | Connector 树、位置、源路径、在位状态、识别方式等 |
| BACKTICK_PLACEHOLDER_344 | hwdiscovery | 当前使用的根 CSR;源文件不可用时该文件可能缺失并记录告警 |
| BACKTICK_PLACEHOLDER_345 | hwdiscovery | 当前平台 CSR |
| BACKTICK_PLACEHOLDER_346 / BACKTICK_PLACEHOLDER_347 | hwdiscovery | 各 Connector 的实际 CSR/二进制源文件副本 |
| BACKTICK_PLACEHOLDER_348 | hwdiscovery | Connector 关联的软件 CSR(存在时) |
| BACKTICK_PLACEHOLDER_349 | hwdiscovery | 满足条件的 EEPROM 备份,单次最多复制 65 个 |
| BACKTICK_PLACEHOLDER_350、BACKTICK_PLACEHOLDER_351 | devmon 特定对象 | JBOG 相关运行信息;仅对应对象和场景存在时生成 |
快速查找:
BACKTICK_PLACEHOLDER_352
4.2 关键日志信息
| 日志片段 | 日志级别 | 含义解读 | 建议处理动作 |
|---|---|---|---|
| BACKTICK_PLACEHOLDER_353 | INFO | 当前为单架构 | 使用 BACKTICK_PLACEHOLDER_354,驱动按 ABI v2 检查 |
| BACKTICK_PLACEHOLDER_355 | INFO | 当前为三层架构 | 同时检查 devmon、hwdiscovery、hwproxy |
| BACKTICK_PLACEHOLDER_356 | INFO | 服务配置和基础初始化完成 | 继续确认 root 对象及启动日志 |
| BACKTICK_PLACEHOLDER_357 | INFO | devmon 根对象已注册 | 可执行 BACKTICK_PLACEHOLDER_358 |
| BACKTICK_PLACEHOLDER_359 | INFO | devmon 服务进入启动阶段 | 无 |
| BACKTICK_PLACEHOLDER_360 | INFO | hwproxy 根对象完成 | 三层架构硬件代理可用 |
| BACKTICK_PLACEHOLDER_361 | INFO | hwproxy 已启动 | 无 |
| BACKTICK_PLACEHOLDER_362 | INFO | hwdiscovery 已启动 | 等待异步 CSR 全量发现完成 |
| BACKTICK_PLACEHOLDER_363 | INFO | 应用启动完成 | 无 |
| BACKTICK_PLACEHOLDER_364 | INFO | CSR1 请求被转发到发现层 | 到 hwdiscovery 日志继续跟踪 |
| BACKTICK_PLACEHOLDER_365 | INFO | CSR1 卸载被转发 | 检查子 position 是否级联清理 |
| BACKTICK_PLACEHOLDER_366 | WARN | 同一位置已存在,重复添加被忽略 | 先 RemoveDevice,或使用新 GroupPosition |
| BACKTICK_PLACEHOLDER_367 | INFO | 正在尝试加载候选动态库 | 核对库路径和 ABI |
| BACKTICK_PLACEHOLDER_368 | INFO | 驱动加载并缓存成功 | 继续确认 init/start 和对象创建 |
| BACKTICK_PLACEHOLDER_369 | NOTICE | 本地添加流程完成 | 检查 ObjectGroup 和对象属性 |
| BACKTICK_PLACEHOLDER_370 | ERROR/异常 | CSR 文件无法读取 | 检查路径、权限和部署 |
| BACKTICK_PLACEHOLDER_371 | ERROR/异常 | AddDeviceWithData 的变体类型错误 | 改传 JSON 字符串或字典 |
| BACKTICK_PLACEHOLDER_372 | ERROR/异常 | 缺少有效 GroupPosition | 修改调用参数 |
| BACKTICK_PLACEHOLDER_373 | WARN | FormatVersion 非法,已回退 5.00 | 修正版本格式,避免路由与预期不一致 |
| BACKTICK_PLACEHOLDER_374 | ERROR/异常 | BACKTICK_PLACEHOLDER_375 为空 | 补齐设备类 |
| BACKTICK_PLACEHOLDER_376 | ERROR/异常 | BACKTICK_PLACEHOLDER_377 为空 | 补齐实例名 |
| BACKTICK_PLACEHOLDER_378 | ERROR/异常 | BACKTICK_PLACEHOLDER_379 为空 | 补齐驱动候选 |
| BACKTICK_PLACEHOLDER_380 | ERROR/异常 | CSR 没有对象定义 | 补齐 Objects |
| BACKTICK_PLACEHOLDER_381 | ERROR | BACKTICK_PLACEHOLDER_382 对应对象不存在 | 确保 Objects 含同名键 |
| BACKTICK_PLACEHOLDER_383 | ERROR/异常 | 非空管理拓扑缺少 Anchor | 配置 BACKTICK_PLACEHOLDER_384 或删除管理拓扑 |
| BACKTICK_PLACEHOLDER_385 | ERROR/异常 | BACKTICK_PLACEHOLDER_386 失败 | 用 BACKTICK_PLACEHOLDER_387、架构、权限和库名排查 |
| BACKTICK_PLACEHOLDER_388 | ERROR/异常 | 缺少 BACKTICK_PLACEHOLDER_389 导出符号 | 检查 BACKTICK_PLACEHOLDER_390 和 BACKTICK_PLACEHOLDER_391 |
| BACKTICK_PLACEHOLDER_392 | ERROR/异常 | 注册函数返回非 0 | 修正注册函数参数和返回值 |
| BACKTICK_PLACEHOLDER_393 | ERROR/异常 | 所有 Compatible 候选都失败 | 核对 Compatible、库名和 ABI |
| BACKTICK_PLACEHOLDER_394 / BACKTICK_PLACEHOLDER_395 | ERROR | 驱动实例或对象注册失败 | 查看前序驱动/CSR日志和异常堆栈 |
| BACKTICK_PLACEHOLDER_396 | ERROR | devmon 拓扑根对象缺失,访问统计无法导出 | 检查启动完整性和异常重启 |
| BACKTICK_PLACEHOLDER_397 | WARN | 一键日志找不到某个 CSR/备份源文件 | 核对源路径;不一定代表运行故障 |
| BACKTICK_PLACEHOLDER_398 | INFO | 驱动加载记录导出成功 | 查看 CSV |
| BACKTICK_PLACEHOLDER_399 | NOTICE | Connector dump 完成 | 查看 connectors.txt 和 CSR 副本 |
默认日志级别为 BACKTICK_PLACEHOLDER_400。三层架构中 BACKTICK_PLACEHOLDER_401、BACKTICK_PLACEHOLDER_402、BACKTICK_PLACEHOLDER_403 日志域均默认使用 BACKTICK_PLACEHOLDER_404。
4.3 调试日志与南向追踪
进入 mdbctl:
BACKTICK_PLACEHOLDER_405
常用命令:
BACKTICK_PLACEHOLDER_406
读取块设备/EEPROM 的示例:
BACKTICK_PLACEHOLDER_407
正常响应类型为 BACKTICK_PLACEHOLDER_408,后跟读取长度和二进制数据。该命令仅适用于目标对象确实暴露 BACKTICK_PLACEHOLDER_409 接口的三层架构环境。
5. 问题定界指南
5.1 典型问题定界
| 现象描述 | 是否为本组件问题 | 判断依据 | 关键证据收集方法 |
|---|---|---|---|
| BACKTICK_PLACEHOLDER_410 服务不存在 | 通常是部署、依赖或启动问题,可能属于 devmon 集成问题 | BACKTICK_PLACEHOLDER_411 无服务名,systemd 状态异常 | BACKTICK_PLACEHOLDER_412、BACKTICK_PLACEHOLDER_413、BACKTICK_PLACEHOLDER_414 |
| AddDevice 报 BACKTICK_PLACEHOLDER_415 | 是,属于调用参数问题 | 当前接口只从 BACKTICK_PLACEHOLDER_416 生成对象组位置 | 保存完整 busctl 命令和 D-Bus 异常 |
| AddDevice 无输出,但对象已创建 | 否,属于 void 方法正常表现 | 方法没有返回参数,ObjectGroup 和成功日志存在 | BACKTICK_PLACEHOLDER_417、对象树、BACKTICK_PLACEHOLDER_418 |
| 重复添加后对象未刷新 | 否,属于接口幂等/防重复行为 | 日志出现 BACKTICK_PLACEHOLDER_419 | 搜索该日志;先卸载再加载 |
| CSR 校验错误 | 通常是 CSR 配置问题 | Unit/Objects/Anchor 日志明确指出缺失字段 | 原始 CSR、BACKTICK_PLACEHOLDER_420 结果、关键错误日志 |
| BACKTICK_PLACEHOLDER_421 | 可能是驱动包或依赖问题 | BACKTICK_PLACEHOLDER_422 失败,未进入驱动注册 | 驱动路径、BACKTICK_PLACEHOLDER_423、BACKTICK_PLACEHOLDER_424、BACKTICK_PLACEHOLDER_425、drivers_load_info.csv |
| BACKTICK_PLACEHOLDER_426 | 是驱动 ABI 接口问题 | 动态库缺少导出符号 | BACKTICK_PLACEHOLDER_427 |
| BACKTICK_PLACEHOLDER_428 返回空数组 | 不一定 | owner 不匹配、发现未完成或 CSR 没有该 owner 数据 | 读取 BACKTICK_PLACEHOLDER_429、connectors.txt、ObjectGroup 属性和 app.log |
| BACKTICK_PLACEHOLDER_430 | 不一定 | 可能选错单架构/三层架构路径,或设备添加失败 | 查看架构日志和两个 ObjectGroup 根路径 |
| 三层架构 CSR1 不加载 | 可能是发现链路问题 | devmon 已转发,但 hwdiscovery/hwproxy 未就绪或 CSR1 驱动缺失 | 三个服务状态、转发日志、connectors.txt、ABI v1 驱动 |
| 对象存在但芯片读取失败 | 可能属于驱动、总线或硬件问题 | 对象注册成功,不代表底层总线可访问 | tracechip、chips_access_statistic.csv、硬件代理日志 |
| 一键日志没有 BACKTICK_PLACEHOLDER_431 | 不一定 | Release 构建可不输出该统计 | 核对构建类型和其他 dump 文件 |
| devmon 周期性重启 | 是或依赖问题 | systemd 配置 BACKTICK_PLACEHOLDER_432,崩溃后会自动拉起 | BACKTICK_PLACEHOLDER_433、coredump、journal、MemoryCurrent、依赖版本 |
| 仅某个位置卸载后其他共享总线对象消失 | 可能是对象归属/版本问题 | 卸载逻辑应只注销本 position 拥有的对象 | 记录卸载前后对象树、版本、app.log 和 CSR |
5.2 错误码速查表
D-Bus/解析错误
| 错误/日志 | 含义 | 可能原因 | 排查建议 |
|---|---|---|---|
| BACKTICK_PLACEHOLDER_434 | D-Bus 服务不存在 | devmon 未启动、服务未注册或环境变量/总线不正确 | 检查 systemd、用户 D-Bus 会话和服务列表 |
| BACKTICK_PLACEHOLDER_435 | 对象路径不存在 | 路径选错、设备未加载、已卸载 | 按架构重新 BACKTICK_PLACEHOLDER_436 |
| BACKTICK_PLACEHOLDER_437 | 接口名错误 | 混用了 BACKTICK_PLACEHOLDER_438 与 BACKTICK_PLACEHOLDER_439 | 先 BACKTICK_PLACEHOLDER_440 |
| BACKTICK_PLACEHOLDER_441 / 签名不匹配 | D-Bus 参数格式错误 | 字典数量、Variant 类型或签名不正确 | 对照第 2 章逐项检查 |
| BACKTICK_PLACEHOLDER_442 | 无有效位置 | GroupPosition 缺失/空 | 传 BACKTICK_PLACEHOLDER_443 |
| BACKTICK_PLACEHOLDER_444 | CSR 变体类型错误 | AddDeviceWithData 传了非 string/dict | 用 BACKTICK_PLACEHOLDER_445 |
| BACKTICK_PLACEHOLDER_446 | Unit 字段为空 | CSR 不完整 | 补齐 Unit |
| BACKTICK_PLACEHOLDER_447 | Objects 为空 | CSR 不完整 | 添加对象定义 |
| BACKTICK_PLACEHOLDER_448 | 拓扑缺 Anchor | 非空拓扑不完整 | 补 Anchor/Buses |
| BACKTICK_PLACEHOLDER_449 | 驱动候选全部失败 | Compatible、文件名、ABI 或部署错误 | 依次核对候选库 |
驱动 ABI 状态码
| 错误码 | 含义 | 可能原因 | 排查建议 |
|---|---|---|---|
| 0 BACKTICK_PLACEHOLDER_450 | 成功 | 正常 | 无 |
| 1 BACKTICK_PLACEHOLDER_451 | 通用错误 | 驱动内部失败 | 查看驱动日志和 dump |
| 2 BACKTICK_PLACEHOLDER_452 | 目标不存在 | 芯片、通道或资源不存在 | 核对 CSR 和硬件在位 |
| 3 BACKTICK_PLACEHOLDER_453 | 参数非法 | CSR/Connector 值不支持 | 打印输入并校验类型/范围 |
| 4 BACKTICK_PLACEHOLDER_454 | 未实现 | 驱动不支持该操作 | 使用替代能力或补充实现 |
| 5 BACKTICK_PLACEHOLDER_455 | 超时 | 总线无响应、设备忙 | tracechip,检查链路和时序 |
| 6 BACKTICK_PLACEHOLDER_456 | 资源忙 | 并发访问或状态机未就绪 | 降低并发、稍后重试 |
| 7 BACKTICK_PLACEHOLDER_457 | 内存不足 | 分配失败或泄漏 | 检查 MemoryCurrent、coredump 和长期增长 |
5.3 调试方法
开启调试日志
先确认当前服务和日志域,再用 mdbctl 调整级别:
BACKTICK_PLACEHOLDER_458
三层架构需要分别对 BACKTICK_PLACEHOLDER_459、BACKTICK_PLACEHOLDER_460、BACKTICK_PLACEHOLDER_461 检查或设置。定位完成后恢复默认级别,避免长期产生大量日志。
分层排查步骤
1. 确认进程和资源限制
BACKTICK_PLACEHOLDER_462
目标 service 配置为 BACKTICK_PLACEHOLDER_463、BACKTICK_PLACEHOLDER_464、BACKTICK_PLACEHOLDER_465,工作目录 BACKTICK_PLACEHOLDER_466,执行文件 BACKTICK_PLACEHOLDER_467。
2. 确认 D-Bus 服务和架构
BACKTICK_PLACEHOLDER_468
3. 确认根接口
BACKTICK_PLACEHOLDER_469
应至少看到 BACKTICK_PLACEHOLDER_470、BACKTICK_PLACEHOLDER_471 和 BACKTICK_PLACEHOLDER_472。
4. 校验 CSR
BACKTICK_PLACEHOLDER_473
检查:
- BACKTICK_PLACEHOLDER_474、BACKTICK_PLACEHOLDER_475、BACKTICK_PLACEHOLDER_476 非空;
- BACKTICK_PLACEHOLDER_477 非空,且含 BACKTICK_PLACEHOLDER_478 对应对象;
- 配置了 BACKTICK_PLACEHOLDER_479 时含 BACKTICK_PLACEHOLDER_480;
- 需要总线映射时 BACKTICK_PLACEHOLDER_481 和 Connector 的 BACKTICK_PLACEHOLDER_482 数量/顺序匹配;
- BACKTICK_PLACEHOLDER_483 与部署驱动 ABI 一致。
5. 校验驱动
BACKTICK_PLACEHOLDER_484
6. 跟踪一次 AddDevice
BACKTICK_PLACEHOLDER_485
判断顺序:参数规范化 → FormatVersion 路由 → CSR 校验 → 驱动加载 → 对象创建 → ObjectGroup → 成功日志。
7. 检查对象组
BACKTICK_PLACEHOLDER_486
若路径存在但 BACKTICK_PLACEHOLDER_487 为空,先读 BACKTICK_PLACEHOLDER_488;若路径根本不存在,回到 CSR/驱动/转发日志。
8. 检查一键日志证据
BACKTICK_PLACEHOLDER_489
9. 检查硬件访问
- 在 mdbctl 中 BACKTICK_PLACEHOLDER_490。
- 使用 BACKTICK_PLACEHOLDER_491 追踪目标芯片。
- 对 Scanner 使用 BACKTICK_PLACEHOLDER_492。
- 查看 BACKTICK_PLACEHOLDER_493 的失败计数和 Error_Recording。
- 对暴露 BlockIO 的对象执行 BACKTICK_PLACEHOLDER_494,区分“对象创建成功”与“底层读写成功”。
复现问题方法
下面流程可复现和隔离“最小 CSR 加载失败”问题:
- 准备一个只包含单个 BACKTICK_PLACEHOLDER_495 和同名 BACKTICK_PLACEHOLDER_496 的 CSR,使用 BACKTICK_PLACEHOLDER_497,并部署匹配的 ABI v2 驱动。
- 选择未使用的 BACKTICK_PLACEHOLDER_498,如 BACKTICK_PLACEHOLDER_499。
- 记录调用前 BACKTICK_PLACEHOLDER_500、D-Bus 对象树和 app.log 末尾。
- 调用 BACKTICK_PLACEHOLDER_501。
- 检查返回码、驱动加载日志和 BACKTICK_PLACEHOLDER_502。
- 调用 BACKTICK_PLACEHOLDER_503/BACKTICK_PLACEHOLDER_504,保存完整响应。
- 调用 BACKTICK_PLACEHOLDER_505,确认对象清理。
预期现象:驱动加载成功、出现 BACKTICK_PLACEHOLDER_506、ObjectGroup 可查询,卸载后路径消失。若最小 CSR 成功而业务 CSR 失败,问题主要落在业务 CSR、目标驱动或拓扑映射;若最小 CSR 也失败,优先检查组件部署、ABI 和依赖环境。
6. 常见问题解答
Q1:Connector 里传了 Position,为什么仍报位置未初始化?
- 问题描述:旧示例使用 BACKTICK_PLACEHOLDER_507,当前代码抛出 BACKTICK_PLACEHOLDER_508。
- 一句话答案:当前动态添加/删除接口必须传 BACKTICK_PLACEHOLDER_509。
- 根因说明:源码从 BACKTICK_PLACEHOLDER_510 生成对象组位置,BACKTICK_PLACEHOLDER_511 只是其他业务字段,不能替代。
- 解决方案:把调用参数改为 BACKTICK_PLACEHOLDER_512。
- 规避方案:所有新脚本统一使用本文命令模板。
- 适用版本:devmon 1.2.94。
Q2:数值 GroupPosition 最终会变成什么?
- 问题描述:调用传整数后,对象路径不是十进制数字。
- 一句话答案:整数会转为大写十六进制,至少 2 位并补成偶数长度。
- 根因说明:位置用于层级拼接和对象组命名,需要稳定的十六进制表示。
- 解决方案:例如 BACKTICK_PLACEHOLDER_513、BACKTICK_PLACEHOLDER_514、BACKTICK_PLACEHOLDER_515;希望完全控制格式时直接传字符串。
- 规避方案:添加和删除时使用同一种表示。
- 适用版本:devmon 1.2.94。
Q3:同一 GroupPosition 再次 AddDevice 会覆盖旧设备吗?
- 问题描述:修改 CSR 后重复调用,运行对象没有变化。
- 一句话答案:不会覆盖,重复位置会直接跳过。
- 根因说明:devmon 在解析和创建前检查 position 是否已存在,防止重复实例。
- 解决方案:先 BACKTICK_PLACEHOLDER_516,再重新 BACKTICK_PLACEHOLDER_517。
- 规避方案:更新流程显式执行卸载—确认清理—重新加载。
- 适用版本:devmon 1.2.94。
Q4:如何判断当前应使用哪个 ObjectGroup 路径?
- 问题描述:访问 BACKTICK_PLACEHOLDER_518 或 BACKTICK_PLACEHOLDER_519 时出现 UnknownObject。
- 一句话答案:单架构/CSR2 使用前者,三层架构 CSR1 使用后者。
- 根因说明:三层架构把旧格式 CSR 的发现结果放在 hwdiscovery 服务。
- 解决方案:查看 BACKTICK_PLACEHOLDER_520 和 CSR BACKTICK_PLACEHOLDER_521,再执行对应 BACKTICK_PLACEHOLDER_522。
- 规避方案:脚本先探测两个服务和根路径。
- 适用版本:支持 unidev 的 devmon 版本,本文以 1.2.94 为准。
附录
附录 A 修订记录
| 版本 | 日期 | 修订人 | 修订内容 |
|---|---|---|---|
| 1.2.94 | 2026-08-24 | 创建 devmon 组件说明,补充组件概述、D-Bus API、驱动/CSR 扩展、日志、问题定界和 FAQ |
不应存在 “not found” 依赖
ldd /opt/bmc/drivers/libExample_Driver.so
#### 步骤五:添加设备并验证
__BACKTICK_PLACEHOLDER_307__
#### 步骤六:卸载并确认清理
__BACKTICK_PLACEHOLDER_308__
#### 示例代码验证方法
1. __BACKTICK_PLACEHOLDER_309__ 能找到全局符号 __BACKTICK_PLACEHOLDER_310__。
2. __BACKTICK_PLACEHOLDER_311__ 不出现 __BACKTICK_PLACEHOLDER_312__。
3. __BACKTICK_PLACEHOLDER_313__ 返回码为 0,日志出现 __BACKTICK_PLACEHOLDER_314__、__BACKTICK_PLACEHOLDER_315__ 和 __BACKTICK_PLACEHOLDER_316__。
4. __BACKTICK_PLACEHOLDER_317__ 存在,属性和 owner 符合 CSR 预期。
5. 一键日志中的 __BACKTICK_PLACEHOLDER_318__ 显示该驱动 __BACKTICK_PLACEHOLDER_319__。
6. __BACKTICK_PLACEHOLDER_320__ 后 ObjectGroup 和本位置设备对象消失,驱动 __BACKTICK_PLACEHOLDER_321__ 已执行。
#### 注意事项
- 驱动库文件名、__BACKTICK_PLACEHOLDER_322__ 归一化名称和 ABI 必须一致。
- __BACKTICK_PLACEHOLDER_323__ 必须使用 __BACKTICK_PLACEHOLDER_324__,避免 C++ 名字改编导致 __BACKTICK_PLACEHOLDER_325__ 失败。
- __BACKTICK_PLACEHOLDER_326__ 返回的驱动表及其中字符串、函数指针必须在库生命周期内持续有效。
- __BACKTICK_PLACEHOLDER_327__ 返回的是借用指针,调用方会立即复制;驱动不得返回已经释放的临时字符串地址。
- 驱动的 __BACKTICK_PLACEHOLDER_328__ 应可重复、安全地终止线程、定时器和 I/O,避免卸载残留。
- 多实例驱动不得用未加锁的全局可变状态保存单个设备上下文。
- 修改驱动后应先卸载旧设备;已缓存的动态库通常需要重启组件或使用全新版本/环境才能确保重新加载。
- 单架构始终使用 ABI v2;不要因为 CSR 的 __BACKTICK_PLACEHOLDER_329__ 小于 5 就部署只有 __BACKTICK_PLACEHOLDER_330__ 的驱动。
## 4. 日志说明
### 4.1 一键日志收集
系统一键日志通常把运行日志放在 __BACKTICK_PLACEHOLDER_331__,把组件 dump 放在 __BACKTICK_PLACEHOLDER_332__。不同版本的收集器可能额外增加实例目录,定位时应优先按文件名搜索。
| 文件路径/文件名 | 产生方 | 内容说明 |
| :--- | :--- | :--- |
| __BACKTICK_PLACEHOLDER_333__ | 系统日志收集 | devmon、hwdiscovery、hwproxy 的运行日志;目标机实时文件通常为 __BACKTICK_PLACEHOLDER_334__ |
| __BACKTICK_PLACEHOLDER_335__ | devmon | 当前设备拓扑和对象层级 |
| __BACKTICK_PLACEHOLDER_336__ | devmon | Scanner/Accessor 运行快照,包括周期、状态、成功/失败计数、值和错误信息 |
| __BACKTICK_PLACEHOLDER_337__ | devmon | 驱动库加载状态、耗时、设备数和错误信息 |
| __BACKTICK_PLACEHOLDER_338__ | devmon | 芯片读写成功/失败次数、访问耗时和错误记录;Release 构建可能不生成 |
| __BACKTICK_PLACEHOLDER_339__ | hwproxy | 三层架构硬件代理对象拓扑 |
| __BACKTICK_PLACEHOLDER_340__ | hwproxy | 三层架构 Accessor/Scanner 快照 |
| __BACKTICK_PLACEHOLDER_341__ | hwproxy | SmcDfxInfo 配置和最近数据 |
| __BACKTICK_PLACEHOLDER_342__ | hwproxy | 三层架构芯片访问统计;Release 构建可能不生成 |
| __BACKTICK_PLACEHOLDER_343__ | hwdiscovery | Connector 树、位置、源路径、在位状态、识别方式等 |
| __BACKTICK_PLACEHOLDER_344__ | hwdiscovery | 当前使用的根 CSR;源文件不可用时该文件可能缺失并记录告警 |
| __BACKTICK_PLACEHOLDER_345__ | hwdiscovery | 当前平台 CSR |
| __BACKTICK_PLACEHOLDER_346__ / __BACKTICK_PLACEHOLDER_347__ | hwdiscovery | 各 Connector 的实际 CSR/二进制源文件副本 |
| __BACKTICK_PLACEHOLDER_348__ | hwdiscovery | Connector 关联的软件 CSR(存在时) |
| __BACKTICK_PLACEHOLDER_349__ | hwdiscovery | 满足条件的 EEPROM 备份,单次最多复制 65 个 |
| __BACKTICK_PLACEHOLDER_350__、__BACKTICK_PLACEHOLDER_351__ | devmon 特定对象 | JBOG 相关运行信息;仅对应对象和场景存在时生成 |
快速查找:
__BACKTICK_PLACEHOLDER_352__
### 4.2 关键日志信息
| 日志片段 | 日志级别 | 含义解读 | 建议处理动作 |
| :--- | :--- | :--- | :--- |
| __BACKTICK_PLACEHOLDER_353__ | INFO | 当前为单架构 | 使用 __BACKTICK_PLACEHOLDER_354__,驱动按 ABI v2 检查 |
| __BACKTICK_PLACEHOLDER_355__ | INFO | 当前为三层架构 | 同时检查 devmon、hwdiscovery、hwproxy |
| __BACKTICK_PLACEHOLDER_356__ | INFO | 服务配置和基础初始化完成 | 继续确认 root 对象及启动日志 |
| __BACKTICK_PLACEHOLDER_357__ | INFO | devmon 根对象已注册 | 可执行 __BACKTICK_PLACEHOLDER_358__ |
| __BACKTICK_PLACEHOLDER_359__ | INFO | devmon 服务进入启动阶段 | 无 |
| __BACKTICK_PLACEHOLDER_360__ | INFO | hwproxy 根对象完成 | 三层架构硬件代理可用 |
| __BACKTICK_PLACEHOLDER_361__ | INFO | hwproxy 已启动 | 无 |
| __BACKTICK_PLACEHOLDER_362__ | INFO | hwdiscovery 已启动 | 等待异步 CSR 全量发现完成 |
| __BACKTICK_PLACEHOLDER_363__ | INFO | 应用启动完成 | 无 |
| __BACKTICK_PLACEHOLDER_364__ | INFO | CSR1 请求被转发到发现层 | 到 hwdiscovery 日志继续跟踪 |
| __BACKTICK_PLACEHOLDER_365__ | INFO | CSR1 卸载被转发 | 检查子 position 是否级联清理 |
| __BACKTICK_PLACEHOLDER_366__ | WARN | 同一位置已存在,重复添加被忽略 | 先 RemoveDevice,或使用新 GroupPosition |
| __BACKTICK_PLACEHOLDER_367__ | INFO | 正在尝试加载候选动态库 | 核对库路径和 ABI |
| __BACKTICK_PLACEHOLDER_368__ | INFO | 驱动加载并缓存成功 | 继续确认 init/start 和对象创建 |
| __BACKTICK_PLACEHOLDER_369__ | NOTICE | 本地添加流程完成 | 检查 ObjectGroup 和对象属性 |
| __BACKTICK_PLACEHOLDER_370__ | ERROR/异常 | CSR 文件无法读取 | 检查路径、权限和部署 |
| __BACKTICK_PLACEHOLDER_371__ | ERROR/异常 | AddDeviceWithData 的变体类型错误 | 改传 JSON 字符串或字典 |
| __BACKTICK_PLACEHOLDER_372__ | ERROR/异常 | 缺少有效 GroupPosition | 修改调用参数 |
| __BACKTICK_PLACEHOLDER_373__ | WARN | FormatVersion 非法,已回退 5.00 | 修正版本格式,避免路由与预期不一致 |
| __BACKTICK_PLACEHOLDER_374__ | ERROR/异常 | __BACKTICK_PLACEHOLDER_375__ 为空 | 补齐设备类 |
| __BACKTICK_PLACEHOLDER_376__ | ERROR/异常 | __BACKTICK_PLACEHOLDER_377__ 为空 | 补齐实例名 |
| __BACKTICK_PLACEHOLDER_378__ | ERROR/异常 | __BACKTICK_PLACEHOLDER_379__ 为空 | 补齐驱动候选 |
| __BACKTICK_PLACEHOLDER_380__ | ERROR/异常 | CSR 没有对象定义 | 补齐 Objects |
| __BACKTICK_PLACEHOLDER_381__ | ERROR | __BACKTICK_PLACEHOLDER_382__ 对应对象不存在 | 确保 Objects 含同名键 |
| __BACKTICK_PLACEHOLDER_383__ | ERROR/异常 | 非空管理拓扑缺少 Anchor | 配置 __BACKTICK_PLACEHOLDER_384__ 或删除管理拓扑 |
| __BACKTICK_PLACEHOLDER_385__ | ERROR/异常 | __BACKTICK_PLACEHOLDER_386__ 失败 | 用 __BACKTICK_PLACEHOLDER_387__、架构、权限和库名排查 |
| __BACKTICK_PLACEHOLDER_388__ | ERROR/异常 | 缺少 __BACKTICK_PLACEHOLDER_389__ 导出符号 | 检查 __BACKTICK_PLACEHOLDER_390__ 和 __BACKTICK_PLACEHOLDER_391__ |
| __BACKTICK_PLACEHOLDER_392__ | ERROR/异常 | 注册函数返回非 0 | 修正注册函数参数和返回值 |
| __BACKTICK_PLACEHOLDER_393__ | ERROR/异常 | 所有 Compatible 候选都失败 | 核对 Compatible、库名和 ABI |
| __BACKTICK_PLACEHOLDER_394__ / __BACKTICK_PLACEHOLDER_395__ | ERROR | 驱动实例或对象注册失败 | 查看前序驱动/CSR日志和异常堆栈 |
| __BACKTICK_PLACEHOLDER_396__ | ERROR | devmon 拓扑根对象缺失,访问统计无法导出 | 检查启动完整性和异常重启 |
| __BACKTICK_PLACEHOLDER_397__ | WARN | 一键日志找不到某个 CSR/备份源文件 | 核对源路径;不一定代表运行故障 |
| __BACKTICK_PLACEHOLDER_398__ | INFO | 驱动加载记录导出成功 | 查看 CSV |
| __BACKTICK_PLACEHOLDER_399__ | NOTICE | Connector dump 完成 | 查看 connectors.txt 和 CSR 副本 |
默认日志级别为 __BACKTICK_PLACEHOLDER_400__。三层架构中 __BACKTICK_PLACEHOLDER_401__、__BACKTICK_PLACEHOLDER_402__、__BACKTICK_PLACEHOLDER_403__ 日志域均默认使用 __BACKTICK_PLACEHOLDER_404__。
### 4.3 调试日志与南向追踪
进入 mdbctl:
__BACKTICK_PLACEHOLDER_405__
常用命令:
__BACKTICK_PLACEHOLDER_406__
读取块设备/EEPROM 的示例:
__BACKTICK_PLACEHOLDER_407__
正常响应类型为 __BACKTICK_PLACEHOLDER_408__,后跟读取长度和二进制数据。该命令仅适用于目标对象确实暴露 __BACKTICK_PLACEHOLDER_409__ 接口的三层架构环境。
## 5. 问题定界指南
### 5.1 典型问题定界
| 现象描述 | 是否为本组件问题 | 判断依据 | 关键证据收集方法 |
| :--- | :--- | :--- | :--- |
| __BACKTICK_PLACEHOLDER_410__ 服务不存在 | 通常是部署、依赖或启动问题,可能属于 devmon 集成问题 | __BACKTICK_PLACEHOLDER_411__ 无服务名,systemd 状态异常 | __BACKTICK_PLACEHOLDER_412__、__BACKTICK_PLACEHOLDER_413__、__BACKTICK_PLACEHOLDER_414__ |
| AddDevice 报 __BACKTICK_PLACEHOLDER_415__ | 是,属于调用参数问题 | 当前接口只从 __BACKTICK_PLACEHOLDER_416__ 生成对象组位置 | 保存完整 busctl 命令和 D-Bus 异常 |
| AddDevice 无输出,但对象已创建 | 否,属于 void 方法正常表现 | 方法没有返回参数,ObjectGroup 和成功日志存在 | __BACKTICK_PLACEHOLDER_417__、对象树、__BACKTICK_PLACEHOLDER_418__ |
| 重复添加后对象未刷新 | 否,属于接口幂等/防重复行为 | 日志出现 __BACKTICK_PLACEHOLDER_419__ | 搜索该日志;先卸载再加载 |
| CSR 校验错误 | 通常是 CSR 配置问题 | Unit/Objects/Anchor 日志明确指出缺失字段 | 原始 CSR、__BACKTICK_PLACEHOLDER_420__ 结果、关键错误日志 |
| __BACKTICK_PLACEHOLDER_421__ | 可能是驱动包或依赖问题 | __BACKTICK_PLACEHOLDER_422__ 失败,未进入驱动注册 | 驱动路径、__BACKTICK_PLACEHOLDER_423__、__BACKTICK_PLACEHOLDER_424__、__BACKTICK_PLACEHOLDER_425__、drivers_load_info.csv |
| __BACKTICK_PLACEHOLDER_426__ | 是驱动 ABI 接口问题 | 动态库缺少导出符号 | __BACKTICK_PLACEHOLDER_427__ |
| __BACKTICK_PLACEHOLDER_428__ 返回空数组 | 不一定 | owner 不匹配、发现未完成或 CSR 没有该 owner 数据 | 读取 __BACKTICK_PLACEHOLDER_429__、connectors.txt、ObjectGroup 属性和 app.log |
| __BACKTICK_PLACEHOLDER_430__ | 不一定 | 可能选错单架构/三层架构路径,或设备添加失败 | 查看架构日志和两个 ObjectGroup 根路径 |
| 三层架构 CSR1 不加载 | 可能是发现链路问题 | devmon 已转发,但 hwdiscovery/hwproxy 未就绪或 CSR1 驱动缺失 | 三个服务状态、转发日志、connectors.txt、ABI v1 驱动 |
| 对象存在但芯片读取失败 | 可能属于驱动、总线或硬件问题 | 对象注册成功,不代表底层总线可访问 | tracechip、chips_access_statistic.csv、硬件代理日志 |
| 一键日志没有 __BACKTICK_PLACEHOLDER_431__ | 不一定 | Release 构建可不输出该统计 | 核对构建类型和其他 dump 文件 |
| devmon 周期性重启 | 是或依赖问题 | systemd 配置 __BACKTICK_PLACEHOLDER_432__,崩溃后会自动拉起 | __BACKTICK_PLACEHOLDER_433__、coredump、journal、MemoryCurrent、依赖版本 |
| 仅某个位置卸载后其他共享总线对象消失 | 可能是对象归属/版本问题 | 卸载逻辑应只注销本 position 拥有的对象 | 记录卸载前后对象树、版本、app.log 和 CSR |
### 5.2 错误码速查表
#### D-Bus/解析错误
| 错误/日志 | 含义 | 可能原因 | 排查建议 |
| :--- | :--- | :--- | :--- |
| __BACKTICK_PLACEHOLDER_434__ | D-Bus 服务不存在 | devmon 未启动、服务未注册或环境变量/总线不正确 | 检查 systemd、用户 D-Bus 会话和服务列表 |
| __BACKTICK_PLACEHOLDER_435__ | 对象路径不存在 | 路径选错、设备未加载、已卸载 | 按架构重新 __BACKTICK_PLACEHOLDER_436__ |
| __BACKTICK_PLACEHOLDER_437__ | 接口名错误 | 混用了 __BACKTICK_PLACEHOLDER_438__ 与 __BACKTICK_PLACEHOLDER_439__ | 先 __BACKTICK_PLACEHOLDER_440__ |
| __BACKTICK_PLACEHOLDER_441__ / 签名不匹配 | D-Bus 参数格式错误 | 字典数量、Variant 类型或签名不正确 | 对照第 2 章逐项检查 |
| __BACKTICK_PLACEHOLDER_442__ | 无有效位置 | GroupPosition 缺失/空 | 传 __BACKTICK_PLACEHOLDER_443__ |
| __BACKTICK_PLACEHOLDER_444__ | CSR 变体类型错误 | AddDeviceWithData 传了非 string/dict | 用 __BACKTICK_PLACEHOLDER_445__ |
| __BACKTICK_PLACEHOLDER_446__ | Unit 字段为空 | CSR 不完整 | 补齐 Unit |
| __BACKTICK_PLACEHOLDER_447__ | Objects 为空 | CSR 不完整 | 添加对象定义 |
| __BACKTICK_PLACEHOLDER_448__ | 拓扑缺 Anchor | 非空拓扑不完整 | 补 Anchor/Buses |
| __BACKTICK_PLACEHOLDER_449__ | 驱动候选全部失败 | Compatible、文件名、ABI 或部署错误 | 依次核对候选库 |
#### 驱动 ABI 状态码
| 错误码 | 含义 | 可能原因 | 排查建议 |
| :--- | :--- | :--- | :--- |
| 0 __BACKTICK_PLACEHOLDER_450__ | 成功 | 正常 | 无 |
| 1 __BACKTICK_PLACEHOLDER_451__ | 通用错误 | 驱动内部失败 | 查看驱动日志和 dump |
| 2 __BACKTICK_PLACEHOLDER_452__ | 目标不存在 | 芯片、通道或资源不存在 | 核对 CSR 和硬件在位 |
| 3 __BACKTICK_PLACEHOLDER_453__ | 参数非法 | CSR/Connector 值不支持 | 打印输入并校验类型/范围 |
| 4 __BACKTICK_PLACEHOLDER_454__ | 未实现 | 驱动不支持该操作 | 使用替代能力或补充实现 |
| 5 __BACKTICK_PLACEHOLDER_455__ | 超时 | 总线无响应、设备忙 | tracechip,检查链路和时序 |
| 6 __BACKTICK_PLACEHOLDER_456__ | 资源忙 | 并发访问或状态机未就绪 | 降低并发、稍后重试 |
| 7 __BACKTICK_PLACEHOLDER_457__ | 内存不足 | 分配失败或泄漏 | 检查 MemoryCurrent、coredump 和长期增长 |
### 5.3 调试方法
#### 开启调试日志
先确认当前服务和日志域,再用 mdbctl 调整级别:
__BACKTICK_PLACEHOLDER_458__
三层架构需要分别对 __BACKTICK_PLACEHOLDER_459__、__BACKTICK_PLACEHOLDER_460__、__BACKTICK_PLACEHOLDER_461__ 检查或设置。定位完成后恢复默认级别,避免长期产生大量日志。
#### 分层排查步骤
##### 1. 确认进程和资源限制
__BACKTICK_PLACEHOLDER_462__
目标 service 配置为 __BACKTICK_PLACEHOLDER_463__、__BACKTICK_PLACEHOLDER_464__、__BACKTICK_PLACEHOLDER_465__,工作目录 __BACKTICK_PLACEHOLDER_466__,执行文件 __BACKTICK_PLACEHOLDER_467__。
##### 2. 确认 D-Bus 服务和架构
__BACKTICK_PLACEHOLDER_468__
##### 3. 确认根接口
__BACKTICK_PLACEHOLDER_469__
应至少看到 __BACKTICK_PLACEHOLDER_470__、__BACKTICK_PLACEHOLDER_471__ 和 __BACKTICK_PLACEHOLDER_472__。
##### 4. 校验 CSR
__BACKTICK_PLACEHOLDER_473__
检查:
- __BACKTICK_PLACEHOLDER_474__、__BACKTICK_PLACEHOLDER_475__、__BACKTICK_PLACEHOLDER_476__ 非空;
- __BACKTICK_PLACEHOLDER_477__ 非空,且含 __BACKTICK_PLACEHOLDER_478__ 对应对象;
- 配置了 __BACKTICK_PLACEHOLDER_479__ 时含 __BACKTICK_PLACEHOLDER_480__;
- 需要总线映射时 __BACKTICK_PLACEHOLDER_481__ 和 Connector 的 __BACKTICK_PLACEHOLDER_482__ 数量/顺序匹配;
- __BACKTICK_PLACEHOLDER_483__ 与部署驱动 ABI 一致。
##### 5. 校验驱动
__BACKTICK_PLACEHOLDER_484__
##### 6. 跟踪一次 AddDevice
__BACKTICK_PLACEHOLDER_485__
判断顺序:参数规范化 → FormatVersion 路由 → CSR 校验 → 驱动加载 → 对象创建 → ObjectGroup → 成功日志。
##### 7. 检查对象组
__BACKTICK_PLACEHOLDER_486__
若路径存在但 __BACKTICK_PLACEHOLDER_487__ 为空,先读 __BACKTICK_PLACEHOLDER_488__;若路径根本不存在,回到 CSR/驱动/转发日志。
##### 8. 检查一键日志证据
__BACKTICK_PLACEHOLDER_489__
##### 9. 检查硬件访问
- 在 mdbctl 中 __BACKTICK_PLACEHOLDER_490__。
- 使用 __BACKTICK_PLACEHOLDER_491__ 追踪目标芯片。
- 对 Scanner 使用 __BACKTICK_PLACEHOLDER_492__。
- 查看 __BACKTICK_PLACEHOLDER_493__ 的失败计数和 Error_Recording。
- 对暴露 BlockIO 的对象执行 __BACKTICK_PLACEHOLDER_494__,区分“对象创建成功”与“底层读写成功”。
#### 复现问题方法
下面流程可复现和隔离“最小 CSR 加载失败”问题:
1. 准备一个只包含单个 __BACKTICK_PLACEHOLDER_495__ 和同名 __BACKTICK_PLACEHOLDER_496__ 的 CSR,使用 __BACKTICK_PLACEHOLDER_497__,并部署匹配的 ABI v2 驱动。
2. 选择未使用的 __BACKTICK_PLACEHOLDER_498__,如 __BACKTICK_PLACEHOLDER_499__。
3. 记录调用前 __BACKTICK_PLACEHOLDER_500__、D-Bus 对象树和 app.log 末尾。
4. 调用 __BACKTICK_PLACEHOLDER_501__。
5. 检查返回码、驱动加载日志和 __BACKTICK_PLACEHOLDER_502__。
6. 调用 __BACKTICK_PLACEHOLDER_503__/__BACKTICK_PLACEHOLDER_504__,保存完整响应。
7. 调用 __BACKTICK_PLACEHOLDER_505__,确认对象清理。
预期现象:驱动加载成功、出现 __BACKTICK_PLACEHOLDER_506__、ObjectGroup 可查询,卸载后路径消失。若最小 CSR 成功而业务 CSR 失败,问题主要落在业务 CSR、目标驱动或拓扑映射;若最小 CSR 也失败,优先检查组件部署、ABI 和依赖环境。
## 6. 常见问题解答
### Q1:Connector 里传了 Position,为什么仍报位置未初始化?
- **问题描述**:旧示例使用 __BACKTICK_PLACEHOLDER_507__,当前代码抛出 __BACKTICK_PLACEHOLDER_508__。
- **一句话答案**:当前动态添加/删除接口必须传 __BACKTICK_PLACEHOLDER_509__。
- **根因说明**:源码从 __BACKTICK_PLACEHOLDER_510__ 生成对象组位置,__BACKTICK_PLACEHOLDER_511__ 只是其他业务字段,不能替代。
- **解决方案**:把调用参数改为 __BACKTICK_PLACEHOLDER_512__。
- **规避方案**:所有新脚本统一使用本文命令模板。
- **适用版本**:devmon 1.2.94。
### Q2:数值 GroupPosition 最终会变成什么?
- **问题描述**:调用传整数后,对象路径不是十进制数字。
- **一句话答案**:整数会转为大写十六进制,至少 2 位并补成偶数长度。
- **根因说明**:位置用于层级拼接和对象组命名,需要稳定的十六进制表示。
- **解决方案**:例如 __BACKTICK_PLACEHOLDER_513__、__BACKTICK_PLACEHOLDER_514__、__BACKTICK_PLACEHOLDER_515__;希望完全控制格式时直接传字符串。
- **规避方案**:添加和删除时使用同一种表示。
- **适用版本**:devmon 1.2.94。
### Q3:同一 GroupPosition 再次 AddDevice 会覆盖旧设备吗?
- **问题描述**:修改 CSR 后重复调用,运行对象没有变化。
- **一句话答案**:不会覆盖,重复位置会直接跳过。
- **根因说明**:devmon 在解析和创建前检查 position 是否已存在,防止重复实例。
- **解决方案**:先 __BACKTICK_PLACEHOLDER_516__,再重新 __BACKTICK_PLACEHOLDER_517__。
- **规避方案**:更新流程显式执行卸载—确认清理—重新加载。
- **适用版本**:devmon 1.2.94。
### Q4:如何判断当前应使用哪个 ObjectGroup 路径?
- **问题描述**:访问 __BACKTICK_PLACEHOLDER_518__ 或 __BACKTICK_PLACEHOLDER_519__ 时出现 UnknownObject。
- **一句话答案**:单架构/CSR2 使用前者,三层架构 CSR1 使用后者。
- **根因说明**:三层架构把旧格式 CSR 的发现结果放在 hwdiscovery 服务。
- **解决方案**:查看 __BACKTICK_PLACEHOLDER_520__ 和 CSR __BACKTICK_PLACEHOLDER_521__,再执行对应 __BACKTICK_PLACEHOLDER_522__。
- **规避方案**:脚本先探测两个服务和根路径。
- **适用版本**:支持 unidev 的 devmon 版本,本文以 1.2.94 为准。
## 附录
### 附录 A 修订记录
| 版本 | 日期 | 修订人 | 修订内容 |
| :--- | :--- | :--- | :--- |
| 1.2.94 | 2026-08-24 | | 创建 devmon 组件说明,补充组件概述、D-Bus API、驱动/CSR 扩展、日志、问题定界和 FAQ |
ldd "$DRIVER" | tee /tmp/devmon-driver-ldd.txt
! grep -q 'not found' /tmp/devmon-driver-ldd.txt6. 跟踪一次 AddDevice
BACKTICK_PLACEHOLDER_485
判断顺序:参数规范化 → FormatVersion 路由 → CSR 校验 → 驱动加载 → 对象创建 → ObjectGroup → 成功日志。
7. 检查对象组
BACKTICK_PLACEHOLDER_486
若路径存在但 BACKTICK_PLACEHOLDER_487 为空,先读 BACKTICK_PLACEHOLDER_488;若路径根本不存在,回到 CSR/驱动/转发日志。
8. 检查一键日志证据
BACKTICK_PLACEHOLDER_489
9. 检查硬件访问
- 在 mdbctl 中 BACKTICK_PLACEHOLDER_490。
- 使用 BACKTICK_PLACEHOLDER_491 追踪目标芯片。
- 对 Scanner 使用 BACKTICK_PLACEHOLDER_492。
- 查看 BACKTICK_PLACEHOLDER_493 的失败计数和 Error_Recording。
- 对暴露 BlockIO 的对象执行 BACKTICK_PLACEHOLDER_494,区分“对象创建成功”与“底层读写成功”。
复现问题方法
下面流程可复现和隔离“最小 CSR 加载失败”问题:
- 准备一个只包含单个 BACKTICK_PLACEHOLDER_495 和同名 BACKTICK_PLACEHOLDER_496 的 CSR,使用 BACKTICK_PLACEHOLDER_497,并部署匹配的 ABI v2 驱动。
- 选择未使用的 BACKTICK_PLACEHOLDER_498,如 BACKTICK_PLACEHOLDER_499。
- 记录调用前 BACKTICK_PLACEHOLDER_500、D-Bus 对象树和 app.log 末尾。
- 调用 BACKTICK_PLACEHOLDER_501。
- 检查返回码、驱动加载日志和 BACKTICK_PLACEHOLDER_502。
- 调用 BACKTICK_PLACEHOLDER_503/BACKTICK_PLACEHOLDER_504,保存完整响应。
- 调用 BACKTICK_PLACEHOLDER_505,确认对象清理。
预期现象:驱动加载成功、出现 BACKTICK_PLACEHOLDER_506、ObjectGroup 可查询,卸载后路径消失。若最小 CSR 成功而业务 CSR 失败,问题主要落在业务 CSR、目标驱动或拓扑映射;若最小 CSR 也失败,优先检查组件部署、ABI 和依赖环境。
6. 常见问题解答
Q1:Connector 里传了 Position,为什么仍报位置未初始化?
- 问题描述:旧示例使用 BACKTICK_PLACEHOLDER_507,当前代码抛出 BACKTICK_PLACEHOLDER_508。
- 一句话答案:当前动态添加/删除接口必须传 BACKTICK_PLACEHOLDER_509。
- 根因说明:源码从 BACKTICK_PLACEHOLDER_510 生成对象组位置,BACKTICK_PLACEHOLDER_511 只是其他业务字段,不能替代。
- 解决方案:把调用参数改为 BACKTICK_PLACEHOLDER_512。
- 规避方案:所有新脚本统一使用本文命令模板。
- 适用版本:devmon 1.2.94。
Q2:数值 GroupPosition 最终会变成什么?
- 问题描述:调用传整数后,对象路径不是十进制数字。
- 一句话答案:整数会转为大写十六进制,至少 2 位并补成偶数长度。
- 根因说明:位置用于层级拼接和对象组命名,需要稳定的十六进制表示。
- 解决方案:例如 BACKTICK_PLACEHOLDER_513、BACKTICK_PLACEHOLDER_514、BACKTICK_PLACEHOLDER_515;希望完全控制格式时直接传字符串。
- 规避方案:添加和删除时使用同一种表示。
- 适用版本:devmon 1.2.94。
Q3:同一 GroupPosition 再次 AddDevice 会覆盖旧设备吗?
- 问题描述:修改 CSR 后重复调用,运行对象没有变化。
- 一句话答案:不会覆盖,重复位置会直接跳过。
- 根因说明:devmon 在解析和创建前检查 position 是否已存在,防止重复实例。
- 解决方案:先 BACKTICK_PLACEHOLDER_516,再重新 BACKTICK_PLACEHOLDER_517。
- 规避方案:更新流程显式执行卸载—确认清理—重新加载。
- 适用版本:devmon 1.2.94。
Q4:如何判断当前应使用哪个 ObjectGroup 路径?
- 问题描述:访问 BACKTICK_PLACEHOLDER_518 或 BACKTICK_PLACEHOLDER_519 时出现 UnknownObject。
- 一句话答案:单架构/CSR2 使用前者,三层架构 CSR1 使用后者。
- 根因说明:三层架构把旧格式 CSR 的发现结果放在 hwdiscovery 服务。
- 解决方案:查看 BACKTICK_PLACEHOLDER_520 和 CSR BACKTICK_PLACEHOLDER_521,再执行对应 BACKTICK_PLACEHOLDER_522。
- 规避方案:脚本先探测两个服务和根路径。
- 适用版本:支持 unidev 的 devmon 版本,本文以 1.2.94 为准。
附录
附录 A 修订记录
| 版本 | 日期 | 修订人 | 修订内容 |
|---|---|---|---|
| 1.2.94 | 2026-08-24 | 创建 devmon 组件说明,补充组件概述、D-Bus API、驱动/CSR 扩展、日志、问题定界和 FAQ |
不应存在 “not found” 依赖
ldd /opt/bmc/drivers/libExample_Driver.so
#### 步骤五:添加设备并验证
__BACKTICK_PLACEHOLDER_307__
#### 步骤六:卸载并确认清理
__BACKTICK_PLACEHOLDER_308__
#### 示例代码验证方法
1. __BACKTICK_PLACEHOLDER_309__ 能找到全局符号 __BACKTICK_PLACEHOLDER_310__。
2. __BACKTICK_PLACEHOLDER_311__ 不出现 __BACKTICK_PLACEHOLDER_312__。
3. __BACKTICK_PLACEHOLDER_313__ 返回码为 0,日志出现 __BACKTICK_PLACEHOLDER_314__、__BACKTICK_PLACEHOLDER_315__ 和 __BACKTICK_PLACEHOLDER_316__。
4. __BACKTICK_PLACEHOLDER_317__ 存在,属性和 owner 符合 CSR 预期。
5. 一键日志中的 __BACKTICK_PLACEHOLDER_318__ 显示该驱动 __BACKTICK_PLACEHOLDER_319__。
6. __BACKTICK_PLACEHOLDER_320__ 后 ObjectGroup 和本位置设备对象消失,驱动 __BACKTICK_PLACEHOLDER_321__ 已执行。
#### 注意事项
- 驱动库文件名、__BACKTICK_PLACEHOLDER_322__ 归一化名称和 ABI 必须一致。
- __BACKTICK_PLACEHOLDER_323__ 必须使用 __BACKTICK_PLACEHOLDER_324__,避免 C++ 名字改编导致 __BACKTICK_PLACEHOLDER_325__ 失败。
- __BACKTICK_PLACEHOLDER_326__ 返回的驱动表及其中字符串、函数指针必须在库生命周期内持续有效。
- __BACKTICK_PLACEHOLDER_327__ 返回的是借用指针,调用方会立即复制;驱动不得返回已经释放的临时字符串地址。
- 驱动的 __BACKTICK_PLACEHOLDER_328__ 应可重复、安全地终止线程、定时器和 I/O,避免卸载残留。
- 多实例驱动不得用未加锁的全局可变状态保存单个设备上下文。
- 修改驱动后应先卸载旧设备;已缓存的动态库通常需要重启组件或使用全新版本/环境才能确保重新加载。
- 单架构始终使用 ABI v2;不要因为 CSR 的 __BACKTICK_PLACEHOLDER_329__ 小于 5 就部署只有 __BACKTICK_PLACEHOLDER_330__ 的驱动。
## 4. 日志说明
### 4.1 一键日志收集
系统一键日志通常把运行日志放在 __BACKTICK_PLACEHOLDER_331__,把组件 dump 放在 __BACKTICK_PLACEHOLDER_332__。不同版本的收集器可能额外增加实例目录,定位时应优先按文件名搜索。
| 文件路径/文件名 | 产生方 | 内容说明 |
| :--- | :--- | :--- |
| __BACKTICK_PLACEHOLDER_333__ | 系统日志收集 | devmon、hwdiscovery、hwproxy 的运行日志;目标机实时文件通常为 __BACKTICK_PLACEHOLDER_334__ |
| __BACKTICK_PLACEHOLDER_335__ | devmon | 当前设备拓扑和对象层级 |
| __BACKTICK_PLACEHOLDER_336__ | devmon | Scanner/Accessor 运行快照,包括周期、状态、成功/失败计数、值和错误信息 |
| __BACKTICK_PLACEHOLDER_337__ | devmon | 驱动库加载状态、耗时、设备数和错误信息 |
| __BACKTICK_PLACEHOLDER_338__ | devmon | 芯片读写成功/失败次数、访问耗时和错误记录;Release 构建可能不生成 |
| __BACKTICK_PLACEHOLDER_339__ | hwproxy | 三层架构硬件代理对象拓扑 |
| __BACKTICK_PLACEHOLDER_340__ | hwproxy | 三层架构 Accessor/Scanner 快照 |
| __BACKTICK_PLACEHOLDER_341__ | hwproxy | SmcDfxInfo 配置和最近数据 |
| __BACKTICK_PLACEHOLDER_342__ | hwproxy | 三层架构芯片访问统计;Release 构建可能不生成 |
| __BACKTICK_PLACEHOLDER_343__ | hwdiscovery | Connector 树、位置、源路径、在位状态、识别方式等 |
| __BACKTICK_PLACEHOLDER_344__ | hwdiscovery | 当前使用的根 CSR;源文件不可用时该文件可能缺失并记录告警 |
| __BACKTICK_PLACEHOLDER_345__ | hwdiscovery | 当前平台 CSR |
| __BACKTICK_PLACEHOLDER_346__ / __BACKTICK_PLACEHOLDER_347__ | hwdiscovery | 各 Connector 的实际 CSR/二进制源文件副本 |
| __BACKTICK_PLACEHOLDER_348__ | hwdiscovery | Connector 关联的软件 CSR(存在时) |
| __BACKTICK_PLACEHOLDER_349__ | hwdiscovery | 满足条件的 EEPROM 备份,单次最多复制 65 个 |
| __BACKTICK_PLACEHOLDER_350__、__BACKTICK_PLACEHOLDER_351__ | devmon 特定对象 | JBOG 相关运行信息;仅对应对象和场景存在时生成 |
快速查找:
__BACKTICK_PLACEHOLDER_352__
### 4.2 关键日志信息
| 日志片段 | 日志级别 | 含义解读 | 建议处理动作 |
| :--- | :--- | :--- | :--- |
| __BACKTICK_PLACEHOLDER_353__ | INFO | 当前为单架构 | 使用 __BACKTICK_PLACEHOLDER_354__,驱动按 ABI v2 检查 |
| __BACKTICK_PLACEHOLDER_355__ | INFO | 当前为三层架构 | 同时检查 devmon、hwdiscovery、hwproxy |
| __BACKTICK_PLACEHOLDER_356__ | INFO | 服务配置和基础初始化完成 | 继续确认 root 对象及启动日志 |
| __BACKTICK_PLACEHOLDER_357__ | INFO | devmon 根对象已注册 | 可执行 __BACKTICK_PLACEHOLDER_358__ |
| __BACKTICK_PLACEHOLDER_359__ | INFO | devmon 服务进入启动阶段 | 无 |
| __BACKTICK_PLACEHOLDER_360__ | INFO | hwproxy 根对象完成 | 三层架构硬件代理可用 |
| __BACKTICK_PLACEHOLDER_361__ | INFO | hwproxy 已启动 | 无 |
| __BACKTICK_PLACEHOLDER_362__ | INFO | hwdiscovery 已启动 | 等待异步 CSR 全量发现完成 |
| __BACKTICK_PLACEHOLDER_363__ | INFO | 应用启动完成 | 无 |
| __BACKTICK_PLACEHOLDER_364__ | INFO | CSR1 请求被转发到发现层 | 到 hwdiscovery 日志继续跟踪 |
| __BACKTICK_PLACEHOLDER_365__ | INFO | CSR1 卸载被转发 | 检查子 position 是否级联清理 |
| __BACKTICK_PLACEHOLDER_366__ | WARN | 同一位置已存在,重复添加被忽略 | 先 RemoveDevice,或使用新 GroupPosition |
| __BACKTICK_PLACEHOLDER_367__ | INFO | 正在尝试加载候选动态库 | 核对库路径和 ABI |
| __BACKTICK_PLACEHOLDER_368__ | INFO | 驱动加载并缓存成功 | 继续确认 init/start 和对象创建 |
| __BACKTICK_PLACEHOLDER_369__ | NOTICE | 本地添加流程完成 | 检查 ObjectGroup 和对象属性 |
| __BACKTICK_PLACEHOLDER_370__ | ERROR/异常 | CSR 文件无法读取 | 检查路径、权限和部署 |
| __BACKTICK_PLACEHOLDER_371__ | ERROR/异常 | AddDeviceWithData 的变体类型错误 | 改传 JSON 字符串或字典 |
| __BACKTICK_PLACEHOLDER_372__ | ERROR/异常 | 缺少有效 GroupPosition | 修改调用参数 |
| __BACKTICK_PLACEHOLDER_373__ | WARN | FormatVersion 非法,已回退 5.00 | 修正版本格式,避免路由与预期不一致 |
| __BACKTICK_PLACEHOLDER_374__ | ERROR/异常 | __BACKTICK_PLACEHOLDER_375__ 为空 | 补齐设备类 |
| __BACKTICK_PLACEHOLDER_376__ | ERROR/异常 | __BACKTICK_PLACEHOLDER_377__ 为空 | 补齐实例名 |
| __BACKTICK_PLACEHOLDER_378__ | ERROR/异常 | __BACKTICK_PLACEHOLDER_379__ 为空 | 补齐驱动候选 |
| __BACKTICK_PLACEHOLDER_380__ | ERROR/异常 | CSR 没有对象定义 | 补齐 Objects |
| __BACKTICK_PLACEHOLDER_381__ | ERROR | __BACKTICK_PLACEHOLDER_382__ 对应对象不存在 | 确保 Objects 含同名键 |
| __BACKTICK_PLACEHOLDER_383__ | ERROR/异常 | 非空管理拓扑缺少 Anchor | 配置 __BACKTICK_PLACEHOLDER_384__ 或删除管理拓扑 |
| __BACKTICK_PLACEHOLDER_385__ | ERROR/异常 | __BACKTICK_PLACEHOLDER_386__ 失败 | 用 __BACKTICK_PLACEHOLDER_387__、架构、权限和库名排查 |
| __BACKTICK_PLACEHOLDER_388__ | ERROR/异常 | 缺少 __BACKTICK_PLACEHOLDER_389__ 导出符号 | 检查 __BACKTICK_PLACEHOLDER_390__ 和 __BACKTICK_PLACEHOLDER_391__ |
| __BACKTICK_PLACEHOLDER_392__ | ERROR/异常 | 注册函数返回非 0 | 修正注册函数参数和返回值 |
| __BACKTICK_PLACEHOLDER_393__ | ERROR/异常 | 所有 Compatible 候选都失败 | 核对 Compatible、库名和 ABI |
| __BACKTICK_PLACEHOLDER_394__ / __BACKTICK_PLACEHOLDER_395__ | ERROR | 驱动实例或对象注册失败 | 查看前序驱动/CSR日志和异常堆栈 |
| __BACKTICK_PLACEHOLDER_396__ | ERROR | devmon 拓扑根对象缺失,访问统计无法导出 | 检查启动完整性和异常重启 |
| __BACKTICK_PLACEHOLDER_397__ | WARN | 一键日志找不到某个 CSR/备份源文件 | 核对源路径;不一定代表运行故障 |
| __BACKTICK_PLACEHOLDER_398__ | INFO | 驱动加载记录导出成功 | 查看 CSV |
| __BACKTICK_PLACEHOLDER_399__ | NOTICE | Connector dump 完成 | 查看 connectors.txt 和 CSR 副本 |
默认日志级别为 __BACKTICK_PLACEHOLDER_400__。三层架构中 __BACKTICK_PLACEHOLDER_401__、__BACKTICK_PLACEHOLDER_402__、__BACKTICK_PLACEHOLDER_403__ 日志域均默认使用 __BACKTICK_PLACEHOLDER_404__。
### 4.3 调试日志与南向追踪
进入 mdbctl:
__BACKTICK_PLACEHOLDER_405__
常用命令:
__BACKTICK_PLACEHOLDER_406__
读取块设备/EEPROM 的示例:
__BACKTICK_PLACEHOLDER_407__
正常响应类型为 __BACKTICK_PLACEHOLDER_408__,后跟读取长度和二进制数据。该命令仅适用于目标对象确实暴露 __BACKTICK_PLACEHOLDER_409__ 接口的三层架构环境。
## 5. 问题定界指南
### 5.1 典型问题定界
| 现象描述 | 是否为本组件问题 | 判断依据 | 关键证据收集方法 |
| :--- | :--- | :--- | :--- |
| __BACKTICK_PLACEHOLDER_410__ 服务不存在 | 通常是部署、依赖或启动问题,可能属于 devmon 集成问题 | __BACKTICK_PLACEHOLDER_411__ 无服务名,systemd 状态异常 | __BACKTICK_PLACEHOLDER_412__、__BACKTICK_PLACEHOLDER_413__、__BACKTICK_PLACEHOLDER_414__ |
| AddDevice 报 __BACKTICK_PLACEHOLDER_415__ | 是,属于调用参数问题 | 当前接口只从 __BACKTICK_PLACEHOLDER_416__ 生成对象组位置 | 保存完整 busctl 命令和 D-Bus 异常 |
| AddDevice 无输出,但对象已创建 | 否,属于 void 方法正常表现 | 方法没有返回参数,ObjectGroup 和成功日志存在 | __BACKTICK_PLACEHOLDER_417__、对象树、__BACKTICK_PLACEHOLDER_418__ |
| 重复添加后对象未刷新 | 否,属于接口幂等/防重复行为 | 日志出现 __BACKTICK_PLACEHOLDER_419__ | 搜索该日志;先卸载再加载 |
| CSR 校验错误 | 通常是 CSR 配置问题 | Unit/Objects/Anchor 日志明确指出缺失字段 | 原始 CSR、__BACKTICK_PLACEHOLDER_420__ 结果、关键错误日志 |
| __BACKTICK_PLACEHOLDER_421__ | 可能是驱动包或依赖问题 | __BACKTICK_PLACEHOLDER_422__ 失败,未进入驱动注册 | 驱动路径、__BACKTICK_PLACEHOLDER_423__、__BACKTICK_PLACEHOLDER_424__、__BACKTICK_PLACEHOLDER_425__、drivers_load_info.csv |
| __BACKTICK_PLACEHOLDER_426__ | 是驱动 ABI 接口问题 | 动态库缺少导出符号 | __BACKTICK_PLACEHOLDER_427__ |
| __BACKTICK_PLACEHOLDER_428__ 返回空数组 | 不一定 | owner 不匹配、发现未完成或 CSR 没有该 owner 数据 | 读取 __BACKTICK_PLACEHOLDER_429__、connectors.txt、ObjectGroup 属性和 app.log |
| __BACKTICK_PLACEHOLDER_430__ | 不一定 | 可能选错单架构/三层架构路径,或设备添加失败 | 查看架构日志和两个 ObjectGroup 根路径 |
| 三层架构 CSR1 不加载 | 可能是发现链路问题 | devmon 已转发,但 hwdiscovery/hwproxy 未就绪或 CSR1 驱动缺失 | 三个服务状态、转发日志、connectors.txt、ABI v1 驱动 |
| 对象存在但芯片读取失败 | 可能属于驱动、总线或硬件问题 | 对象注册成功,不代表底层总线可访问 | tracechip、chips_access_statistic.csv、硬件代理日志 |
| 一键日志没有 __BACKTICK_PLACEHOLDER_431__ | 不一定 | Release 构建可不输出该统计 | 核对构建类型和其他 dump 文件 |
| devmon 周期性重启 | 是或依赖问题 | systemd 配置 __BACKTICK_PLACEHOLDER_432__,崩溃后会自动拉起 | __BACKTICK_PLACEHOLDER_433__、coredump、journal、MemoryCurrent、依赖版本 |
| 仅某个位置卸载后其他共享总线对象消失 | 可能是对象归属/版本问题 | 卸载逻辑应只注销本 position 拥有的对象 | 记录卸载前后对象树、版本、app.log 和 CSR |
### 5.2 错误码速查表
#### D-Bus/解析错误
| 错误/日志 | 含义 | 可能原因 | 排查建议 |
| :--- | :--- | :--- | :--- |
| __BACKTICK_PLACEHOLDER_434__ | D-Bus 服务不存在 | devmon 未启动、服务未注册或环境变量/总线不正确 | 检查 systemd、用户 D-Bus 会话和服务列表 |
| __BACKTICK_PLACEHOLDER_435__ | 对象路径不存在 | 路径选错、设备未加载、已卸载 | 按架构重新 __BACKTICK_PLACEHOLDER_436__ |
| __BACKTICK_PLACEHOLDER_437__ | 接口名错误 | 混用了 __BACKTICK_PLACEHOLDER_438__ 与 __BACKTICK_PLACEHOLDER_439__ | 先 __BACKTICK_PLACEHOLDER_440__ |
| __BACKTICK_PLACEHOLDER_441__ / 签名不匹配 | D-Bus 参数格式错误 | 字典数量、Variant 类型或签名不正确 | 对照第 2 章逐项检查 |
| __BACKTICK_PLACEHOLDER_442__ | 无有效位置 | GroupPosition 缺失/空 | 传 __BACKTICK_PLACEHOLDER_443__ |
| __BACKTICK_PLACEHOLDER_444__ | CSR 变体类型错误 | AddDeviceWithData 传了非 string/dict | 用 __BACKTICK_PLACEHOLDER_445__ |
| __BACKTICK_PLACEHOLDER_446__ | Unit 字段为空 | CSR 不完整 | 补齐 Unit |
| __BACKTICK_PLACEHOLDER_447__ | Objects 为空 | CSR 不完整 | 添加对象定义 |
| __BACKTICK_PLACEHOLDER_448__ | 拓扑缺 Anchor | 非空拓扑不完整 | 补 Anchor/Buses |
| __BACKTICK_PLACEHOLDER_449__ | 驱动候选全部失败 | Compatible、文件名、ABI 或部署错误 | 依次核对候选库 |
#### 驱动 ABI 状态码
| 错误码 | 含义 | 可能原因 | 排查建议 |
| :--- | :--- | :--- | :--- |
| 0 __BACKTICK_PLACEHOLDER_450__ | 成功 | 正常 | 无 |
| 1 __BACKTICK_PLACEHOLDER_451__ | 通用错误 | 驱动内部失败 | 查看驱动日志和 dump |
| 2 __BACKTICK_PLACEHOLDER_452__ | 目标不存在 | 芯片、通道或资源不存在 | 核对 CSR 和硬件在位 |
| 3 __BACKTICK_PLACEHOLDER_453__ | 参数非法 | CSR/Connector 值不支持 | 打印输入并校验类型/范围 |
| 4 __BACKTICK_PLACEHOLDER_454__ | 未实现 | 驱动不支持该操作 | 使用替代能力或补充实现 |
| 5 __BACKTICK_PLACEHOLDER_455__ | 超时 | 总线无响应、设备忙 | tracechip,检查链路和时序 |
| 6 __BACKTICK_PLACEHOLDER_456__ | 资源忙 | 并发访问或状态机未就绪 | 降低并发、稍后重试 |
| 7 __BACKTICK_PLACEHOLDER_457__ | 内存不足 | 分配失败或泄漏 | 检查 MemoryCurrent、coredump 和长期增长 |
### 5.3 调试方法
#### 开启调试日志
先确认当前服务和日志域,再用 mdbctl 调整级别:
__BACKTICK_PLACEHOLDER_458__
三层架构需要分别对 __BACKTICK_PLACEHOLDER_459__、__BACKTICK_PLACEHOLDER_460__、__BACKTICK_PLACEHOLDER_461__ 检查或设置。定位完成后恢复默认级别,避免长期产生大量日志。
#### 分层排查步骤
##### 1. 确认进程和资源限制
__BACKTICK_PLACEHOLDER_462__
目标 service 配置为 __BACKTICK_PLACEHOLDER_463__、__BACKTICK_PLACEHOLDER_464__、__BACKTICK_PLACEHOLDER_465__,工作目录 __BACKTICK_PLACEHOLDER_466__,执行文件 __BACKTICK_PLACEHOLDER_467__。
##### 2. 确认 D-Bus 服务和架构
__BACKTICK_PLACEHOLDER_468__
##### 3. 确认根接口
__BACKTICK_PLACEHOLDER_469__
应至少看到 __BACKTICK_PLACEHOLDER_470__、__BACKTICK_PLACEHOLDER_471__ 和 __BACKTICK_PLACEHOLDER_472__。
##### 4. 校验 CSR
__BACKTICK_PLACEHOLDER_473__
检查:
- __BACKTICK_PLACEHOLDER_474__、__BACKTICK_PLACEHOLDER_475__、__BACKTICK_PLACEHOLDER_476__ 非空;
- __BACKTICK_PLACEHOLDER_477__ 非空,且含 __BACKTICK_PLACEHOLDER_478__ 对应对象;
- 配置了 __BACKTICK_PLACEHOLDER_479__ 时含 __BACKTICK_PLACEHOLDER_480__;
- 需要总线映射时 __BACKTICK_PLACEHOLDER_481__ 和 Connector 的 __BACKTICK_PLACEHOLDER_482__ 数量/顺序匹配;
- __BACKTICK_PLACEHOLDER_483__ 与部署驱动 ABI 一致。
##### 5. 校验驱动
__BACKTICK_PLACEHOLDER_484__
##### 6. 跟踪一次 AddDevice
__BACKTICK_PLACEHOLDER_485__
判断顺序:参数规范化 → FormatVersion 路由 → CSR 校验 → 驱动加载 → 对象创建 → ObjectGroup → 成功日志。
##### 7. 检查对象组
__BACKTICK_PLACEHOLDER_486__
若路径存在但 __BACKTICK_PLACEHOLDER_487__ 为空,先读 __BACKTICK_PLACEHOLDER_488__;若路径根本不存在,回到 CSR/驱动/转发日志。
##### 8. 检查一键日志证据
__BACKTICK_PLACEHOLDER_489__
##### 9. 检查硬件访问
- 在 mdbctl 中 __BACKTICK_PLACEHOLDER_490__。
- 使用 __BACKTICK_PLACEHOLDER_491__ 追踪目标芯片。
- 对 Scanner 使用 __BACKTICK_PLACEHOLDER_492__。
- 查看 __BACKTICK_PLACEHOLDER_493__ 的失败计数和 Error_Recording。
- 对暴露 BlockIO 的对象执行 __BACKTICK_PLACEHOLDER_494__,区分“对象创建成功”与“底层读写成功”。
#### 复现问题方法
下面流程可复现和隔离“最小 CSR 加载失败”问题:
1. 准备一个只包含单个 __BACKTICK_PLACEHOLDER_495__ 和同名 __BACKTICK_PLACEHOLDER_496__ 的 CSR,使用 __BACKTICK_PLACEHOLDER_497__,并部署匹配的 ABI v2 驱动。
2. 选择未使用的 __BACKTICK_PLACEHOLDER_498__,如 __BACKTICK_PLACEHOLDER_499__。
3. 记录调用前 __BACKTICK_PLACEHOLDER_500__、D-Bus 对象树和 app.log 末尾。
4. 调用 __BACKTICK_PLACEHOLDER_501__。
5. 检查返回码、驱动加载日志和 __BACKTICK_PLACEHOLDER_502__。
6. 调用 __BACKTICK_PLACEHOLDER_503__/__BACKTICK_PLACEHOLDER_504__,保存完整响应。
7. 调用 __BACKTICK_PLACEHOLDER_505__,确认对象清理。
预期现象:驱动加载成功、出现 __BACKTICK_PLACEHOLDER_506__、ObjectGroup 可查询,卸载后路径消失。若最小 CSR 成功而业务 CSR 失败,问题主要落在业务 CSR、目标驱动或拓扑映射;若最小 CSR 也失败,优先检查组件部署、ABI 和依赖环境。
## 6. 常见问题解答
### Q1:Connector 里传了 Position,为什么仍报位置未初始化?
- **问题描述**:旧示例使用 __BACKTICK_PLACEHOLDER_507__,当前代码抛出 __BACKTICK_PLACEHOLDER_508__。
- **一句话答案**:当前动态添加/删除接口必须传 __BACKTICK_PLACEHOLDER_509__。
- **根因说明**:源码从 __BACKTICK_PLACEHOLDER_510__ 生成对象组位置,__BACKTICK_PLACEHOLDER_511__ 只是其他业务字段,不能替代。
- **解决方案**:把调用参数改为 __BACKTICK_PLACEHOLDER_512__。
- **规避方案**:所有新脚本统一使用本文命令模板。
- **适用版本**:devmon 1.2.94。
### Q2:数值 GroupPosition 最终会变成什么?
- **问题描述**:调用传整数后,对象路径不是十进制数字。
- **一句话答案**:整数会转为大写十六进制,至少 2 位并补成偶数长度。
- **根因说明**:位置用于层级拼接和对象组命名,需要稳定的十六进制表示。
- **解决方案**:例如 __BACKTICK_PLACEHOLDER_513__、__BACKTICK_PLACEHOLDER_514__、__BACKTICK_PLACEHOLDER_515__;希望完全控制格式时直接传字符串。
- **规避方案**:添加和删除时使用同一种表示。
- **适用版本**:devmon 1.2.94。
### Q3:同一 GroupPosition 再次 AddDevice 会覆盖旧设备吗?
- **问题描述**:修改 CSR 后重复调用,运行对象没有变化。
- **一句话答案**:不会覆盖,重复位置会直接跳过。
- **根因说明**:devmon 在解析和创建前检查 position 是否已存在,防止重复实例。
- **解决方案**:先 __BACKTICK_PLACEHOLDER_516__,再重新 __BACKTICK_PLACEHOLDER_517__。
- **规避方案**:更新流程显式执行卸载—确认清理—重新加载。
- **适用版本**:devmon 1.2.94。
### Q4:如何判断当前应使用哪个 ObjectGroup 路径?
- **问题描述**:访问 __BACKTICK_PLACEHOLDER_518__ 或 __BACKTICK_PLACEHOLDER_519__ 时出现 UnknownObject。
- **一句话答案**:单架构/CSR2 使用前者,三层架构 CSR1 使用后者。
- **根因说明**:三层架构把旧格式 CSR 的发现结果放在 hwdiscovery 服务。
- **解决方案**:查看 __BACKTICK_PLACEHOLDER_520__ 和 CSR __BACKTICK_PLACEHOLDER_521__,再执行对应 __BACKTICK_PLACEHOLDER_522__。
- **规避方案**:脚本先探测两个服务和根路径。
- **适用版本**:支持 unidev 的 devmon 版本,本文以 1.2.94 为准。
## 附录
### 附录 A 修订记录
| 版本 | 日期 | 修订人 | 修订内容 |
| :--- | :--- | :--- | :--- |
| 1.2.94 | 2026-08-24 | | 创建 devmon 组件说明,补充组件概述、D-Bus API、驱动/CSR 扩展、日志、问题定界和 FAQ |示例代码验证方法
- BACKTICK_PLACEHOLDER_309 能找到全局符号 BACKTICK_PLACEHOLDER_310。
- BACKTICK_PLACEHOLDER_311 不出现 BACKTICK_PLACEHOLDER_312。
- BACKTICK_PLACEHOLDER_313 返回码为 0,日志出现 BACKTICK_PLACEHOLDER_314、BACKTICK_PLACEHOLDER_315 和 BACKTICK_PLACEHOLDER_316。
- BACKTICK_PLACEHOLDER_317 存在,属性和 owner 符合 CSR 预期。
- 一键日志中的 BACKTICK_PLACEHOLDER_318 显示该驱动 BACKTICK_PLACEHOLDER_319。
- BACKTICK_PLACEHOLDER_320 后 ObjectGroup 和本位置设备对象消失,驱动 BACKTICK_PLACEHOLDER_321 已执行。
注意事项
- 驱动库文件名、BACKTICK_PLACEHOLDER_322 归一化名称和 ABI 必须一致。
- BACKTICK_PLACEHOLDER_323 必须使用 BACKTICK_PLACEHOLDER_324,避免 C++ 名字改编导致 BACKTICK_PLACEHOLDER_325 失败。
- BACKTICK_PLACEHOLDER_326 返回的驱动表及其中字符串、函数指针必须在库生命周期内持续有效。
- BACKTICK_PLACEHOLDER_327 返回的是借用指针,调用方会立即复制;驱动不得返回已经释放的临时字符串地址。
- 驱动的 BACKTICK_PLACEHOLDER_328 应可重复、安全地终止线程、定时器和 I/O,避免卸载残留。
- 多实例驱动不得用未加锁的全局可变状态保存单个设备上下文。
- 修改驱动后应先卸载旧设备;已缓存的动态库通常需要重启组件或使用全新版本/环境才能确保重新加载。
- 单架构始终使用 ABI v2;不要因为 CSR 的 BACKTICK_PLACEHOLDER_329 小于 5 就部署只有 BACKTICK_PLACEHOLDER_330 的驱动。
4. 日志说明
4.1 一键日志收集
系统一键日志通常把运行日志放在 BACKTICK_PLACEHOLDER_331,把组件 dump 放在 BACKTICK_PLACEHOLDER_332。不同版本的收集器可能额外增加实例目录,定位时应优先按文件名搜索。
| 文件路径/文件名 | 产生方 | 内容说明 |
|---|---|---|
| BACKTICK_PLACEHOLDER_333 | 系统日志收集 | devmon、hwdiscovery、hwproxy 的运行日志;目标机实时文件通常为 BACKTICK_PLACEHOLDER_334 |
| BACKTICK_PLACEHOLDER_335 | devmon | 当前设备拓扑和对象层级 |
| BACKTICK_PLACEHOLDER_336 | devmon | Scanner/Accessor 运行快照,包括周期、状态、成功/失败计数、值和错误信息 |
| BACKTICK_PLACEHOLDER_337 | devmon | 驱动库加载状态、耗时、设备数和错误信息 |
| BACKTICK_PLACEHOLDER_338 | devmon | 芯片读写成功/失败次数、访问耗时和错误记录;Release 构建可能不生成 |
| BACKTICK_PLACEHOLDER_339 | hwproxy | 三层架构硬件代理对象拓扑 |
| BACKTICK_PLACEHOLDER_340 | hwproxy | 三层架构 Accessor/Scanner 快照 |
| BACKTICK_PLACEHOLDER_341 | hwproxy | SmcDfxInfo 配置和最近数据 |
| BACKTICK_PLACEHOLDER_342 | hwproxy | 三层架构芯片访问统计;Release 构建可能不生成 |
| BACKTICK_PLACEHOLDER_343 | hwdiscovery | Connector 树、位置、源路径、在位状态、识别方式等 |
| BACKTICK_PLACEHOLDER_344 | hwdiscovery | 当前使用的根 CSR;源文件不可用时该文件可能缺失并记录告警 |
| BACKTICK_PLACEHOLDER_345 | hwdiscovery | 当前平台 CSR |
| BACKTICK_PLACEHOLDER_346 / BACKTICK_PLACEHOLDER_347 | hwdiscovery | 各 Connector 的实际 CSR/二进制源文件副本 |
| BACKTICK_PLACEHOLDER_348 | hwdiscovery | Connector 关联的软件 CSR(存在时) |
| BACKTICK_PLACEHOLDER_349 | hwdiscovery | 满足条件的 EEPROM 备份,单次最多复制 65 个 |
| BACKTICK_PLACEHOLDER_350、BACKTICK_PLACEHOLDER_351 | devmon 特定对象 | JBOG 相关运行信息;仅对应对象和场景存在时生成 |
快速查找:
BACKTICK_PLACEHOLDER_352
4.2 关键日志信息
| 日志片段 | 日志级别 | 含义解读 | 建议处理动作 |
|---|---|---|---|
| BACKTICK_PLACEHOLDER_353 | INFO | 当前为单架构 | 使用 BACKTICK_PLACEHOLDER_354,驱动按 ABI v2 检查 |
| BACKTICK_PLACEHOLDER_355 | INFO | 当前为三层架构 | 同时检查 devmon、hwdiscovery、hwproxy |
| BACKTICK_PLACEHOLDER_356 | INFO | 服务配置和基础初始化完成 | 继续确认 root 对象及启动日志 |
| BACKTICK_PLACEHOLDER_357 | INFO | devmon 根对象已注册 | 可执行 BACKTICK_PLACEHOLDER_358 |
| BACKTICK_PLACEHOLDER_359 | INFO | devmon 服务进入启动阶段 | 无 |
| BACKTICK_PLACEHOLDER_360 | INFO | hwproxy 根对象完成 | 三层架构硬件代理可用 |
| BACKTICK_PLACEHOLDER_361 | INFO | hwproxy 已启动 | 无 |
| BACKTICK_PLACEHOLDER_362 | INFO | hwdiscovery 已启动 | 等待异步 CSR 全量发现完成 |
| BACKTICK_PLACEHOLDER_363 | INFO | 应用启动完成 | 无 |
| BACKTICK_PLACEHOLDER_364 | INFO | CSR1 请求被转发到发现层 | 到 hwdiscovery 日志继续跟踪 |
| BACKTICK_PLACEHOLDER_365 | INFO | CSR1 卸载被转发 | 检查子 position 是否级联清理 |
| BACKTICK_PLACEHOLDER_366 | WARN | 同一位置已存在,重复添加被忽略 | 先 RemoveDevice,或使用新 GroupPosition |
| BACKTICK_PLACEHOLDER_367 | INFO | 正在尝试加载候选动态库 | 核对库路径和 ABI |
| BACKTICK_PLACEHOLDER_368 | INFO | 驱动加载并缓存成功 | 继续确认 init/start 和对象创建 |
| BACKTICK_PLACEHOLDER_369 | NOTICE | 本地添加流程完成 | 检查 ObjectGroup 和对象属性 |
| BACKTICK_PLACEHOLDER_370 | ERROR/异常 | CSR 文件无法读取 | 检查路径、权限和部署 |
| BACKTICK_PLACEHOLDER_371 | ERROR/异常 | AddDeviceWithData 的变体类型错误 | 改传 JSON 字符串或字典 |
| BACKTICK_PLACEHOLDER_372 | ERROR/异常 | 缺少有效 GroupPosition | 修改调用参数 |
| BACKTICK_PLACEHOLDER_373 | WARN | FormatVersion 非法,已回退 5.00 | 修正版本格式,避免路由与预期不一致 |
| BACKTICK_PLACEHOLDER_374 | ERROR/异常 | BACKTICK_PLACEHOLDER_375 为空 | 补齐设备类 |
| BACKTICK_PLACEHOLDER_376 | ERROR/异常 | BACKTICK_PLACEHOLDER_377 为空 | 补齐实例名 |
| BACKTICK_PLACEHOLDER_378 | ERROR/异常 | BACKTICK_PLACEHOLDER_379 为空 | 补齐驱动候选 |
| BACKTICK_PLACEHOLDER_380 | ERROR/异常 | CSR 没有对象定义 | 补齐 Objects |
| BACKTICK_PLACEHOLDER_381 | ERROR | BACKTICK_PLACEHOLDER_382 对应对象不存在 | 确保 Objects 含同名键 |
| BACKTICK_PLACEHOLDER_383 | ERROR/异常 | 非空管理拓扑缺少 Anchor | 配置 BACKTICK_PLACEHOLDER_384 或删除管理拓扑 |
| BACKTICK_PLACEHOLDER_385 | ERROR/异常 | BACKTICK_PLACEHOLDER_386 失败 | 用 BACKTICK_PLACEHOLDER_387、架构、权限和库名排查 |
| BACKTICK_PLACEHOLDER_388 | ERROR/异常 | 缺少 BACKTICK_PLACEHOLDER_389 导出符号 | 检查 BACKTICK_PLACEHOLDER_390 和 BACKTICK_PLACEHOLDER_391 |
| BACKTICK_PLACEHOLDER_392 | ERROR/异常 | 注册函数返回非 0 | 修正注册函数参数和返回值 |
| BACKTICK_PLACEHOLDER_393 | ERROR/异常 | 所有 Compatible 候选都失败 | 核对 Compatible、库名和 ABI |
| BACKTICK_PLACEHOLDER_394 / BACKTICK_PLACEHOLDER_395 | ERROR | 驱动实例或对象注册失败 | 查看前序驱动/CSR日志和异常堆栈 |
| BACKTICK_PLACEHOLDER_396 | ERROR | devmon 拓扑根对象缺失,访问统计无法导出 | 检查启动完整性和异常重启 |
| BACKTICK_PLACEHOLDER_397 | WARN | 一键日志找不到某个 CSR/备份源文件 | 核对源路径;不一定代表运行故障 |
| BACKTICK_PLACEHOLDER_398 | INFO | 驱动加载记录导出成功 | 查看 CSV |
| BACKTICK_PLACEHOLDER_399 | NOTICE | Connector dump 完成 | 查看 connectors.txt 和 CSR 副本 |
默认日志级别为 BACKTICK_PLACEHOLDER_400。三层架构中 BACKTICK_PLACEHOLDER_401、BACKTICK_PLACEHOLDER_402、BACKTICK_PLACEHOLDER_403 日志域均默认使用 BACKTICK_PLACEHOLDER_404。
4.3 调试日志与南向追踪
进入 mdbctl:
BACKTICK_PLACEHOLDER_405
常用命令:
BACKTICK_PLACEHOLDER_406
读取块设备/EEPROM 的示例:
BACKTICK_PLACEHOLDER_407
正常响应类型为 BACKTICK_PLACEHOLDER_408,后跟读取长度和二进制数据。该命令仅适用于目标对象确实暴露 BACKTICK_PLACEHOLDER_409 接口的三层架构环境。
5. 问题定界指南
5.1 典型问题定界
| 现象描述 | 是否为本组件问题 | 判断依据 | 关键证据收集方法 |
|---|---|---|---|
| BACKTICK_PLACEHOLDER_410 服务不存在 | 通常是部署、依赖或启动问题,可能属于 devmon 集成问题 | BACKTICK_PLACEHOLDER_411 无服务名,systemd 状态异常 | BACKTICK_PLACEHOLDER_412、BACKTICK_PLACEHOLDER_413、BACKTICK_PLACEHOLDER_414 |
| AddDevice 报 BACKTICK_PLACEHOLDER_415 | 是,属于调用参数问题 | 当前接口只从 BACKTICK_PLACEHOLDER_416 生成对象组位置 | 保存完整 busctl 命令和 D-Bus 异常 |
| AddDevice 无输出,但对象已创建 | 否,属于 void 方法正常表现 | 方法没有返回参数,ObjectGroup 和成功日志存在 | BACKTICK_PLACEHOLDER_417、对象树、BACKTICK_PLACEHOLDER_418 |
| 重复添加后对象未刷新 | 否,属于接口幂等/防重复行为 | 日志出现 BACKTICK_PLACEHOLDER_419 | 搜索该日志;先卸载再加载 |
| CSR 校验错误 | 通常是 CSR 配置问题 | Unit/Objects/Anchor 日志明确指出缺失字段 | 原始 CSR、BACKTICK_PLACEHOLDER_420 结果、关键错误日志 |
| BACKTICK_PLACEHOLDER_421 | 可能是驱动包或依赖问题 | BACKTICK_PLACEHOLDER_422 失败,未进入驱动注册 | 驱动路径、BACKTICK_PLACEHOLDER_423、BACKTICK_PLACEHOLDER_424、BACKTICK_PLACEHOLDER_425、drivers_load_info.csv |
| BACKTICK_PLACEHOLDER_426 | 是驱动 ABI 接口问题 | 动态库缺少导出符号 | BACKTICK_PLACEHOLDER_427 |
| BACKTICK_PLACEHOLDER_428 返回空数组 | 不一定 | owner 不匹配、发现未完成或 CSR 没有该 owner 数据 | 读取 BACKTICK_PLACEHOLDER_429、connectors.txt、ObjectGroup 属性和 app.log |
| BACKTICK_PLACEHOLDER_430 | 不一定 | 可能选错单架构/三层架构路径,或设备添加失败 | 查看架构日志和两个 ObjectGroup 根路径 |
| 三层架构 CSR1 不加载 | 可能是发现链路问题 | devmon 已转发,但 hwdiscovery/hwproxy 未就绪或 CSR1 驱动缺失 | 三个服务状态、转发日志、connectors.txt、ABI v1 驱动 |
| 对象存在但芯片读取失败 | 可能属于驱动、总线或硬件问题 | 对象注册成功,不代表底层总线可访问 | tracechip、chips_access_statistic.csv、硬件代理日志 |
| 一键日志没有 BACKTICK_PLACEHOLDER_431 | 不一定 | Release 构建可不输出该统计 | 核对构建类型和其他 dump 文件 |
| devmon 周期性重启 | 是或依赖问题 | systemd 配置 BACKTICK_PLACEHOLDER_432,崩溃后会自动拉起 | BACKTICK_PLACEHOLDER_433、coredump、journal、MemoryCurrent、依赖版本 |
| 仅某个位置卸载后其他共享总线对象消失 | 可能是对象归属/版本问题 | 卸载逻辑应只注销本 position 拥有的对象 | 记录卸载前后对象树、版本、app.log 和 CSR |
5.2 错误码速查表
D-Bus/解析错误
| 错误/日志 | 含义 | 可能原因 | 排查建议 |
|---|---|---|---|
| BACKTICK_PLACEHOLDER_434 | D-Bus 服务不存在 | devmon 未启动、服务未注册或环境变量/总线不正确 | 检查 systemd、用户 D-Bus 会话和服务列表 |
| BACKTICK_PLACEHOLDER_435 | 对象路径不存在 | 路径选错、设备未加载、已卸载 | 按架构重新 BACKTICK_PLACEHOLDER_436 |
| BACKTICK_PLACEHOLDER_437 | 接口名错误 | 混用了 BACKTICK_PLACEHOLDER_438 与 BACKTICK_PLACEHOLDER_439 | 先 BACKTICK_PLACEHOLDER_440 |
| BACKTICK_PLACEHOLDER_441 / 签名不匹配 | D-Bus 参数格式错误 | 字典数量、Variant 类型或签名不正确 | 对照第 2 章逐项检查 |
| BACKTICK_PLACEHOLDER_442 | 无有效位置 | GroupPosition 缺失/空 | 传 BACKTICK_PLACEHOLDER_443 |
| BACKTICK_PLACEHOLDER_444 | CSR 变体类型错误 | AddDeviceWithData 传了非 string/dict | 用 BACKTICK_PLACEHOLDER_445 |
| BACKTICK_PLACEHOLDER_446 | Unit 字段为空 | CSR 不完整 | 补齐 Unit |
| BACKTICK_PLACEHOLDER_447 | Objects 为空 | CSR 不完整 | 添加对象定义 |
| BACKTICK_PLACEHOLDER_448 | 拓扑缺 Anchor | 非空拓扑不完整 | 补 Anchor/Buses |
| BACKTICK_PLACEHOLDER_449 | 驱动候选全部失败 | Compatible、文件名、ABI 或部署错误 | 依次核对候选库 |
驱动 ABI 状态码
| 错误码 | 含义 | 可能原因 | 排查建议 |
|---|---|---|---|
| 0 BACKTICK_PLACEHOLDER_450 | 成功 | 正常 | 无 |
| 1 BACKTICK_PLACEHOLDER_451 | 通用错误 | 驱动内部失败 | 查看驱动日志和 dump |
| 2 BACKTICK_PLACEHOLDER_452 | 目标不存在 | 芯片、通道或资源不存在 | 核对 CSR 和硬件在位 |
| 3 BACKTICK_PLACEHOLDER_453 | 参数非法 | CSR/Connector 值不支持 | 打印输入并校验类型/范围 |
| 4 BACKTICK_PLACEHOLDER_454 | 未实现 | 驱动不支持该操作 | 使用替代能力或补充实现 |
| 5 BACKTICK_PLACEHOLDER_455 | 超时 | 总线无响应、设备忙 | tracechip,检查链路和时序 |
| 6 BACKTICK_PLACEHOLDER_456 | 资源忙 | 并发访问或状态机未就绪 | 降低并发、稍后重试 |
| 7 BACKTICK_PLACEHOLDER_457 | 内存不足 | 分配失败或泄漏 | 检查 MemoryCurrent、coredump 和长期增长 |
5.3 调试方法
开启调试日志
先确认当前服务和日志域,再用 mdbctl 调整级别:
BACKTICK_PLACEHOLDER_458
三层架构需要分别对 BACKTICK_PLACEHOLDER_459、BACKTICK_PLACEHOLDER_460、BACKTICK_PLACEHOLDER_461 检查或设置。定位完成后恢复默认级别,避免长期产生大量日志。
分层排查步骤
1. 确认进程和资源限制
BACKTICK_PLACEHOLDER_462
目标 service 配置为 BACKTICK_PLACEHOLDER_463、BACKTICK_PLACEHOLDER_464、BACKTICK_PLACEHOLDER_465,工作目录 BACKTICK_PLACEHOLDER_466,执行文件 BACKTICK_PLACEHOLDER_467。
2. 确认 D-Bus 服务和架构
BACKTICK_PLACEHOLDER_468
3. 确认根接口
BACKTICK_PLACEHOLDER_469
应至少看到 BACKTICK_PLACEHOLDER_470、BACKTICK_PLACEHOLDER_471 和 BACKTICK_PLACEHOLDER_472。
4. 校验 CSR
BACKTICK_PLACEHOLDER_473
检查:
- BACKTICK_PLACEHOLDER_474、BACKTICK_PLACEHOLDER_475、BACKTICK_PLACEHOLDER_476 非空;
- BACKTICK_PLACEHOLDER_477 非空,且含 BACKTICK_PLACEHOLDER_478 对应对象;
- 配置了 BACKTICK_PLACEHOLDER_479 时含 BACKTICK_PLACEHOLDER_480;
- 需要总线映射时 BACKTICK_PLACEHOLDER_481 和 Connector 的 BACKTICK_PLACEHOLDER_482 数量/顺序匹配;
- BACKTICK_PLACEHOLDER_483 与部署驱动 ABI 一致。
5. 校验驱动
BACKTICK_PLACEHOLDER_484
6. 跟踪一次 AddDevice
BACKTICK_PLACEHOLDER_485
判断顺序:参数规范化 → FormatVersion 路由 → CSR 校验 → 驱动加载 → 对象创建 → ObjectGroup → 成功日志。
7. 检查对象组
BACKTICK_PLACEHOLDER_486
若路径存在但 BACKTICK_PLACEHOLDER_487 为空,先读 BACKTICK_PLACEHOLDER_488;若路径根本不存在,回到 CSR/驱动/转发日志。
8. 检查一键日志证据
BACKTICK_PLACEHOLDER_489
9. 检查硬件访问
- 在 mdbctl 中 BACKTICK_PLACEHOLDER_490。
- 使用 BACKTICK_PLACEHOLDER_491 追踪目标芯片。
- 对 Scanner 使用 BACKTICK_PLACEHOLDER_492。
- 查看 BACKTICK_PLACEHOLDER_493 的失败计数和 Error_Recording。
- 对暴露 BlockIO 的对象执行 BACKTICK_PLACEHOLDER_494,区分“对象创建成功”与“底层读写成功”。
复现问题方法
下面流程可复现和隔离“最小 CSR 加载失败”问题:
- 准备一个只包含单个 BACKTICK_PLACEHOLDER_495 和同名 BACKTICK_PLACEHOLDER_496 的 CSR,使用 BACKTICK_PLACEHOLDER_497,并部署匹配的 ABI v2 驱动。
- 选择未使用的 BACKTICK_PLACEHOLDER_498,如 BACKTICK_PLACEHOLDER_499。
- 记录调用前 BACKTICK_PLACEHOLDER_500、D-Bus 对象树和 app.log 末尾。
- 调用 BACKTICK_PLACEHOLDER_501。
- 检查返回码、驱动加载日志和 BACKTICK_PLACEHOLDER_502。
- 调用 BACKTICK_PLACEHOLDER_503/BACKTICK_PLACEHOLDER_504,保存完整响应。
- 调用 BACKTICK_PLACEHOLDER_505,确认对象清理。
预期现象:驱动加载成功、出现 BACKTICK_PLACEHOLDER_506、ObjectGroup 可查询,卸载后路径消失。若最小 CSR 成功而业务 CSR 失败,问题主要落在业务 CSR、目标驱动或拓扑映射;若最小 CSR 也失败,优先检查组件部署、ABI 和依赖环境。
6. 常见问题解答
Q1:Connector 里传了 Position,为什么仍报位置未初始化?
- 问题描述:旧示例使用 BACKTICK_PLACEHOLDER_507,当前代码抛出 BACKTICK_PLACEHOLDER_508。
- 一句话答案:当前动态添加/删除接口必须传 BACKTICK_PLACEHOLDER_509。
- 根因说明:源码从 BACKTICK_PLACEHOLDER_510 生成对象组位置,BACKTICK_PLACEHOLDER_511 只是其他业务字段,不能替代。
- 解决方案:把调用参数改为 BACKTICK_PLACEHOLDER_512。
- 规避方案:所有新脚本统一使用本文命令模板。
- 适用版本:devmon 1.2.94。
Q2:数值 GroupPosition 最终会变成什么?
- 问题描述:调用传整数后,对象路径不是十进制数字。
- 一句话答案:整数会转为大写十六进制,至少 2 位并补成偶数长度。
- 根因说明:位置用于层级拼接和对象组命名,需要稳定的十六进制表示。
- 解决方案:例如 BACKTICK_PLACEHOLDER_513、BACKTICK_PLACEHOLDER_514、BACKTICK_PLACEHOLDER_515;希望完全控制格式时直接传字符串。
- 规避方案:添加和删除时使用同一种表示。
- 适用版本:devmon 1.2.94。
Q3:同一 GroupPosition 再次 AddDevice 会覆盖旧设备吗?
- 问题描述:修改 CSR 后重复调用,运行对象没有变化。
- 一句话答案:不会覆盖,重复位置会直接跳过。
- 根因说明:devmon 在解析和创建前检查 position 是否已存在,防止重复实例。
- 解决方案:先 BACKTICK_PLACEHOLDER_516,再重新 BACKTICK_PLACEHOLDER_517。
- 规避方案:更新流程显式执行卸载—确认清理—重新加载。
- 适用版本:devmon 1.2.94。
Q4:如何判断当前应使用哪个 ObjectGroup 路径?
- 问题描述:访问 BACKTICK_PLACEHOLDER_518 或 BACKTICK_PLACEHOLDER_519 时出现 UnknownObject。
- 一句话答案:单架构/CSR2 使用前者,三层架构 CSR1 使用后者。
- 根因说明:三层架构把旧格式 CSR 的发现结果放在 hwdiscovery 服务。
- 解决方案:查看 BACKTICK_PLACEHOLDER_520 和 CSR BACKTICK_PLACEHOLDER_521,再执行对应 BACKTICK_PLACEHOLDER_522。
- 规避方案:脚本先探测两个服务和根路径。
- 适用版本:支持 unidev 的 devmon 版本,本文以 1.2.94 为准。
附录
附录 A 修订记录
| 版本 | 日期 | 修订人 | 修订内容 |
|---|---|---|---|
| 1.2.94 | 2026-08-24 | 创建 devmon 组件说明,补充组件概述、D-Bus API、驱动/CSR 扩展、日志、问题定界和 FAQ |
不应存在 “not found” 依赖
ldd /opt/bmc/drivers/libExample_Driver.so
#### 步骤五:添加设备并验证
__BACKTICK_PLACEHOLDER_307__
#### 步骤六:卸载并确认清理
__BACKTICK_PLACEHOLDER_308__
#### 示例代码验证方法
1. __BACKTICK_PLACEHOLDER_309__ 能找到全局符号 __BACKTICK_PLACEHOLDER_310__。
2. __BACKTICK_PLACEHOLDER_311__ 不出现 __BACKTICK_PLACEHOLDER_312__。
3. __BACKTICK_PLACEHOLDER_313__ 返回码为 0,日志出现 __BACKTICK_PLACEHOLDER_314__、__BACKTICK_PLACEHOLDER_315__ 和 __BACKTICK_PLACEHOLDER_316__。
4. __BACKTICK_PLACEHOLDER_317__ 存在,属性和 owner 符合 CSR 预期。
5. 一键日志中的 __BACKTICK_PLACEHOLDER_318__ 显示该驱动 __BACKTICK_PLACEHOLDER_319__。
6. __BACKTICK_PLACEHOLDER_320__ 后 ObjectGroup 和本位置设备对象消失,驱动 __BACKTICK_PLACEHOLDER_321__ 已执行。
#### 注意事项
- 驱动库文件名、__BACKTICK_PLACEHOLDER_322__ 归一化名称和 ABI 必须一致。
- __BACKTICK_PLACEHOLDER_323__ 必须使用 __BACKTICK_PLACEHOLDER_324__,避免 C++ 名字改编导致 __BACKTICK_PLACEHOLDER_325__ 失败。
- __BACKTICK_PLACEHOLDER_326__ 返回的驱动表及其中字符串、函数指针必须在库生命周期内持续有效。
- __BACKTICK_PLACEHOLDER_327__ 返回的是借用指针,调用方会立即复制;驱动不得返回已经释放的临时字符串地址。
- 驱动的 __BACKTICK_PLACEHOLDER_328__ 应可重复、安全地终止线程、定时器和 I/O,避免卸载残留。
- 多实例驱动不得用未加锁的全局可变状态保存单个设备上下文。
- 修改驱动后应先卸载旧设备;已缓存的动态库通常需要重启组件或使用全新版本/环境才能确保重新加载。
- 单架构始终使用 ABI v2;不要因为 CSR 的 __BACKTICK_PLACEHOLDER_329__ 小于 5 就部署只有 __BACKTICK_PLACEHOLDER_330__ 的驱动。
## 4. 日志说明
### 4.1 一键日志收集
系统一键日志通常把运行日志放在 __BACKTICK_PLACEHOLDER_331__,把组件 dump 放在 __BACKTICK_PLACEHOLDER_332__。不同版本的收集器可能额外增加实例目录,定位时应优先按文件名搜索。
| 文件路径/文件名 | 产生方 | 内容说明 |
| :--- | :--- | :--- |
| __BACKTICK_PLACEHOLDER_333__ | 系统日志收集 | devmon、hwdiscovery、hwproxy 的运行日志;目标机实时文件通常为 __BACKTICK_PLACEHOLDER_334__ |
| __BACKTICK_PLACEHOLDER_335__ | devmon | 当前设备拓扑和对象层级 |
| __BACKTICK_PLACEHOLDER_336__ | devmon | Scanner/Accessor 运行快照,包括周期、状态、成功/失败计数、值和错误信息 |
| __BACKTICK_PLACEHOLDER_337__ | devmon | 驱动库加载状态、耗时、设备数和错误信息 |
| __BACKTICK_PLACEHOLDER_338__ | devmon | 芯片读写成功/失败次数、访问耗时和错误记录;Release 构建可能不生成 |
| __BACKTICK_PLACEHOLDER_339__ | hwproxy | 三层架构硬件代理对象拓扑 |
| __BACKTICK_PLACEHOLDER_340__ | hwproxy | 三层架构 Accessor/Scanner 快照 |
| __BACKTICK_PLACEHOLDER_341__ | hwproxy | SmcDfxInfo 配置和最近数据 |
| __BACKTICK_PLACEHOLDER_342__ | hwproxy | 三层架构芯片访问统计;Release 构建可能不生成 |
| __BACKTICK_PLACEHOLDER_343__ | hwdiscovery | Connector 树、位置、源路径、在位状态、识别方式等 |
| __BACKTICK_PLACEHOLDER_344__ | hwdiscovery | 当前使用的根 CSR;源文件不可用时该文件可能缺失并记录告警 |
| __BACKTICK_PLACEHOLDER_345__ | hwdiscovery | 当前平台 CSR |
| __BACKTICK_PLACEHOLDER_346__ / __BACKTICK_PLACEHOLDER_347__ | hwdiscovery | 各 Connector 的实际 CSR/二进制源文件副本 |
| __BACKTICK_PLACEHOLDER_348__ | hwdiscovery | Connector 关联的软件 CSR(存在时) |
| __BACKTICK_PLACEHOLDER_349__ | hwdiscovery | 满足条件的 EEPROM 备份,单次最多复制 65 个 |
| __BACKTICK_PLACEHOLDER_350__、__BACKTICK_PLACEHOLDER_351__ | devmon 特定对象 | JBOG 相关运行信息;仅对应对象和场景存在时生成 |
快速查找:
__BACKTICK_PLACEHOLDER_352__
### 4.2 关键日志信息
| 日志片段 | 日志级别 | 含义解读 | 建议处理动作 |
| :--- | :--- | :--- | :--- |
| __BACKTICK_PLACEHOLDER_353__ | INFO | 当前为单架构 | 使用 __BACKTICK_PLACEHOLDER_354__,驱动按 ABI v2 检查 |
| __BACKTICK_PLACEHOLDER_355__ | INFO | 当前为三层架构 | 同时检查 devmon、hwdiscovery、hwproxy |
| __BACKTICK_PLACEHOLDER_356__ | INFO | 服务配置和基础初始化完成 | 继续确认 root 对象及启动日志 |
| __BACKTICK_PLACEHOLDER_357__ | INFO | devmon 根对象已注册 | 可执行 __BACKTICK_PLACEHOLDER_358__ |
| __BACKTICK_PLACEHOLDER_359__ | INFO | devmon 服务进入启动阶段 | 无 |
| __BACKTICK_PLACEHOLDER_360__ | INFO | hwproxy 根对象完成 | 三层架构硬件代理可用 |
| __BACKTICK_PLACEHOLDER_361__ | INFO | hwproxy 已启动 | 无 |
| __BACKTICK_PLACEHOLDER_362__ | INFO | hwdiscovery 已启动 | 等待异步 CSR 全量发现完成 |
| __BACKTICK_PLACEHOLDER_363__ | INFO | 应用启动完成 | 无 |
| __BACKTICK_PLACEHOLDER_364__ | INFO | CSR1 请求被转发到发现层 | 到 hwdiscovery 日志继续跟踪 |
| __BACKTICK_PLACEHOLDER_365__ | INFO | CSR1 卸载被转发 | 检查子 position 是否级联清理 |
| __BACKTICK_PLACEHOLDER_366__ | WARN | 同一位置已存在,重复添加被忽略 | 先 RemoveDevice,或使用新 GroupPosition |
| __BACKTICK_PLACEHOLDER_367__ | INFO | 正在尝试加载候选动态库 | 核对库路径和 ABI |
| __BACKTICK_PLACEHOLDER_368__ | INFO | 驱动加载并缓存成功 | 继续确认 init/start 和对象创建 |
| __BACKTICK_PLACEHOLDER_369__ | NOTICE | 本地添加流程完成 | 检查 ObjectGroup 和对象属性 |
| __BACKTICK_PLACEHOLDER_370__ | ERROR/异常 | CSR 文件无法读取 | 检查路径、权限和部署 |
| __BACKTICK_PLACEHOLDER_371__ | ERROR/异常 | AddDeviceWithData 的变体类型错误 | 改传 JSON 字符串或字典 |
| __BACKTICK_PLACEHOLDER_372__ | ERROR/异常 | 缺少有效 GroupPosition | 修改调用参数 |
| __BACKTICK_PLACEHOLDER_373__ | WARN | FormatVersion 非法,已回退 5.00 | 修正版本格式,避免路由与预期不一致 |
| __BACKTICK_PLACEHOLDER_374__ | ERROR/异常 | __BACKTICK_PLACEHOLDER_375__ 为空 | 补齐设备类 |
| __BACKTICK_PLACEHOLDER_376__ | ERROR/异常 | __BACKTICK_PLACEHOLDER_377__ 为空 | 补齐实例名 |
| __BACKTICK_PLACEHOLDER_378__ | ERROR/异常 | __BACKTICK_PLACEHOLDER_379__ 为空 | 补齐驱动候选 |
| __BACKTICK_PLACEHOLDER_380__ | ERROR/异常 | CSR 没有对象定义 | 补齐 Objects |
| __BACKTICK_PLACEHOLDER_381__ | ERROR | __BACKTICK_PLACEHOLDER_382__ 对应对象不存在 | 确保 Objects 含同名键 |
| __BACKTICK_PLACEHOLDER_383__ | ERROR/异常 | 非空管理拓扑缺少 Anchor | 配置 __BACKTICK_PLACEHOLDER_384__ 或删除管理拓扑 |
| __BACKTICK_PLACEHOLDER_385__ | ERROR/异常 | __BACKTICK_PLACEHOLDER_386__ 失败 | 用 __BACKTICK_PLACEHOLDER_387__、架构、权限和库名排查 |
| __BACKTICK_PLACEHOLDER_388__ | ERROR/异常 | 缺少 __BACKTICK_PLACEHOLDER_389__ 导出符号 | 检查 __BACKTICK_PLACEHOLDER_390__ 和 __BACKTICK_PLACEHOLDER_391__ |
| __BACKTICK_PLACEHOLDER_392__ | ERROR/异常 | 注册函数返回非 0 | 修正注册函数参数和返回值 |
| __BACKTICK_PLACEHOLDER_393__ | ERROR/异常 | 所有 Compatible 候选都失败 | 核对 Compatible、库名和 ABI |
| __BACKTICK_PLACEHOLDER_394__ / __BACKTICK_PLACEHOLDER_395__ | ERROR | 驱动实例或对象注册失败 | 查看前序驱动/CSR日志和异常堆栈 |
| __BACKTICK_PLACEHOLDER_396__ | ERROR | devmon 拓扑根对象缺失,访问统计无法导出 | 检查启动完整性和异常重启 |
| __BACKTICK_PLACEHOLDER_397__ | WARN | 一键日志找不到某个 CSR/备份源文件 | 核对源路径;不一定代表运行故障 |
| __BACKTICK_PLACEHOLDER_398__ | INFO | 驱动加载记录导出成功 | 查看 CSV |
| __BACKTICK_PLACEHOLDER_399__ | NOTICE | Connector dump 完成 | 查看 connectors.txt 和 CSR 副本 |
默认日志级别为 __BACKTICK_PLACEHOLDER_400__。三层架构中 __BACKTICK_PLACEHOLDER_401__、__BACKTICK_PLACEHOLDER_402__、__BACKTICK_PLACEHOLDER_403__ 日志域均默认使用 __BACKTICK_PLACEHOLDER_404__。
### 4.3 调试日志与南向追踪
进入 mdbctl:
__BACKTICK_PLACEHOLDER_405__
常用命令:
__BACKTICK_PLACEHOLDER_406__
读取块设备/EEPROM 的示例:
__BACKTICK_PLACEHOLDER_407__
正常响应类型为 __BACKTICK_PLACEHOLDER_408__,后跟读取长度和二进制数据。该命令仅适用于目标对象确实暴露 __BACKTICK_PLACEHOLDER_409__ 接口的三层架构环境。
## 5. 问题定界指南
### 5.1 典型问题定界
| 现象描述 | 是否为本组件问题 | 判断依据 | 关键证据收集方法 |
| :--- | :--- | :--- | :--- |
| __BACKTICK_PLACEHOLDER_410__ 服务不存在 | 通常是部署、依赖或启动问题,可能属于 devmon 集成问题 | __BACKTICK_PLACEHOLDER_411__ 无服务名,systemd 状态异常 | __BACKTICK_PLACEHOLDER_412__、__BACKTICK_PLACEHOLDER_413__、__BACKTICK_PLACEHOLDER_414__ |
| AddDevice 报 __BACKTICK_PLACEHOLDER_415__ | 是,属于调用参数问题 | 当前接口只从 __BACKTICK_PLACEHOLDER_416__ 生成对象组位置 | 保存完整 busctl 命令和 D-Bus 异常 |
| AddDevice 无输出,但对象已创建 | 否,属于 void 方法正常表现 | 方法没有返回参数,ObjectGroup 和成功日志存在 | __BACKTICK_PLACEHOLDER_417__、对象树、__BACKTICK_PLACEHOLDER_418__ |
| 重复添加后对象未刷新 | 否,属于接口幂等/防重复行为 | 日志出现 __BACKTICK_PLACEHOLDER_419__ | 搜索该日志;先卸载再加载 |
| CSR 校验错误 | 通常是 CSR 配置问题 | Unit/Objects/Anchor 日志明确指出缺失字段 | 原始 CSR、__BACKTICK_PLACEHOLDER_420__ 结果、关键错误日志 |
| __BACKTICK_PLACEHOLDER_421__ | 可能是驱动包或依赖问题 | __BACKTICK_PLACEHOLDER_422__ 失败,未进入驱动注册 | 驱动路径、__BACKTICK_PLACEHOLDER_423__、__BACKTICK_PLACEHOLDER_424__、__BACKTICK_PLACEHOLDER_425__、drivers_load_info.csv |
| __BACKTICK_PLACEHOLDER_426__ | 是驱动 ABI 接口问题 | 动态库缺少导出符号 | __BACKTICK_PLACEHOLDER_427__ |
| __BACKTICK_PLACEHOLDER_428__ 返回空数组 | 不一定 | owner 不匹配、发现未完成或 CSR 没有该 owner 数据 | 读取 __BACKTICK_PLACEHOLDER_429__、connectors.txt、ObjectGroup 属性和 app.log |
| __BACKTICK_PLACEHOLDER_430__ | 不一定 | 可能选错单架构/三层架构路径,或设备添加失败 | 查看架构日志和两个 ObjectGroup 根路径 |
| 三层架构 CSR1 不加载 | 可能是发现链路问题 | devmon 已转发,但 hwdiscovery/hwproxy 未就绪或 CSR1 驱动缺失 | 三个服务状态、转发日志、connectors.txt、ABI v1 驱动 |
| 对象存在但芯片读取失败 | 可能属于驱动、总线或硬件问题 | 对象注册成功,不代表底层总线可访问 | tracechip、chips_access_statistic.csv、硬件代理日志 |
| 一键日志没有 __BACKTICK_PLACEHOLDER_431__ | 不一定 | Release 构建可不输出该统计 | 核对构建类型和其他 dump 文件 |
| devmon 周期性重启 | 是或依赖问题 | systemd 配置 __BACKTICK_PLACEHOLDER_432__,崩溃后会自动拉起 | __BACKTICK_PLACEHOLDER_433__、coredump、journal、MemoryCurrent、依赖版本 |
| 仅某个位置卸载后其他共享总线对象消失 | 可能是对象归属/版本问题 | 卸载逻辑应只注销本 position 拥有的对象 | 记录卸载前后对象树、版本、app.log 和 CSR |
### 5.2 错误码速查表
#### D-Bus/解析错误
| 错误/日志 | 含义 | 可能原因 | 排查建议 |
| :--- | :--- | :--- | :--- |
| __BACKTICK_PLACEHOLDER_434__ | D-Bus 服务不存在 | devmon 未启动、服务未注册或环境变量/总线不正确 | 检查 systemd、用户 D-Bus 会话和服务列表 |
| __BACKTICK_PLACEHOLDER_435__ | 对象路径不存在 | 路径选错、设备未加载、已卸载 | 按架构重新 __BACKTICK_PLACEHOLDER_436__ |
| __BACKTICK_PLACEHOLDER_437__ | 接口名错误 | 混用了 __BACKTICK_PLACEHOLDER_438__ 与 __BACKTICK_PLACEHOLDER_439__ | 先 __BACKTICK_PLACEHOLDER_440__ |
| __BACKTICK_PLACEHOLDER_441__ / 签名不匹配 | D-Bus 参数格式错误 | 字典数量、Variant 类型或签名不正确 | 对照第 2 章逐项检查 |
| __BACKTICK_PLACEHOLDER_442__ | 无有效位置 | GroupPosition 缺失/空 | 传 __BACKTICK_PLACEHOLDER_443__ |
| __BACKTICK_PLACEHOLDER_444__ | CSR 变体类型错误 | AddDeviceWithData 传了非 string/dict | 用 __BACKTICK_PLACEHOLDER_445__ |
| __BACKTICK_PLACEHOLDER_446__ | Unit 字段为空 | CSR 不完整 | 补齐 Unit |
| __BACKTICK_PLACEHOLDER_447__ | Objects 为空 | CSR 不完整 | 添加对象定义 |
| __BACKTICK_PLACEHOLDER_448__ | 拓扑缺 Anchor | 非空拓扑不完整 | 补 Anchor/Buses |
| __BACKTICK_PLACEHOLDER_449__ | 驱动候选全部失败 | Compatible、文件名、ABI 或部署错误 | 依次核对候选库 |
#### 驱动 ABI 状态码
| 错误码 | 含义 | 可能原因 | 排查建议 |
| :--- | :--- | :--- | :--- |
| 0 __BACKTICK_PLACEHOLDER_450__ | 成功 | 正常 | 无 |
| 1 __BACKTICK_PLACEHOLDER_451__ | 通用错误 | 驱动内部失败 | 查看驱动日志和 dump |
| 2 __BACKTICK_PLACEHOLDER_452__ | 目标不存在 | 芯片、通道或资源不存在 | 核对 CSR 和硬件在位 |
| 3 __BACKTICK_PLACEHOLDER_453__ | 参数非法 | CSR/Connector 值不支持 | 打印输入并校验类型/范围 |
| 4 __BACKTICK_PLACEHOLDER_454__ | 未实现 | 驱动不支持该操作 | 使用替代能力或补充实现 |
| 5 __BACKTICK_PLACEHOLDER_455__ | 超时 | 总线无响应、设备忙 | tracechip,检查链路和时序 |
| 6 __BACKTICK_PLACEHOLDER_456__ | 资源忙 | 并发访问或状态机未就绪 | 降低并发、稍后重试 |
| 7 __BACKTICK_PLACEHOLDER_457__ | 内存不足 | 分配失败或泄漏 | 检查 MemoryCurrent、coredump 和长期增长 |
### 5.3 调试方法
#### 开启调试日志
先确认当前服务和日志域,再用 mdbctl 调整级别:
__BACKTICK_PLACEHOLDER_458__
三层架构需要分别对 __BACKTICK_PLACEHOLDER_459__、__BACKTICK_PLACEHOLDER_460__、__BACKTICK_PLACEHOLDER_461__ 检查或设置。定位完成后恢复默认级别,避免长期产生大量日志。
#### 分层排查步骤
##### 1. 确认进程和资源限制
__BACKTICK_PLACEHOLDER_462__
目标 service 配置为 __BACKTICK_PLACEHOLDER_463__、__BACKTICK_PLACEHOLDER_464__、__BACKTICK_PLACEHOLDER_465__,工作目录 __BACKTICK_PLACEHOLDER_466__,执行文件 __BACKTICK_PLACEHOLDER_467__。
##### 2. 确认 D-Bus 服务和架构
__BACKTICK_PLACEHOLDER_468__
##### 3. 确认根接口
__BACKTICK_PLACEHOLDER_469__
应至少看到 __BACKTICK_PLACEHOLDER_470__、__BACKTICK_PLACEHOLDER_471__ 和 __BACKTICK_PLACEHOLDER_472__。
##### 4. 校验 CSR
__BACKTICK_PLACEHOLDER_473__
检查:
- __BACKTICK_PLACEHOLDER_474__、__BACKTICK_PLACEHOLDER_475__、__BACKTICK_PLACEHOLDER_476__ 非空;
- __BACKTICK_PLACEHOLDER_477__ 非空,且含 __BACKTICK_PLACEHOLDER_478__ 对应对象;
- 配置了 __BACKTICK_PLACEHOLDER_479__ 时含 __BACKTICK_PLACEHOLDER_480__;
- 需要总线映射时 __BACKTICK_PLACEHOLDER_481__ 和 Connector 的 __BACKTICK_PLACEHOLDER_482__ 数量/顺序匹配;
- __BACKTICK_PLACEHOLDER_483__ 与部署驱动 ABI 一致。
##### 5. 校验驱动
__BACKTICK_PLACEHOLDER_484__
##### 6. 跟踪一次 AddDevice
__BACKTICK_PLACEHOLDER_485__
判断顺序:参数规范化 → FormatVersion 路由 → CSR 校验 → 驱动加载 → 对象创建 → ObjectGroup → 成功日志。
##### 7. 检查对象组
__BACKTICK_PLACEHOLDER_486__
若路径存在但 __BACKTICK_PLACEHOLDER_487__ 为空,先读 __BACKTICK_PLACEHOLDER_488__;若路径根本不存在,回到 CSR/驱动/转发日志。
##### 8. 检查一键日志证据
__BACKTICK_PLACEHOLDER_489__
##### 9. 检查硬件访问
- 在 mdbctl 中 __BACKTICK_PLACEHOLDER_490__。
- 使用 __BACKTICK_PLACEHOLDER_491__ 追踪目标芯片。
- 对 Scanner 使用 __BACKTICK_PLACEHOLDER_492__。
- 查看 __BACKTICK_PLACEHOLDER_493__ 的失败计数和 Error_Recording。
- 对暴露 BlockIO 的对象执行 __BACKTICK_PLACEHOLDER_494__,区分“对象创建成功”与“底层读写成功”。
#### 复现问题方法
下面流程可复现和隔离“最小 CSR 加载失败”问题:
1. 准备一个只包含单个 __BACKTICK_PLACEHOLDER_495__ 和同名 __BACKTICK_PLACEHOLDER_496__ 的 CSR,使用 __BACKTICK_PLACEHOLDER_497__,并部署匹配的 ABI v2 驱动。
2. 选择未使用的 __BACKTICK_PLACEHOLDER_498__,如 __BACKTICK_PLACEHOLDER_499__。
3. 记录调用前 __BACKTICK_PLACEHOLDER_500__、D-Bus 对象树和 app.log 末尾。
4. 调用 __BACKTICK_PLACEHOLDER_501__。
5. 检查返回码、驱动加载日志和 __BACKTICK_PLACEHOLDER_502__。
6. 调用 __BACKTICK_PLACEHOLDER_503__/__BACKTICK_PLACEHOLDER_504__,保存完整响应。
7. 调用 __BACKTICK_PLACEHOLDER_505__,确认对象清理。
预期现象:驱动加载成功、出现 __BACKTICK_PLACEHOLDER_506__、ObjectGroup 可查询,卸载后路径消失。若最小 CSR 成功而业务 CSR 失败,问题主要落在业务 CSR、目标驱动或拓扑映射;若最小 CSR 也失败,优先检查组件部署、ABI 和依赖环境。
## 6. 常见问题解答
### Q1:Connector 里传了 Position,为什么仍报位置未初始化?
- **问题描述**:旧示例使用 __BACKTICK_PLACEHOLDER_507__,当前代码抛出 __BACKTICK_PLACEHOLDER_508__。
- **一句话答案**:当前动态添加/删除接口必须传 __BACKTICK_PLACEHOLDER_509__。
- **根因说明**:源码从 __BACKTICK_PLACEHOLDER_510__ 生成对象组位置,__BACKTICK_PLACEHOLDER_511__ 只是其他业务字段,不能替代。
- **解决方案**:把调用参数改为 __BACKTICK_PLACEHOLDER_512__。
- **规避方案**:所有新脚本统一使用本文命令模板。
- **适用版本**:devmon 1.2.94。
### Q2:数值 GroupPosition 最终会变成什么?
- **问题描述**:调用传整数后,对象路径不是十进制数字。
- **一句话答案**:整数会转为大写十六进制,至少 2 位并补成偶数长度。
- **根因说明**:位置用于层级拼接和对象组命名,需要稳定的十六进制表示。
- **解决方案**:例如 __BACKTICK_PLACEHOLDER_513__、__BACKTICK_PLACEHOLDER_514__、__BACKTICK_PLACEHOLDER_515__;希望完全控制格式时直接传字符串。
- **规避方案**:添加和删除时使用同一种表示。
- **适用版本**:devmon 1.2.94。
### Q3:同一 GroupPosition 再次 AddDevice 会覆盖旧设备吗?
- **问题描述**:修改 CSR 后重复调用,运行对象没有变化。
- **一句话答案**:不会覆盖,重复位置会直接跳过。
- **根因说明**:devmon 在解析和创建前检查 position 是否已存在,防止重复实例。
- **解决方案**:先 __BACKTICK_PLACEHOLDER_516__,再重新 __BACKTICK_PLACEHOLDER_517__。
- **规避方案**:更新流程显式执行卸载—确认清理—重新加载。
- **适用版本**:devmon 1.2.94。
### Q4:如何判断当前应使用哪个 ObjectGroup 路径?
- **问题描述**:访问 __BACKTICK_PLACEHOLDER_518__ 或 __BACKTICK_PLACEHOLDER_519__ 时出现 UnknownObject。
- **一句话答案**:单架构/CSR2 使用前者,三层架构 CSR1 使用后者。
- **根因说明**:三层架构把旧格式 CSR 的发现结果放在 hwdiscovery 服务。
- **解决方案**:查看 __BACKTICK_PLACEHOLDER_520__ 和 CSR __BACKTICK_PLACEHOLDER_521__,再执行对应 __BACKTICK_PLACEHOLDER_522__。
- **规避方案**:脚本先探测两个服务和根路径。
- **适用版本**:支持 unidev 的 devmon 版本,本文以 1.2.94 为准。
## 附录
### 附录 A 修订记录
| 版本 | 日期 | 修订人 | 修订内容 |
| :--- | :--- | :--- | :--- |
| 1.2.94 | 2026-08-24 | | 创建 devmon 组件说明,补充组件概述、D-Bus API、驱动/CSR 扩展、日志、问题定界和 FAQ |