1 个不稳定版本
0.1.1 | 2024年4月29日 |
---|
#1913 在 嵌入式开发
9KB
utrace
utrace 是一种基于仪表化的嵌入式应用程序性能分析工具。它旨在具有平台无关性、异步友好性和低开销。utrace 的操作原理受到了出色的 defmt 记录库 的启发。
用法
面向用户的主要 API 是两个可以用来插入仪表化的过程宏 - 属性 #[trace] 和函数式的 [trace_here]。可能的用法在本代码片段中演示
#[utrace::trace]
async fn do_something() {
}
#[utrace::trace]
fn do_something_else() {
}
{
utrace::trace_here!();
...
...
}
当 #[trace] 仪表化异步函数时,默认情况下将报告相应的未来创建、丢弃和轮询跨度的时间点。
跟踪信息的时间戳和传输
虽然跟踪仪表化本身是平台无关的,但它需要一种从 DUT 到主机系统获取时间戳和传输数据的方式。
为了向库提供时间戳函数,使用 #[timestamp] 宏。例如
#[utrace::timestamp]
fn utrace_timestamp_fn() -> u64 {
(Tim15::now() - <Tim15 as Monotonic>::ZERO).to_micros()
}
在当前版本中,时间戳函数的签名必须是 rust fn() -> u64
。
要定义传输,用 #[default_transport] 标注一个函数,如下所示
#[utrace::default_transport]
pub fn write(buf: &[u8]) {
...
}
当前实现提供了在 utrace_rtt 包中的基于 RTT 的传输实现。
请注意,当前实现需要临界区实现。例如,如果您正在使用单核 ARM MCU,您可以添加以下内容到您的 Cargo.toml。
cortex-m = { version = "0.7.7", features = ["critical-section-single-core"] }
到您的 Cargo.toml。
跟踪数据解释
用于跟踪解释的元数据存储在输出elf二进制文件中。正确捆绑这些元数据需要在二进制链接过程中将utrace_linker.x脚本传递给链接器。这可以通过在build.rs脚本中添加如下内容来实现:
println!("cargo::rustc-link-arg=-Tutrace_linker.x");
或者通过添加
rustflags = [
"-C", "link-arg=-Tutrace_linker.x"
]
到你的.cargo/config.toml。第一种方法应优先于第二种。
要提取元数据和解释跟踪数据流,应使用utrace_parser库。这个库的包提供了一个名为utrace-capture的二进制文件,它可以从TCP连接或stdin接收原始跟踪流,并将跟踪数据写入chrome://tracing格式。要安装它,执行:
cargo install --locked utrace_parser --features="cli"
假设使用OpenOCD作为DUT接口。在这种情况下,你的OpenOCD初始化脚本中应该有如下内容:
rtt setup 0x20000000 0x20000 "SEGGER RTT"
rtt server start 9001 0
rtt start
这将告诉OpenOCD监听端口9001,并将通道0的原始RTT数据发送给连接的客户端。要在此配置中捕获并保存跟踪流,请运行:
utrace-capture <path to firmware elf executable> --tcp localhost:9001 --out-ct trace_out
跟踪将被捕获在trace_out_xxx.json文件中。要完成捕获,请按Ctrl+C。如果您使用Chrome浏览器,可以使用chrome://tracing打开这些跟踪,或者使用Perfetto UI。
注意,probe-rs (cargo embed) RTT功能尝试连接到服务器,而不是监听端口,因此您需要使用--tcp-server
标志,例如:
utrace-capture <path to firmware elf executable> --tcp-server 0.0.0.0:9001 --out-ct trace_out
跟踪数据也可以使用--stdin
标志从stdin捕获。
依赖项
~1.3–2.2MB
~46K SLoC