Skip to content

Commit

Permalink
[WIP] Defmt print support
Browse files Browse the repository at this point in the history
Signed-off-by: paulober <[email protected]>
  • Loading branch information
paulober committed Oct 18, 2024
1 parent 2143185 commit 6931f3a
Show file tree
Hide file tree
Showing 12 changed files with 281 additions and 16 deletions.
2 changes: 2 additions & 0 deletions .vscodeignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ tmp.py
!scripts/Pico.code-profile
!scripts/raspberrypi-swd.cfg
!data/**
!scripts/rttDecoder.mjs
!scripts/rttDecoder.js
scripts/*.ps1
scripts/fix_windows_reg.py
scripts/vscodeUninstaller.mjs
Expand Down
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,12 @@
"title": "Flash Pico Project (SWD)",
"category": "Raspberry Pi Pico",
"enablement": "raspberry-pi-pico.isPicoProject && !raspberry-pi-pico.isRustProject"
},
{
"command": "raspberry-pi-pico.getRTTDecoderPath",
"title": "Get RTT Decoder module path",
"category": "Raspberry Pi Pico",
"enablement": "false"
}
],
"configuration": {
Expand Down
98 changes: 98 additions & 0 deletions scripts/rttDecoder.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
const { spawn } = require('child_process');

class DefmtDecoder {
constructor() {
this.process = null;
this.elfPath = null;
this.displayOutput = null;
this.graphData = null;
this.ports = [];
}

init(config, displayOutput, graphData) {
// Store the callbacks and elfPath from the config
this.elfPath = config.elfPath;
this.displayOutput = displayOutput;
this.graphData = graphData;
this.ports = config.ports;

const defmtPrintPath = `${process.platform === "win32" ? process.env.USERPROFILE : process.env.HOME}/.cargo/bin/defmt-print${process.platform === "win32" ? ".exe" : ""}`;

// Spawn the defmt-print process with the provided ELF path
this.process = spawn(defmtPrintPath, ['-e', this.elfPath, "stdin"]);

// Handle data from defmt-print stdout and relay it to the displayOutput callback
this.process.stdout.on('data', (data) => {
if (this.displayOutput) {
this.displayOutput(data.toString());
}
});

// Handle errors from defmt-print stderr
this.process.stderr.on('data', (data) => {
if (this.displayOutput) {
this.displayOutput(data.toString());
}
});

// Handle when the process closes
this.process.on('close', (code) => {
if (this.displayOutput) {
this.displayOutput(`Decoding process exited with code: ${code}`);
}
});
}

sendData(input) {
// Write input data to defmt-print's stdin
try {
if (this.process && this.process.stdin.writable) {
this.process.stdin.write(input);
return;
}
} catch { }

throw new Error('Process stdin is not writable.');
}

// Expected methods from the SWODecoder API conforming to the AdvancedDecoder interface

typeName() {
return 'DefmtDecoder';
}

outputLabel() {
return 'RPi Pico';
}

softwareEvent(port, data) {
if (this.ports.indexOf(port) !== -1) {
// Handle the software event, potentially by sending data to defmt-print stdin
this.sendData(data);
}
}

synchronized() {
// Handle the synchronized event
if (this.displayOutput) {
this.displayOutput('Synchronized');
}
}

lostSynchronization() {
// Handle the lost synchronization event
if (this.displayOutput) {
this.displayOutput('Lost synchronization');
}
}

dispose() {
// Clean up the process
if (this.process) {
this.process.kill();
this.process = null;
}
}
}

module.exports = exports = DefmtDecoder;
121 changes: 121 additions & 0 deletions scripts/rttDecoder.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { spawn } from 'child_process';
import EventEmitter from 'events';

/*
interface AdvancedDecoder {
init(
config: SWOAdvancedDecoderConfig,
outputData: (output: string) => void,
graphData: (data: number, id: string) => void
): void;
typeName(): string;
outputLabel(): string;
softwareEvent(port: number, data: Buffer): void;
synchronized(): void;
lostSynchronization(): void;
}*/

