Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[VSC-1473/1495] update dockerfile and qemu options #1282

Merged
merged 10 commits into from
Oct 28, 2024
7 changes: 5 additions & 2 deletions docs_espressif/en/additionalfeatures/docker-container.rst
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,11 @@ for a list of USB serial devices.
.. note::
this command needs to be used only one time,unless the computer has restarted. **1-1** is the device's bus id ``<BUSID>`` I would like to bind.

5. After binding, please attach the specified device to WSL with this command in the Powershell command prompt.
5. After binding, please attach the specified device to WSL with this command in the Powershell command prompt. The ``--auto-attach`` parameter allows the device to be visible in the container after unplug and plug.

.. code-block::

usbipd attach --wsl --busid <BUSID>
usbipd attach --wsl --busid <BUSID> --auto-attach

6. At last, let us check if it works well on both side and type this command on WSL side.

Expand Down Expand Up @@ -231,6 +231,9 @@ Create a Container

At this moment, you can start to use the ``Blink`` example project for building, flashing, monitoring, debugging, etc.

.. warning::
* In order to have access to the serial port from the Docker container, make sure you have attached the device with ``usbipd attach --wsl --busid <BUSID> --auto-attach`` **BEFORE** opening the folder in container in VS Code otherwise it won't be visible. If you want to be able to plug and unplug the device and still see it in the docker container don't forget the ``--auto-attach`` usbipd parameter.

3. Here taking the esp32-c3 as an example, users only need to change the target device from ``esp32`` to ``esp32-c3``, as below:

.. image:: ../../../media/tutorials/using_docker_container/device_target_esp32_c3.png
Expand Down
2 changes: 2 additions & 0 deletions l10n/bundle.l10n.es.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@
"{destFolder} already exists.": "{destFolder} ya existe.",
"ESP-IDF Project has been imported": "El proyecto ESP-IDF ha sido importado.",
"Merging binaries for flashing": "Fusionar binarios para flashear",
"ESP-IDF: Starting ESP-IDF QEMU Debug": "ESP-IDF: Iniciando la depuración QEMU de ESP-IDF",
"Error launching QEMU debugging": "Error al iniciar la depuración de QEMU",
"Select a partition to use": "Seleccione una partición para usar",
"Enter custom partition table offset": "Ingrese el desplazamiento de la tabla de particiones personalizada",
"Flash binary to this partition": "Flash binario a esta partición",
Expand Down
2 changes: 2 additions & 0 deletions l10n/bundle.l10n.pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@
"{destFolder} already exists.": "{destFolder} já existe.",
"ESP-IDF Project has been imported": "O projeto ESP-IDF foi importado",
"Merging binaries for flashing": "Mesclando binários para piscar",
"ESP-IDF: Starting ESP-IDF QEMU Debug": "ESP-IDF: Iniciando a depuração ESP-IDF QEMU",
"Error launching QEMU debugging": "Erro ao iniciar a depuração do QEMU",
"Select a partition to use": "Selecione uma partição para usar",
"Enter custom partition table offset": "Insira o deslocamento da tabela de partição personalizada",
"Flash binary to this partition": "Flash binário para esta partição",
Expand Down
2 changes: 2 additions & 0 deletions l10n/bundle.l10n.ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@
"{destFolder} already exists.": "{destFolder} уже существует.",
"ESP-IDF Project has been imported": "Проект ESP-IDF импортирован.",
"Merging binaries for flashing": "Объединение бинарников для перепрошивки",
"ESP-IDF: Starting ESP-IDF QEMU Debug": "ESP-IDF: запуск отладки ESP-IDF QEMU",
"Error launching QEMU debugging": "Ошибка запуска отладки QEMU",
"Select a partition to use": "Выберите раздел для использования",
"Enter custom partition table offset": "Введите пользовательское смещение таблицы разделов",
"Flash binary to this partition": "Записать двоичный файл в этот раздел",
Expand Down
2 changes: 2 additions & 0 deletions l10n/bundle.l10n.zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@
"{destFolder} already exists.": "{destFolder} 已存在。",
"ESP-IDF Project has been imported": "ESP-IDF 项目已导入",
"Merging binaries for flashing": "合并二进制文件以进行闪烁",
"ESP-IDF: Starting ESP-IDF QEMU Debug": "ESP-IDF:启动 ESP-IDF QEMU 调试",
"Error launching QEMU debugging": "启动 QEMU 调试时出错",
"Select a partition to use": "选择要使用的分区",
"Enter custom partition table offset": "输入自定义分区表偏移量",
"Flash binary to this partition": "将二进制文件烧录到该分区",
Expand Down
9 changes: 9 additions & 0 deletions src/build/buildCmd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@ export async function buildCommand(
await TaskManager.runTasks();
}
}
const buildDirPath = readParameter(
"idf.buildPath",
workspace
) as string;
const qemuBinPath = join(buildDirPath, "merged_qemu.bin");
const qemuBinExists = await pathExists(qemuBinPath);
if (qemuBinExists) {
await vscode.workspace.fs.delete(vscode.Uri.file(qemuBinPath));
}
if (!cancelToken.isCancellationRequested) {
updateIdfComponentsTree(workspace);
Logger.infoNotify("Build Successfully");
Expand Down
235 changes: 154 additions & 81 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ import { configureProjectWithGcov } from "./coverage/configureProject";
import { ComponentManagerUIPanel } from "./component-manager/panel";
import { verifyAppBinary } from "./espIdf/debugAdapter/verifyApp";
import { mergeFlashBinaries } from "./qemu/mergeFlashBin";
import { IQemuOptions, QemuManager } from "./qemu/qemuManager";
import { QemuLaunchMode, QemuManager } from "./qemu/qemuManager";
import {
PartitionItem,
PartitionTreeDataProvider,
Expand Down Expand Up @@ -356,9 +356,38 @@ export async function activate(context: vscode.ExtensionContext) {
} else {
UpdateCmakeLists.updateSrcsInCmakeLists(e.fsPath, srcOp.other);
}
await binTimestampEventFunc(e);
});
context.subscriptions.push(srcWatchOnChangeDisposable);

