Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
31 changes: 26 additions & 5 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 the 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.
For this example, the project has been already configured for application tracing purposes. On other projects you need to enable ``CONFIG_APPTRACE_DEST_JTAG`` 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.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,7 @@
},
"trace.poll_period": {
"type": "number",
"default": 1,
"default": 0,
"scope": "resource",
"description": "%trace.poll_period.description%"
},
Expand All @@ -833,7 +833,7 @@
},
"trace.stop_tmo": {
"type": "number",
"default": 5,
"default": 3,
"scope": "resource",
"description": "%trace.stop_tmo.description%"
},
Expand Down
112 changes: 70 additions & 42 deletions src/espIdf/tracing/appTraceManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ export class AppTraceManager extends EventEmitter {
private archiveDataProvider: AppTraceArchiveTreeDataProvider;
private tclConnectionParams: TCLConnection;
private shallContinueCheckingStatus: boolean;
private workspaceFolder: vscode.Uri;

constructor(
treeDataProvider: AppTraceTreeDataProvider,
Expand All @@ -147,59 +146,82 @@ 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();
});
}
} catch (error) {
Logger.errorNotify(error.message, error, "AppTraceManager start");
}
}

public async stop() {
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);
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();

// Stop OpenOCD server when app tracing finishes naturally
const openOCDManager = OpenOCDManager.init();
if (openOCDManager.isRunning()) {
openOCDManager.stop();
}
});
}

public async stop(workspace: vscode.Uri) {
if (await OpenOCDManager.init().promptUserToLaunchOpenOCDServer()) {
this.shallContinueCheckingStatus = false;
const stopHandler = this.sendCommandToTCLSession(
"esp apptrace stop",
this.workspaceFolder
workspace
);
stopHandler.on("response", (resp: Buffer) => {
const respStr = resp.toString();
Expand All @@ -215,6 +237,12 @@ export class AppTraceManager extends EventEmitter {
);
}
stopHandler.stop();

// Stop OpenOCD server after app tracing is stopped
const openOCDManager = OpenOCDManager.init();
if (openOCDManager.isRunning()) {
openOCDManager.stop();
}
});
} else {
this.treeDataProvider.updateDescription(
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
27 changes: 26 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2532,7 +2532,7 @@ export async function activate(context: vscode.ExtensionContext) {
if (appTraceLabel) {
await appTraceManager.start(workspaceRoot);
} else {
await appTraceManager.stop();
await appTraceManager.stop(workspaceRoot);
}
});
});
Expand Down 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