class DefmtDecoder extends EventEmitter {
constructor() {
this.process = null;
this.elfPath = null;
this.displayOutput = null;
this.graphData = null;
}

init(config, displayOutput, graphData) {
// Store the callbacks and elfPath from the config
this.elfPath = config.config.elfPath;
this.displayOutput = displayOutput;
this.graphData = graphData;

const defmtPrintPath = `${process.platform === "win32" ? process.env.USERPROFILE : process.env.HOME}/.cargo/bin/defmt-print${process.platform === "win32" ? ".exe" : ""}`;

// Spawn the defmt-print process with the provided ELF path
this.process = spawn(defmtPrintPath, ['-e', this.elfPath, "stdin"]);

// Handle data from defmt-print stdout and relay it to the displayOutput callback
this.process.stdout.on('data', (data) => {
if (this.displayOutput) {
this.displayOutput(data.toString());
}
});

// Handle errors from defmt-print stderr
this.process.stderr.on('data', (data) => {
if (this.displayOutput) {
//this.displayOutput(`Error: ${data.toString()}`);
this.displayOutput(data.toString());
}
});

// Handle when the process closes
this.process.on('close', (code) => {
if (this.displayOutput) {
this.displayOutput(`Decoding process exited with code: ${code}`);
}
});
}

//sendData(input: Buffer): void;
sendData(input) {
// Write input data to defmt-print's stdin
try {
if (this.process && this.process.stdin.writable) {
this.process.stdin.write(input);
return;
}
} catch { }

throw new Error('Process stdin is not writable.');
}

// Expected methods from the SWODecoder API conforming to the AdvancedDecoder interface

//typeName(): string;
typeName() {
return 'DefmtDecoder';
}

//outputLabel(): string;
outputLabel() {
return 'RPi Pico';
}

//softwareEvent(port: number, data: Buffer): void;
softwareEvent(port, data) {
if (this.ports.indexOf(port) !== -1) {
// Handle the software event, potentially by sending data to defmt-print stdin
this.sendData(data);
}
}

//synchronized(): void;
synchronized() {
// Handle the synchronized event
if (this.displayOutput) {
this.displayOutput('Synchronized');
}
}

//lostSynchronization(): void;
lostSynchronization() {
// Handle the lost synchronization event
if (this.displayOutput) {
this.displayOutput('Lost synchronization');
}
}

// own dispose method

dispose() {
// Clean up the process
if (this.process) {
this.process.kill();
this.process = null;
}
this.emit('dispose');
}
}

export default DefmtDecoder;
6 changes: 3 additions & 3 deletions src/commands/getPaths.mts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ import Settings, { SettingsKey } from "../settings.mjs";
import which from "which";
import { execSync } from "child_process";
import { getPicotoolReleases } from "../utils/githubREST.mjs";
import { openOCDVersion } from "../webview/newProjectPanel.mjs";
import State from "../state.mjs";
import VersionBundlesLoader from "../utils/versionBundles.mjs";
import { getSupportedToolchains } from "../utils/toolchainUtil.mjs";
import Logger from "../logger.mjs";
import { rustProjectGetSelectedChip } from "../utils/rustUtil.mjs";
import { OPENOCD_VERSION } from "../utils/sharedConstants.mjs";