const buildWatcher = vscode.workspace.createFileSystemWatcher(
"**/.bin_timestamp",
false,
false,
true
);

const binTimestampEventFunc = async (e: vscode.Uri) => {
const buildDirPath = idfConf.readParameter(
"idf.buildPath",
workspaceRoot
) as string;
const qemuBinPath = path.join(buildDirPath, "merged_qemu.bin");
const qemuBinExists = await pathExists(qemuBinPath);
if (qemuBinExists) {
await vscode.workspace.fs.delete(vscode.Uri.file(qemuBinPath));
}
};

const buildWatcherDisposable = buildWatcher.onDidChange(
binTimestampEventFunc
);
context.subscriptions.push(buildWatcherDisposable);
const buildWatcherCreateDisposable = buildWatcher.onDidCreate(
binTimestampEventFunc
);
context.subscriptions.push(buildWatcherCreateDisposable);

vscode.workspace.onDidChangeWorkspaceFolders(async (e) => {
if (PreCheck.isWorkspaceFolderOpen()) {
for (const ws of e.removed) {
Expand Down Expand Up @@ -426,9 +455,6 @@ export async function activate(context: vscode.ExtensionContext) {
workspace: workspaceRoot,
} as IOpenOCDConfig;
openOCDManager.configureServer(openOCDConfig);
qemuManager.configure({
workspaceFolder: workspaceRoot,
} as IQemuOptions);
}
ConfserverProcess.dispose();
});
Expand Down Expand Up @@ -964,9 +990,6 @@ export async function activate(context: vscode.ExtensionContext) {
workspace: workspaceRoot,
} as IOpenOCDConfig;
openOCDManager.configureServer(openOCDConfig);
qemuManager.configure({
workspaceFolder: workspaceRoot,
} as IQemuOptions);
ConfserverProcess.dispose();
const coverageOptions = getCoverageOptions(workspaceRoot);
covRenderer = new CoverageRenderer(workspaceRoot, coverageOptions);
Expand Down Expand Up @@ -1173,10 +1196,6 @@ export async function activate(context: vscode.ExtensionContext) {
}
} else if (e.affectsConfiguration("idf.espIdfPath" + winFlag)) {
ESP.URL.Docs.IDF_INDEX = undefined;
} else if (e.affectsConfiguration("idf.qemuTcpPort")) {
qemuManager.configure({
tcpPort: idfConf.readParameter("idf.qemuTcpPort", workspaceRoot),
} as IQemuOptions);
} else if (e.affectsConfiguration("idf.port" + winFlag)) {
if (statusBarItems && statusBarItems["port"]) {
statusBarItems["port"].text =
Expand Down Expand Up @@ -2436,52 +2455,79 @@ export async function activate(context: vscode.ExtensionContext) {

registerIDFCommand("espIdf.qemuDebug", () => {
PreCheck.perform([openFolderCheck], async () => {
if (IDFMonitor.terminal) {
IDFMonitor.terminal.sendText(ESP.CTRL_RBRACKET);
}
const buildDirPath = idfConf.readParameter(
"idf.buildPath",
const notificationMode = idfConf.readParameter(
"idf.notificationMode",
workspaceRoot
) as string;
const qemuBinExists = await pathExists(
path.join(buildDirPath, "merged_qemu.bin")
);
if (!qemuBinExists) {
await mergeFlashBinaries(workspaceRoot);
}
if (qemuManager.isRunning()) {
qemuManager.stop();
await utils.sleep(1000);
}
qemuManager.configureWithDefValues();
qemuManager.start();
const gdbPath = await utils.getToolchainPath(workspaceRoot, "gdb");
const workspaceFolder = vscode.workspace.getWorkspaceFolder(
workspaceRoot
);
await vscode.debug.startDebugging(workspaceFolder, {
name: "GDB QEMU",
type: "gdbtarget",
request: "attach",
sessionID: "qemu.debug.session",
gdb: gdbPath,
initCommands: [
"set remote hardware-watchpoint-limit {IDF_TARGET_CPU_WATCHPOINT_NUM}",
"mon reset halt",
"maintenance flush register-cache",
"thb app_main",
],
target: {
type: "remote",
host: "localhost",
port: "1234",
const ProgressLocation =
notificationMode === idfConf.NotificationMode.All ||
notificationMode === idfConf.NotificationMode.Notifications
? vscode.ProgressLocation.Notification
: vscode.ProgressLocation.Window;
await vscode.window.withProgress(
{
cancellable: true,
location: ProgressLocation,
title: vscode.l10n.t("ESP-IDF: Starting ESP-IDF QEMU Debug"),
},
});
vscode.debug.onDidTerminateDebugSession(async (session) => {
if (session.configuration.sessionID === "qemu.debug.session") {
qemuManager.stop();
async (
progress: vscode.Progress<{ message: string; increment: number }>,
cancelToken: vscode.CancellationToken
) => {
try {
if (IDFMonitor.terminal) {
IDFMonitor.terminal.sendText(ESP.CTRL_RBRACKET);
}
const buildDirPath = idfConf.readParameter(
"idf.buildPath",
workspaceRoot
) as string;
const qemuBinExists = await pathExists(
path.join(buildDirPath, "merged_qemu.bin")
);
if (!qemuBinExists) {
await mergeFlashBinaries(workspaceRoot);
}
if (qemuManager.isRunning()) {
qemuManager.stop();
await utils.sleep(1000);
}
await qemuManager.start(QemuLaunchMode.Debug, workspaceRoot);
const gdbPath = await utils.getToolchainPath(workspaceRoot, "gdb");
const workspaceFolder = vscode.workspace.getWorkspaceFolder(
workspaceRoot
);
await vscode.debug.startDebugging(workspaceFolder, {
name: "GDB QEMU",
type: "gdbtarget",
request: "attach",
sessionID: "qemu.debug.session",
gdb: gdbPath,
initCommands: [
"set remote hardware-watchpoint-limit {IDF_TARGET_CPU_WATCHPOINT_NUM}",
"mon reset halt",
"maintenance flush register-cache",
"thb app_main",
],
target: {
type: "remote",
host: "localhost",
port: "1234",
},
});
vscode.debug.onDidTerminateDebugSession(async (session) => {
if (session.configuration.sessionID === "qemu.debug.session") {
qemuManager.stop();
}
});
} catch (error) {
const msg = error.message
? error.message
: vscode.l10n.t("Error launching QEMU debugging");
Logger.errorNotify(msg, error, "extension qemu debug");
}
}
});
);
});
});

Expand Down Expand Up @@ -3861,35 +3907,62 @@ const flash = (

function createQemuMonitor() {
PreCheck.perform([openFolderCheck], async () => {
const isQemuLaunched = qemuManager.isRunning();
if (isQemuLaunched) {
qemuManager.stop();
}
const qemuTcpPort = idfConf.readParameter(
"idf.qemuTcpPort",
workspaceRoot
) as number;
qemuManager.configure({
launchArgs: [
"-nographic",
"-machine",
"esp32",
"-drive",
"file=build/merged_qemu.bin,if=mtd,format=raw",
"-monitor stdio",
`-serial tcp::${qemuTcpPort},server,nowait`,
],
} as IQemuOptions);
await qemuManager.start();
if (IDFMonitor.terminal) {
await utils.sleep(1000);
}
const serialPort = `socket://localhost:${qemuTcpPort}`;
const noReset = idfConf.readParameter(
"idf.monitorNoReset",
const notificationMode = idfConf.readParameter(
"idf.notificationMode",
workspaceRoot
) as boolean;
await createNewIdfMonitor(workspaceRoot, noReset, serialPort);
) as string;
const ProgressLocation =
notificationMode === idfConf.NotificationMode.All ||
notificationMode === idfConf.NotificationMode.Notifications
? vscode.ProgressLocation.Notification
: vscode.ProgressLocation.Window;
await vscode.window.withProgress(
{
cancellable: true,
location: ProgressLocation,
title: "ESP-IDF: Starting ESP-IDF QEMU Monitor",
},
async (
progress: vscode.Progress<{ message: string; increment: number }>,
cancelToken: vscode.CancellationToken
) => {
try {
const isQemuLaunched = qemuManager.isRunning();
if (isQemuLaunched) {
qemuManager.stop();
}
const buildDirPath = idfConf.readParameter(
"idf.buildPath",
workspaceRoot
) as string;
const qemuBinExists = await pathExists(
path.join(buildDirPath, "merged_qemu.bin")
);
if (!qemuBinExists) {
await mergeFlashBinaries(workspaceRoot);
}
const qemuTcpPort = idfConf.readParameter(
"idf.qemuTcpPort",
workspaceRoot
) as string;
await qemuManager.start(QemuLaunchMode.Monitor, workspaceRoot);
if (IDFMonitor.terminal) {
await utils.sleep(1000);
}
const serialPort = `socket://localhost:${qemuTcpPort}`;
const noReset = idfConf.readParameter(
"idf.monitorNoReset",
workspaceRoot
) as boolean;
await createNewIdfMonitor(workspaceRoot, noReset, serialPort);
} catch (error) {
const msg = error.message
? error.message
: "Error launching QEMU monitor";
Logger.errorNotify(msg, error, "extension qemu monitor");
}
}
);
});
}

Expand Down
Loading