Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions docs_espressif/en/additionalfeatures/app-tracing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,52 @@ This feature allows to transfer arbitrary data between host and ESP32 via JTAG i

Developers can use this library to send application specific state of execution to the host and receive commands or other type of info in the opposite direction at runtime.

Let's open a ESP-IDF project. For this tutorial we will use the `system/app_trace_to_host <https://github.com/espressif/esp-idf/tree/master/examples/system/app_trace_to_host>`_ example.
Let's open a ESP-IDF project. For this tutorial we will use the `system/app_trace_basic <https://github.com/espressif/esp-idf/tree/master/examples/system/app_trace_basic>`_ example.

- Navigate to **View** > **Command Palette**.

- Type **ESP-IDF: New Project**, select the command and choose ESP-IDF version to use.

If you don't see the option, please review the setup in :ref:`Install ESP-IDF and Tools <installation>`.

- A window will be open with settings to configure the project. Later you can choose from a list a ESP-IDF examples, go the **system** section and choose the ``app_trace_to_host``. You will see a **Create Project Using Example app_trace_to_host** button in the top and a description of the project below. Click the button and the project will be opened in a new window.
- A window will be open with settings to configure the project. Later you can choose from a list a ESP-IDF examples, go the **system** section and choose the ``app_trace_basic``. You will see a **Create Project Using Example app_trace_basic project** button in the top and a description of the project below. Click the button and the project will be opened in a new window.

.. image:: ../../../media/tutorials/app_trace/app_tracing.png

For this example, the project has been already configured for application tracing purposes. On other projects you need to enable ``CONFIG_APPTRACE_DEST_TRAX`` and ``CONFIG_APPTRACE_ENABLE`` with the **ESP-IDF: SDK Configuration Editor** command.

.. note::
For the ``app_trace_basic`` example to work properly, you need to add the following settings to your project's ``.vscode/settings.json`` file:

.. code-block:: json

{
"trace.poll_period": 0,
"trace.trace_size": 2048,
"trace.stop_tmo": 3,
"trace.wait4halt": 0,
"trace.skip_size": 0
}

These settings ensure the same tracing behavior as demonstrated in the example.

- Configure, build and flash your project as explained in the :ref:`Build the project <build the project>`.

- Click the ``ESP-IDF Explorer`` in the `Visual Studio Code Activity bar <https://code.visualstudio.com/docs/getstarted/userinterface>`_ (1). On the ``IDF APP TRACER`` section, click the ``Start App Trace`` (2). This will execute the extension's OpenOCD server and send the corresponding tracing commands to generate a tracing log. You can see the generated tracing log in the ``APP TRACE ARCHIVES`` named with ``Trace Log #1`` (3). Each time you execute ``Start App Trace`` a new tracing will be generated and shown in the archives list. You can also start tracing by running the **ESP-IDF: App Trace** command.
- Click the ``ESP-IDF Explorer`` in the `Visual Studio Code Activity bar <https://code.visualstudio.com/docs/getstarted/userinterface>`_.

1. On the ``IDF APP TRACER`` section, click the ``Start App Trace``. This will execute the extension's OpenOCD server and send the corresponding tracing commands to generate a tracing log.

2. You can see the generated tracing log in the ``APP TRACE ARCHIVES`` named with ``Trace Log #1``.

3. Each time you execute ``Start App Trace`` a new tracing will be generated and shown in the archives list. You can also start tracing by running the **ESP-IDF: App Trace** command.

.. note::
* The OpenOCD server output is shown in menu **View** > **Output** > **ESP-IDF**.
* Make sure that OpenOCD configuration files are properly configured with **ESP-IDF: Select OpenOCD Board Configuration** command.

.. image:: ../../../media/tutorials/app_trace/start_tracing.png

- Click on ``Trace Log #1`` to open a window with the trace report. Click ``Show Report`` button to see the trace output.
- Click on ``Trace Log #1`` to open the trace file directly in the editor.

.. image:: ../../../media/tutorials/app_trace/trace_report.png

Expand Down
Binary file modified media/tutorials/app_trace/app_tracing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified media/tutorials/app_trace/trace_report.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
102 changes: 63 additions & 39 deletions src/espIdf/tracing/appTraceManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,53 +147,77 @@ export class AppTraceManager extends EventEmitter {
AppTraceButtonType.AppTraceButton,
""
);
const fileName = `file:${sep}${sep}${join(
workspace.fsPath,
"trace",
`trace_${new Date().getTime()}.trace`
)}`.replace(/\\/g, "/");
const pollPeriod = idfConf.readParameter(
"trace.poll_period",
workspace
);
this.workspaceFolder = workspace;
const traceSize = idfConf.readParameter("trace.trace_size", workspace) as string;
const stopTmo = idfConf.readParameter("trace.stop_tmo", workspace) as string;
const wait4halt = idfConf.readParameter("trace.wait4halt", workspace) as string;
const skipSize = idfConf.readParameter("trace.skip_size", workspace) as string;
const startTrackingHandler = this.sendCommandToTCLSession(
[
"esp",
"apptrace",
"start",
fileName,
pollPeriod,
traceSize,
stopTmo,
wait4halt,
skipSize,
].join(" "),
workspace
);
const tracingStatusHandler = this.appTracingStatusChecker(() => {
tracingStatusHandler.stop();
startTrackingHandler.stop();

this.treeDataProvider.showStartButton(
AppTraceButtonType.AppTraceButton
);
this.treeDataProvider.updateDescription(
AppTraceButtonType.AppTraceButton,
"[Stopped]"
);
this.archiveDataProvider.populateArchiveTree();
// Send reset command first to ensure proper initialization, then start app trace
const resetHandler = this.sendCommandToTCLSession("reset", workspace);
resetHandler.on("response", () => {
// Reset completed, now start app trace
this.executeAppTraceStart(workspace);
resetHandler.stop();
});

// If reset fails, still try to start app trace
resetHandler.on("error", () => {
this.executeAppTraceStart(workspace);
resetHandler.stop();
});
}
} catch (error) {
Logger.errorNotify(error.message, error, "AppTraceManager start");
}
}