export class GetPythonPathCommand extends CommandWithResult<string> {
constructor() {
Expand Down Expand Up @@ -394,7 +394,7 @@ export class GetOpenOCDRootCommand extends CommandWithResult<
this.running = true;

// check if it is installed if not install it
const result = await downloadAndInstallOpenOCD(openOCDVersion);
const result = await downloadAndInstallOpenOCD(OPENOCD_VERSION);

if (result === null || !result) {
this.running = false;
Expand All @@ -404,7 +404,7 @@ export class GetOpenOCDRootCommand extends CommandWithResult<

this.running = false;

return buildOpenOCDPath(openOCDVersion);
return buildOpenOCDPath(OPENOCD_VERSION);
}
}

Expand Down
19 changes: 19 additions & 0 deletions src/commands/rttDecoder.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Logger from "../logger.mjs";
import { CommandWithResult } from "./command.mjs";
import { Uri } from "vscode";

export default class GetRTTDecoderPathCommand extends CommandWithResult<string> {

Check warning on line 5 in src/commands/rttDecoder.mts

View workflow job for this annotation

GitHub Actions / build

This line has a length of 81. Maximum allowed is 80
private readonly _logger = new Logger("GetRTTDecoderPathCommand");

public static readonly id = "getRTTDecoderPath";

constructor(private readonly _extensionUri: Uri) {
super(GetRTTDecoderPathCommand.id);
}

execute(): string {
this._logger.debug("Retrieving RTT decoder path");

return Uri.joinPath(this._extensionUri, "scripts", "rttDecoder.cjs").fsPath;
}
}
6 changes: 4 additions & 2 deletions src/extension.mts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ import { getSupportedToolchains } from "./utils/toolchainUtil.mjs";
import {
NewProjectPanel,
getWebviewOptions,
openOCDVersion,
} from "./webview/newProjectPanel.mjs";
import GithubApiCache from "./utils/githubApiCache.mjs";
import ClearGithubApiCacheCommand from "./commands/clearGithubApiCache.mjs";
Expand All @@ -87,6 +86,8 @@ import {
} from "./utils/rustUtil.mjs";
import State from "./state.mjs";
import { NewRustProjectPanel } from "./webview/newRustProjectPanel.mjs";
import GetRTTDecoderPathCommand from "./commands/rttDecoder.mjs";
import { OPENOCD_VERSION } from "./utils/sharedConstants.mjs";

export async function activate(context: ExtensionContext): Promise<void> {
Logger.info(LoggerSource.extension, "Extension activation triggered");
Expand Down Expand Up @@ -135,6 +136,7 @@ export async function activate(context: ExtensionContext): Promise<void> {
new ImportProjectCommand(context.extensionUri),
new NewExampleProjectCommand(context.extensionUri),
new UninstallPicoSDKCommand(),
new GetRTTDecoderPathCommand(context.extensionUri),
];

// register all command handlers
Expand Down Expand Up @@ -537,7 +539,7 @@ export async function activate(context: ExtensionContext): Promise<void> {
},
async progress => {
const result = await downloadAndInstallOpenOCD(
openOCDVersion,
OPENOCD_VERSION,
(prog: GotProgress) => {
const percent = prog.percent * 100;
progress.report({
Expand Down
4 changes: 2 additions & 2 deletions src/utils/download.mts
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ import { got, type Progress } from "got";
import { pipeline as streamPipeline } from "node:stream/promises";
import {
CURRENT_PYTHON_VERSION,
OPENOCD_VERSION,
WINDOWS_ARM64_PYTHON_DOWNLOAD_URL,
WINDOWS_X86_PYTHON_DOWNLOAD_URL,
} from "./sharedConstants.mjs";
import VersionBundlesLoader from "./versionBundles.mjs";
import { openOCDVersion } from "../webview/newProjectPanel.mjs";

/// Translate nodejs platform names to ninja platform names
const NINJA_PLATFORMS: { [key: string]: string } = {
Expand Down Expand Up @@ -1390,7 +1390,7 @@ export async function installLatestRustRequirements(
async progress => {
let progressState = 0;

return downloadAndInstallOpenOCD(openOCDVersion, (prog: Progress) => {
return downloadAndInstallOpenOCD(OPENOCD_VERSION, (prog: Progress) => {
const percent = prog.percent * 100;
progress.report({ increment: percent - progressState });
progressState = percent;
Expand Down
19 changes: 18 additions & 1 deletion src/utils/projectGeneration/projectRust.mts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ async function generateVSCodeConfig(projectRoot: string): Promise<boolean> {
openOCDLaunchCommands: ["adapter speed 5000"],
preLaunchTask: "Compile Project (debug)",
// TODO: does currently not work
rttConfig: {
/*rttConfig: {
enabled: true,
clearSearch: true,
address: "0x2003fbc0",
Expand All @@ -86,6 +86,23 @@ async function generateVSCodeConfig(projectRoot: string): Promise<boolean> {
port: 0,
},
],
},*/
rttConfig: {
enabled: true,
address: "auto",
decoders: [
{
label: "RPi Pico",
type: "advanced",
decoder: "${command:raspberry-pi-pico.getRTTDecoderPath}",
inputmode: "disabled",
noprompt: true,
ports: [0],
config: {
elfPath: "${command:raspberry-pi-pico.launchTargetPath}",
},
},
],
},
},
],
Expand Down
4 changes: 2 additions & 2 deletions src/utils/rustUtil.mts
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,8 @@ export async function downloadAndInstallRust(): Promise<boolean> {
return false;
}

// install probe-rs-tools
const probeRsTools = "probe-rs-tools";
// or install probe-rs-tools
const probeRsTools = "defmt-print";
result = await cargoInstall(probeRsTools, true);
if (!result) {
void window.showErrorMessage(
Expand Down
1 change: 1 addition & 0 deletions src/utils/sharedConstants.mts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export const WINDOWS_ARM64_PYTHON_DOWNLOAD_URL =
export const CURRENT_PYTHON_VERSION = "3.12.6";

export const CURRENT_DATA_VERSION = "0.17.0";
export const OPENOCD_VERSION = "0.12.0+dev";
Loading

0 comments on commit 6931f3a

Please sign in to comment.