R-DIAG
概述
R-DIAG 通过 预定义事件类型 与 结构化数据体 统一管理各模块事件,并提供两种接口供上位机获取事件数据:
本地接口:基于物理接口(如 LOGUART),适用于现场调试和快速数据获取。
网络接口:基于网络协议(如 TCP/UDP),适用于远程诊断、多设备并发访问和云端集成。
工作流程
通过 R-DIAG 记录和解析事件的流程如下:
事件结构定义和记录:在 SDK 中定义事件类型和数据结构,并在代码中调用 API 记录事件。
生成配置文件:编译时自动生成 JSON 格式的结构体描述文件和版本校验信息。
记录事件:设备烧录固件后,在运行时按定义记录事件数据。
获取事件:上位机通过接口读取事件数据。
解析事件:上位机通过 JSON 文件解析并展示事件详情。
能力与扩展
功能启用
要启用或禁用 R-DIAG 功能,请按以下步骤操作:
导航至
{SDK}/amebaxxx_gcc_project目录执行指令
./menuconfig.py进入 menuconfig 界面修改 选项
备注
R-DIAG 功能默认为启用状态。
本地故障诊断
SDK 默认支持使用 Realtek 串口调试工具 Trace Tool (v2.1.38+) 通过 LOGUART 获取与解析事件。 工具说明见 日志工具 ,针对 R-DIAG 功能的使用步骤如下:
在 DIAG 选项卡中配置参数
Time Period:获取时间范围,默认 “In a week”
Start Date / End Date:当 Time Period 选择 "Custom options" 时需手动设置起止时间
Buffer Size:单次获取缓冲区大小,默认 500 bytes
点击 Start Diagnose 开始获取事件,解析结果显示在页面左侧
点击 Export 将记录导出到
/TraceTool/DiagnoseInfoExport的 Excel 文件
自定义事件添加
在 component/soc/common/diagnose/ameba_diag_customer.h 中新增自定义事件步骤如下:
定义事件 ID
按 DIAG_EVT_CUSTOMER_事件名 格式命名,使用 RTK_EVENT_TYPE_CUSTOMER 作为基址。示例:
enum diag_evt_customer {
DIAG_EVT_CUSTOMER_DEMO = RTK_EVENT_TYPE_CUSTOMER + 0x01,
...
};
定义事件结构
命名规则: 事件 ID 枚举名的小写形式。示例: DIAG_EVT_CUSTOMER_DEMO 对应结构体 diag_evt_customer_demo。
内存对齐: 使用 __PACKED 属性
变量定义规则:
注释要求
面向事件解析的注释必须使用
/* <!-- DIAG: --> xxxxx*/并置于变量定义行末,且不可跨行。示例:
struct diag_evt_customer_demo { u16 reason; /* <!-- DIAG: --> enum customer_demo_reason in customer_demo_types.h */ u32 timestamp; /* <!-- DIAG: --> UNIX time in seconds */ // os tick value } __PACKED;
生成 JSON 效果:
"diag_evt_customer_demo": { "reason": { "type": "u16", "enum_ref": "customer_demo_reason", "comment": "enum customer_demo_reason in customer_demo_types.h" }, "timestamp": { "type": "u32", "comment": "UNIX time in seconds" } },
不直接使用枚举类型:
根据枚举值范围选择基础整型
在注释标明枚举类型及其定义文件,以便工具解析枚举注释
示例:上述结构体 diag_evt_customer_demo 中变量 reason 实际使用的枚举定义如下:
// file:customer_demo_types.h (just for example) enum customer_demo_reason { CUSTOMER_DEMO_RSN_UNKNOWN = 10001, /* <!-- DIAG: --> unknown */ CUSTOMER_DEMO_RSN_TIMEOUT = 10002, /* <!-- DIAG: --> timeout occurred */ CUSTOMER_DEMO_RSN_THRESHOLD = 10003, /* <!-- DIAG: --> threshold exceeded */ };
生成的 JSON 文件会映射枚举值与注释:
"customer_demo_reason": { "unknown": 10001, "timeout occurred": 10002, "threshold exceeded": 10003 },
结构体嵌套不超过 3 层
字符串字段使用
char位域仅支持
u8、u16、u32,不足 1 byte 需填充。
记录事件
事件等级如下:
enum rtk_event_level { RTK_EVENT_LEVEL_ALWAYS = 0, RTK_EVENT_LEVEL_ERROR, RTK_EVENT_LEVEL_WARNING, RTK_EVENT_LEVEL_INFO, RTK_EVENT_LEVEL_DEBUG, };
按等级调用 API ,传入三参数: 事件类型 ID 、结构体地址与长度。
RTK_EVENT_A(_type, _info, _len) RTK_EVENT_E(_type, _info, _len) RTK_EVENT_W(_type, _info, _len) RTK_EVENT_I(_type, _info, _len) RTK_EVENT_D(_type, _info, _len)
示例(在“客户示例触发”处理函数中,记录 INFO 级事件):
void customer_demo_trigger_handler(void) { struct diag_evt_customer_demo event_data = { .reason = 10002, /* triggered by timeout */ .timestamp = 1731580000U }; RTK_EVENT_I(DIAG_EVT_CUSTOMER_DEMO, (u8 *)&event_data, sizeof(event_data)); }
更新 JSON
请将上位机工具的配置文件更新为编译生成的 ameba_diagnose_format_full.json,避免解析错误。
若使用 本地故障诊断 ,请更新至 /TraceTool/DiagnoseProfiles。
事件解析效果
添加上述 DIAG_EVT_CUSTOMER_DEMO 示例事件后,使用 本地故障诊断 解析效果如下:
远程故障诊断示例
本示例演示通过 MQTT,在 PC 与 Ameba 设备之间收集并解析诊断事件。
SDK 示例路径:
{SDK}/component/example/wifi/wifi_diagnose_mqttPC 端工具路径:
diagnose_tool_wrapper
环境与网络拓扑
树莓派(安装 Mosquitto 服务器与客户端)作为 MQTT Broker
PC 作为上位机,运行事件采集与解析工具
Ameba 运行示例固件,产生并通过 MQTT 发送事件
所有设备需连接到同一 AP
使用前确认树莓派的 IPv4 地址(供下文 Ameba 与 PC 配置使用)
主题约定
request_diag_events: PC 发布请求; Ameba 订阅response_diag_events: Ameba 发布响应; PC 订阅
备注
树莓派仅为示例 MQTT Broker 运行环境,可替换为:云端服务器(公有云或私有云)、虚拟机(如 VMware、VirtualBox 等)、或 Linux 系统的 PC。
替换时请确保:
已安装并启动 MQTT Broker,监听地址与端口对外可达
Ameba 与 PC 能路由访问该 Broker;若不在同一 AP/子网,需要满足跨网段或公网可达,并配置端口转发、防火墙规则、DNS 解析等
快速上手
获取树莓派在当前 AP 下的 IPv4 地址,如
192.168.1.106设备端配置( Ameba 示例)
在文件
{SDK}/component/example/wifi/wifi_diagnose_mqtt/example_wifi_diagnose_mqtt.c中,将 MQTT Broker 地址改为树莓派 IP :static const char *address = "192.168.1.106";
编译与烧录
在
{SDK}/amebaxxx_gcc_project目录下执行:./build.py -a wifi_diagnose_mqtt
完成编译后,按设备平台常规流程烧录固件至 Ameba 设备
PC 端配置
在
diagnose_tool_wrapper/diagnose_defines.py中,将 Broker 地址更新为树莓派 IP :MQTT_BROKER = "192.168.1.106"
运行 PC 端工具
进入
diagnose_tool_wrapper目录,执行:python diagnose_main.py
工具将通过
WiFiDiagnoseServer.diag_read_events()组织流程:内部调用
DiagController.diag_read_backgroud_worker()完成读取前配置(版本哈希校验、时间对齐、发送缓冲区设定、时间范围设定), 随后调用DiagController.get_diag_event()获取并解析 Ameba 当天事件,并将结果保存至diagnose_tool_wrapper/DiagnoseInfoExport下的 JSON 文件。
调整获取时间范围(可选)
在
diagnose_main.py修改WiFiDiagnoseServer.diag_read_events()的输入参数,以限定需要拉取的设备时间戳区间。
备注
若版本哈希校验失败,请更新上位机 JSON 与设备一致
若 PC 无法获取事件,请检查:
MQTT Broker 是否已启动(树莓派 mosquitto 服务状态)
MQTT Broker 所在设备防火墙是否放行 入站 的 MQTT 默认端口(1883)
PC 防火墙或安全软件是否允许 出站 连接到 Broker 的 MQTT 端口
客户端连接参数(IP/端口等)与 Broker 配置是否一致
结果可视化
将 diagnose_tool_wrapper/DiagnoseInfoExport 下生成的 JSON 文件进行简单可视化,效果示意如下:
远程故障诊断开发
设备端接口配置
上位机如需通过网络接口获取事件,设备端需在 SDK 代码中注册事件数据发送接口,告诉 Diagnose 组件如何交付事件数据:
int rtk_diag_config_transform(rtk_diag_sender_t sender, u8 *sender_buffer, u16 sender_buffer_size);
项目 |
描述 |
|---|---|
功能 |
配置事件数据的发送接口 |
参数 |
sender: 用户实现的事件数据发送函数,原型如下 typedef int (*rtk_diag_sender_t)(const u8 *data, u16 len);
sender_buffer: Diagnose组件用于拷贝事件数据的固定发送缓冲区 sender_buffer_size: 发送缓冲区大小(字节) |
返回值 |
0表示成功,非零为错误码 |
说明 |
|
示例 |
以 u8 diag_send_buf[1024] = {0};
int rtk_diag_mqtt_send(const u8 *data, u16 len);
static void prvMQTTTask(void *pvParameters)
{
...
rtk_diag_config_transform(rtk_diag_mqtt_send, diag_send_buf, 1024);
}
|
上位机交互协议
上位机工具以请求-响应模式与 Ameba 交互,Ameba 始终被动响应指令;完整流程如下:
获取事件前配置
Hash 检查:验证设备与上位机 JSON 版本一致,避免结构体定义变更导致解析错误
OS 时间戳获取:建立上位机真实时间与设备时间戳映射,以解析事件发生的真实时间
发送缓冲设置:限制单次传输最大长度,避免影响系统调度
获取事件交互
上位机将按 Ameba 响应动态更新请求的时间与偏移量参数,直到设备没有更多事件可发送或达到上位机设定的时间范围