pw_trace: tokenizer basic example
Run the trace sample app and dump all trace data to a file.
- Use std::chrono::system_clock as the time source for host builds.
- Add trace_to_file.h which registers callbacks and saves all trace data
to a provided binary file.
Change-Id: I57fac75ed91fc98646e7aae920897687a39549ab
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/13802
Commit-Queue: Rob Oliver <rgoliver@google.com>
Reviewed-by: (☞゚∀゚)☞ Tennessee Carmel-Veilleux <tennessee@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index c8f937b..e89bf65 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -109,7 +109,10 @@
# Trace examples currently only support running on non-windows host
if (defined(pw_toolchain_SCOPE.is_host_toolchain) &&
pw_toolchain_SCOPE.is_host_toolchain && host_os != "win") {
- deps += [ "$dir_pw_trace:trace_example_basic" ]
+ deps += [
+ "$dir_pw_trace:trace_example_basic",
+ "$dir_pw_trace_tokenized:trace_tokenized_example_basic",
+ ]
}
}
}
diff --git a/pw_trace_tokenized/BUILD b/pw_trace_tokenized/BUILD
index 535e29d..c5dfe52 100644
--- a/pw_trace_tokenized/BUILD
+++ b/pw_trace_tokenized/BUILD
@@ -14,6 +14,7 @@
load(
"//pw_build:pigweed.bzl",
+ "pw_cc_binary",
"pw_cc_library",
"pw_cc_test",
)
@@ -127,3 +128,27 @@
],
)
+pw_cc_library(
+ name = "pw_trace_host_trace_time",
+ includes = [ "example/public" ],
+ deps = [ "//pw_trace" ],
+ srcs = [ "host_trace_time.cc" ]
+)
+
+pw_cc_library(
+ name = "pw_trace_example_to_file",
+ includes = [ "example/public" ],
+ deps = [ "//pw_trace" ],
+ hdrs = [ "example/public/pw_trace_tokenized/example/trace_to_file.h" ]
+)
+
+pw_cc_binary(
+ name = "trace_tokenized_example_basic",
+ deps = [
+ ":pw_trace_example_to_file",
+ "//pw_log",
+ "//dir_pw_trace",
+ "//dir_pw_trace:pw_trace_sample_app",
+ ],
+ srcs = [ "example/basic.cc" ]
+)
diff --git a/pw_trace_tokenized/BUILD.gn b/pw_trace_tokenized/BUILD.gn
index 7a083d1..97892fb 100644
--- a/pw_trace_tokenized/BUILD.gn
+++ b/pw_trace_tokenized/BUILD.gn
@@ -90,6 +90,11 @@
sources = [ "fake_trace_time.cc" ]
}
+pw_source_set("host_trace_time") {
+ deps = [ ":pw_trace_tokenized_core" ]
+ sources = [ "host_trace_time.cc" ]
+}
+
pw_source_set("pw_trace_tokenized_core") {
public_configs = [
":backend_config",
@@ -114,3 +119,24 @@
pw_doc_group("docs") {
sources = [ "docs.rst" ]
}
+
+config("trace_example_config") {
+ include_dirs = [ "example/public" ]
+}
+
+pw_source_set("trace_example_to_file") {
+ deps = [ ":pw_trace_tokenized" ]
+ public_configs = [ ":trace_example_config" ]
+ public = [ "example/public/pw_trace_tokenized/example/trace_to_file.h" ]
+}
+
+# Builds trace examples
+pw_executable("trace_tokenized_example_basic") {
+ deps = [
+ ":trace_example_to_file",
+ "$dir_pw_log",
+ "$dir_pw_trace",
+ "$dir_pw_trace:trace_sample_app",
+ ]
+ sources = [ "example/basic.cc" ]
+}
diff --git a/pw_trace_tokenized/docs.rst b/pw_trace_tokenized/docs.rst
index f0af6a5..61715fc 100644
--- a/pw_trace_tokenized/docs.rst
+++ b/pw_trace_tokenized/docs.rst
@@ -180,3 +180,17 @@
------------------
``pw_ring_buffer``
``pw_varint``
+
+
+--------
+Examples
+--------
+The examples all use `pw_trace` sample app to provide the trace data. Details
+for how to build, run, and decode the traces are included at the top of each
+example. This is early work, and is provided as an example of how different
+tracing concepts can look.
+
+Basic
+-----
+The basic example turns on tracing and dumps all trace output to a file provided
+on the command line.
diff --git a/pw_trace_tokenized/example/basic.cc b/pw_trace_tokenized/example/basic.cc
new file mode 100644
index 0000000..4daa894
--- /dev/null
+++ b/pw_trace_tokenized/example/basic.cc
@@ -0,0 +1,49 @@
+// Copyright 2020 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+//==============================================================================
+// BUID
+// ninja -C out
+// host_clang_debug/obj/pw_trace_tokenized/bin/trace_tokenized_example_basic
+//
+// RUN
+// .out/host_clang_debug/obj/pw_trace_tokenized/bin/trace_tokenized_example_basic
+// trace.bin
+//
+// DECODE
+// python pw_trace_tokenized/py/trace_tokenized.py -i trace.bin -o trace.json
+// ./out/host_clang_debug/obj/pw_trace_tokenized/bin/trace_tokenized_example_basic
+//
+// VIEW
+// In chrome navigate to chrome://tracing, and load the trace.json file.
+
+#include "pw_log/log.h"
+#include "pw_trace/example/sample_app.h"
+#include "pw_trace_tokenized/example/trace_to_file.h"
+
+int main(int argc, char** argv) { // Take filename as arg
+ if (argc != 2) {
+ PW_LOG_ERROR("Expected output file name as argument.\n");
+ return -1;
+ }
+
+ // Enable tracing.
+ PW_TRACE_SET_ENABLED(true);
+
+ // Dump trace data to the file passed in.
+ pw::trace::TraceToFile trace_to_file(argv[1]);
+
+ PW_LOG_INFO("Running basic trace example...\n");
+ RunTraceSampleApp();
+ return 0;
+}
\ No newline at end of file
diff --git a/pw_trace_tokenized/example/public/pw_trace_tokenized/example/trace_to_file.h b/pw_trace_tokenized/example/public/pw_trace_tokenized/example/trace_to_file.h
new file mode 100644
index 0000000..5c2d783
--- /dev/null
+++ b/pw_trace_tokenized/example/public/pw_trace_tokenized/example/trace_to_file.h
@@ -0,0 +1,69 @@
+// Copyright 2020 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+//==============================================================================
+//
+
+#pragma once
+
+#include <stdio.h>
+
+#include <fstream>
+
+#include "pw_trace/example/sample_app.h"
+#include "pw_trace_tokenized/trace_callback.h"
+
+namespace pw {
+namespace trace {
+
+class TraceToFile {
+ public:
+ TraceToFile(const char* file_name) {
+ Callbacks::Instance().RegisterSink(TraceSinkStartBlock,
+ TraceSinkAddBytes,
+ TraceSinkEndBlock,
+ &out_,
+ &sink_handle_);
+ out_.open(file_name, std::ios::out | std::ios::binary);
+ }
+
+ ~TraceToFile() {
+ Callbacks::Instance().UnregisterSink(sink_handle_);
+ out_.close();
+ }
+
+ static void TraceSinkStartBlock(void* user_data, size_t size) {
+ std::ofstream* out = reinterpret_cast<std::ofstream*>(user_data);
+ uint8_t b = static_cast<uint8_t>(size);
+ out->write(reinterpret_cast<const char*>(&b), sizeof(b));
+ }
+
+ static void TraceSinkAddBytes(void* user_data,
+ const void* bytes,
+ size_t size) {
+ std::ofstream* out = reinterpret_cast<std::ofstream*>(user_data);
+ out->write(reinterpret_cast<const char*>(bytes), size);
+ }
+
+ static void TraceSinkEndBlock(void* user_data) {
+ std::ofstream* out = reinterpret_cast<std::ofstream*>(user_data);
+ out->flush();
+ }
+
+ private:
+ std::ofstream out_;
+ CallbacksImpl::SinkHandle sink_handle_;
+};
+
+} // namespace trace
+} // namespace pw
diff --git a/pw_trace_tokenized/host_trace_time.cc b/pw_trace_tokenized/host_trace_time.cc
new file mode 100644
index 0000000..b9135b4
--- /dev/null
+++ b/pw_trace_tokenized/host_trace_time.cc
@@ -0,0 +1,36 @@
+// Copyright 2020 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+//==============================================================================
+//
+
+#include <chrono>
+
+#include "pw_trace_tokenized/trace_tokenized.h"
+
+using namespace std::chrono;
+
+namespace {
+
+auto start = system_clock::now();
+
+} // namespace
+
+// Define trace time as a counter for tests.
+PW_TRACE_TIME_TYPE pw_trace_GetTraceTime() {
+ auto delta = system_clock::now() - start;
+ return duration_cast<microseconds>(delta).count();
+}
+
+// Microsecond time source
+size_t pw_trace_GetTraceTimeTicksPerSecond() { return 1000000; }
diff --git a/targets/host/target_toolchains.gni b/targets/host/target_toolchains.gni
index 1a9512b..98b094f 100644
--- a/targets/host/target_toolchains.gni
+++ b/targets/host/target_toolchains.gni
@@ -35,8 +35,8 @@
# Configure backend for trace facade.
pw_trace_BACKEND = "$dir_pw_trace_tokenized"
- # Tokenizer trace time, for now using a fake time.
- pw_trace_tokenizer_time = "$dir_pw_trace_tokenized:fake_trace_time"
+ # Tokenizer trace time.
+ pw_trace_tokenizer_time = "$dir_pw_trace_tokenized:host_trace_time"
# Allow nanopb to be toggled via a build arg on host for easy testing.
_has_nanopb = pw_protobuf_GENERATORS + [ "nanopb" ] - [ "nanopb" ] !=