private executeAppTraceStart(workspace: vscode.Uri) {
const fileName = `file:${sep}${sep}${join(
workspace.fsPath,
"trace",
`trace_${new Date().getTime()}.trace`
)}`.replace(/\\/g, "/");
const pollPeriod = idfConf.readParameter("trace.poll_period", workspace);
this.workspaceFolder = workspace;
const traceSize = idfConf.readParameter(
"trace.trace_size",
workspace
) as string;
const stopTmo = idfConf.readParameter(
"trace.stop_tmo",
workspace
) as string;
const wait4halt = idfConf.readParameter(
"trace.wait4halt",
workspace
) as string;
const skipSize = idfConf.readParameter(
"trace.skip_size",
workspace
) as string;
const startTrackingHandler = this.sendCommandToTCLSession(
[
"esp",
"apptrace",
"start",
fileName,
pollPeriod,
traceSize,
stopTmo,
wait4halt,
skipSize,
].join(" "),
workspace
);
const tracingStatusHandler = this.appTracingStatusChecker(() => {
tracingStatusHandler.stop();
startTrackingHandler.stop();

this.treeDataProvider.showStartButton(AppTraceButtonType.AppTraceButton);
this.treeDataProvider.updateDescription(
AppTraceButtonType.AppTraceButton,
"[Stopped]"
);
this.archiveDataProvider.populateArchiveTree();
});
}

public async stop() {
if (await OpenOCDManager.init().promptUserToLaunchOpenOCDServer()) {
this.shallContinueCheckingStatus = false;
Expand Down
33 changes: 23 additions & 10 deletions src/espIdf/tracing/tree/appTraceArchiveTreeDataProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
* Project: ESP-IDF VSCode Extension
* File Created: Tuesday, 16th July 2019 1:38:00 pm
* Copyright 2019 Espressif Systems (Shanghai) CO LTD
*
*
* 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
*
*
* http://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.
Expand Down Expand Up @@ -119,19 +119,32 @@ export class AppTraceArchiveTreeDataProvider
appTraceArchiveNode.fileName = label;
appTraceArchiveNode.filePath = join(traceFolder, fileName);
appTraceArchiveNode.type = type;
appTraceArchiveNode.command = {
command: "espIdf.apptrace.archive.showReport",
title: "Show Report",
arguments: [appTraceArchiveNode],
};

// Only set command for Heap Trace items - App Trace items will open the file directly
if (appTraceArchiveNode.type === TraceType.HeapTrace) {
appTraceArchiveNode.command = {
command: "espIdf.apptrace.archive.showReport",
title: "Show Report",
arguments: [appTraceArchiveNode],
};
appTraceArchiveNode.iconPath = new vscode.ThemeIcon("pulse");
} else {
// For App Trace, set command to open file directly
appTraceArchiveNode.command = {
command: "vscode.open",
title: "Open File",
arguments: [vscode.Uri.file(appTraceArchiveNode.filePath)],
};
appTraceArchiveNode.iconPath = new vscode.ThemeIcon("archive");
}

const traceSize = statSync(appTraceArchiveNode.filePath);
appTraceArchiveNode.description = `${this.sinceAgo(name[1].split(".trace")[0])} ${traceSize.size}B`;
appTraceArchiveNode.tooltip = `${label} has ${traceSize.size} bytes (${this.sinceAgo(name[1].split(".trace")[0])})`;
appTraceArchiveNode.description = `${this.sinceAgo(
name[1].split(".trace")[0]
)} ${traceSize.size}B`;
appTraceArchiveNode.tooltip = `${label} has ${
traceSize.size
} bytes (${this.sinceAgo(name[1].split(".trace")[0])})`;
return appTraceArchiveNode;
}
private sinceAgo(epoch: string): string {
Expand Down
25 changes: 25 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2939,6 +2939,31 @@ export async function activate(context: vscode.ExtensionContext) {
);
}
}

// For App Trace, directly open the file instead of showing the webview
if (trace.type === TraceType.AppTrace) {
try {
const textDocument = await vscode.workspace.openTextDocument(
trace.filePath
);
const column = vscode.window.activeTextEditor
? vscode.window.activeTextEditor.viewColumn
: undefined;
await vscode.window.showTextDocument(textDocument, {
viewColumn: column || vscode.ViewColumn.One,
});
return;
} catch (error) {
Logger.errorNotify(
`Failed to open App Trace file: ${error.message}`,
error,
"extension apptrace showReport openFile"
);
return;
}
}

// For Heap Trace, show the webview as before
AppTracePanel.createOrShow(context, {
trace: {
fileName: trace.fileName,
Expand Down