Skip to content

Commit

Permalink
preparing for V0.4.0.pre2
Browse files Browse the repository at this point in the history
  • Loading branch information
haneefdm committed Aug 10, 2021
1 parent 00823e7 commit 7172679
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 43 deletions.
9 changes: 7 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
ChangeLog

# V0.4.0.pre1
# V0.4.0.pre2

This will be a major release with a lot of changes and many new features. The `TERMINAL` area of VSCode is utilized a lot more heavily to enable bidirectional communication with the firmware. It is used for RTT, SWO and Semi-hosting.

New Features:
* Support for RTT (SEGGER Real Time Trace) with OpenOCD and JLink. See [Issue#456](https://github.com/Marus/cortex-debug/issues/456) for more info
* JLink RTT has a limitation that it can ONLY work with one channel (channel 0). There is another artifact with channel 0 where you may see output from a previous run at the very beginning.
* You can plot RTT data just like you could with SWO. The setup in launch.json is identical. [See this comment](https://github.com/Marus/cortex-debug/issues/456#issuecomment-896021784)
* **Channel sharing:** You can use the same RTT channels in multiple ways. Corte-Debug reads the channel data from OpenOCD/JLink once and distributes to all subscribers (terminals & graphs). For instance, you can plot a channel and also look at its binary data in a terminal. Just use two decoders with the same channel (actually called port) number.
* JLink RTT has a limitation that it can ONLY work with one channel (channel 0). There is another artifact with RTT channels where you may see output from a previous run at the very beginning.
* The default polling interval in OpenOCD is 100 ms. If you are outputting more frequently, try lowering the interval in `launch.json`. 10ms seems more acceptable as a tradeoff between creating bus traffic and not losing/blocking data. If nothing changes, then OpenOCD does do much even if the interval is small.
* SWO console and binary decoded text data now appears in a "TERMINAL" tab instead in the "OUTPUT" tab
* All gdb-server (OpenOCD, JLink, etc.) output is also in the "TERMINAL" tab. In there you can also interact with your semihosting
* Support in debugger for `Jump to Cursor`, thanks to [PR#417](https://github.com/Marus/cortex-debug/pull/417)
* `demangle` is on by default. You can turn it off in `launch.json`
* A change in this pre-release, you will see some debug information in the gdb-server console. You will also see messages output by the extension that are not part of the actual output in bright magenta. This will happen in all terminals (RTT, SWO and console)
* WARNING: The `Adapter Output` window in the `OUTPUT` tab will go away. Replaced by the 'gdb-server' in the `TERMINAL` tab.

# V0.3.13

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1901,5 +1901,5 @@
"compile": "webpack --mode development",
"test-compile": "tsc -p ./"
},
"version": "0.4.0-pre1"
"version": "0.4.0-pre2"
}
7 changes: 7 additions & 0 deletions src/frontend/pty.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ class ACTIONS {
static killLine(n=0) { return (n ? ACTIONS.cursorBack(n) : '') + ACTIONS.killLineForward(); }
};

export function magentaWrite(msg: string, pty: PtyTerminal) {
if (pty) {
pty.write(BR_MAGENTA_FG + msg + RESET);
}
}


/*
** The following events generated by this class
**
Expand Down
53 changes: 28 additions & 25 deletions src/frontend/rtt_terminal.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import * as vscode from 'vscode';
import * as net from 'net';
import * as fs from 'fs';
import { parseHostPort, RTTConsoleDecoderOpts, TerminalInputMode } from '../common';
import { IPtyTerminalOptions, PtyTerminal, RESET } from './pty';
import { RTTConsoleDecoderOpts, TerminalInputMode } from '../common';
import { IPtyTerminalOptions, magentaWrite, PtyTerminal, RESET } from './pty';
import { decoders as DECODER_MAP } from './swo/decoders/utils';
import { SocketRTTSource } from './swo/sources/socket';
import { scrypt } from 'crypto';

export class RTTTerminal {
protected ptyTerm: PtyTerminal;
Expand All @@ -24,8 +22,9 @@ export class RTTTerminal {
src: SocketRTTSource) {
this.ptyOptions = this.createTermOptions(null);
this.createTerminal();
this.openLogFile();
this.binaryFormatter = new BinaryFormatter(this.ptyTerm, this.options.encoding, this.options.scale);
this.connectToSource(src);
this.openLogFile();
setTimeout(() => this.terminal.show(), 100);
}

Expand All @@ -38,17 +37,17 @@ export class RTTTerminal {
this.source = null;
} else if (code === 'ECONNREFUSED') {
// We expect 'ECONNREFUSED' if the server has not yet started.
this.ptyTerm.write(`${e.message}\nPlease report this problem.`);
magentaWrite(`${e.message}\nPlease report this problem.`, this.ptyTerm);
this.source = null;
} else {
this.ptyTerm.write(`${e.message}\nPlease report this problem.`);
magentaWrite(`${e.message}\nPlease report this problem.`, this.ptyTerm);
}
});
src.on('data', (data) => { this.onData(data); });

if (src.connError) {
this.source = src;
this.ptyTerm.write(`${src.connError.message}\nPlease report this problem.`);
magentaWrite(`${src.connError.message}\nPlease report this problem.`, this.ptyTerm);
} else if (src.connected) {
this.source = src;
}
Expand All @@ -62,12 +61,12 @@ export class RTTTerminal {
private onClose() {
this.source = null;
this.inUse = false;
this.binaryFormatter.reset();
if (!this.options.noclear && (this.logFd >= 0)) {
try { fs.closeSync(this.logFd); } catch { };
}
this.logFd = -1;
this.ptyTerm.write(RESET + `\nRTT connection on TCP port ${this.options.tcpPort} ended. Waiting for next connection...`);
this.ptyTerm.write(RESET + '\n');
magentaWrite(`RTT connection on TCP port ${this.options.tcpPort} ended. Waiting for next connection...`, this.ptyTerm);
}

private onData(data: Buffer) {
Expand All @@ -82,7 +81,7 @@ export class RTTTerminal {
}
}
catch (e) {
this.ptyTerm.write(`Error writing data: ${e}\n`);
magentaWrite(`Error writing data: ${e}\n`, this.ptyTerm);
}
}

Expand All @@ -93,7 +92,9 @@ export class RTTTerminal {
this.logFd = fs.openSync(this.options.logfile, 'w');
}
catch (e) {
console.error(`Could not open file ${this.options.logfile} for writing. ${e.toString()}`);
const msg = `Could not open file ${this.options.logfile} for writing. ${e.toString()}`;
console.error(msg);
magentaWrite(msg, this.ptyTerm)
}
}
}
Expand Down Expand Up @@ -131,15 +132,15 @@ export class RTTTerminal {
this.ptyTerm = new PtyTerminal(this.createTermOptions(null));
this.ptyTerm.on('data', this.sendData.bind(this));
this.ptyTerm.on('close', this.terminalClosed.bind(this));
this.binaryFormatter = new BinaryFormatter(this.ptyTerm, this.options.encoding, this.options.scale);
}

protected createPrompt(): string {
return this.options.noprompt ? '' : this.options.prompt || `RTT:${this.options.port}> `
}

static createTermName(options: RTTConsoleDecoderOpts, existing: string | null): string {
const orig = options.label || `RTT Ch:${options.port} ${options.type}`;
const suffix = options.type === 'binary' ? `enc:${getEncoding(options.encoding)}` : options.type;
const orig = options.label || `RTT Ch:${options.port} ${suffix}`;
let ret = orig;
let count = 1;
while (vscode.window.terminals.findIndex((t) => t.name === ret) >= 0) {
Expand Down Expand Up @@ -184,12 +185,13 @@ export class RTTTerminal {
this.openLogFile();
}
catch (e) {
this.ptyTerm.write(`Error: closing fille ${e}\n`);
magentaWrite(`Error: closing fille ${e}\n`, this.ptyTerm);
}
}
this.options = options;
this.ptyOptions = this.createTermOptions(newTermName);;
this.ptyOptions = this.createTermOptions(newTermName);
this.ptyTerm.resetOptions(this.ptyOptions);
this.binaryFormatter = new BinaryFormatter(this.ptyTerm, this.options.encoding, this.options.scale);
this.connectToSource(src);
return true;
}
Expand Down Expand Up @@ -217,25 +219,26 @@ function padLeft(str: string, len: number, chr = ' '): string {
return str;
}

function getEncoding(enc: string): string {
const encodings: string[] = ['signed', 'unsigned', 'Q16.16', 'float'];
if (!enc || this.encodings.indexOf(enc) < 0) {
enc = 'unsigned';
}
return enc;
}

class BinaryFormatter {
private readonly bytesNeeded = 4;
private buffer = Buffer.alloc(4);
private bytesRead = 0;
public readonly encodings: string[] = ['signed', 'unsigned', 'Q16.16', 'float'];

constructor(
protected ptyTerm: PtyTerminal,
protected encoding: string,
protected scale: number) {
this.reset();
if (this.encodings.indexOf(encoding) < 0) {
this.encoding = 'unsigned';
}
this.scale = scale || 1;
}

public reset() {
this.bytesRead = 0;
this.encoding = getEncoding(encoding);
this.scale = scale || 1;
}

public writeBinary(input: string | Buffer) {
Expand Down
18 changes: 6 additions & 12 deletions src/frontend/server_console.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import * as net from 'net';
import * as vscode from 'vscode';
import * as fs from 'fs';
import * as os from 'os';
import { BR_MAGENTA_FG, IPtyTerminalOptions, PtyTerminal, RESET } from './pty';
import { getAnyFreePort, parseHostPort, TerminalInputMode } from '../common';
import {IPtyTerminalOptions, magentaWrite, PtyTerminal } from './pty';
import { getAnyFreePort, TerminalInputMode } from '../common';

export class GDBServerConsole {
protected toBackendServer: net.Server = null;
Expand Down Expand Up @@ -36,10 +36,10 @@ export class GDBServerConsole {
this.ptyTerm.on('close', () => { this.onTerminalClosed(); });
this.ptyTerm.on('data', (data) => { this.sendToBackend(data); });
if (this.toBackend === null) {
this.magentaWrite('Waiting for gdb server to start...');
magentaWrite('Waiting for gdb server to start...', this.ptyTerm);
this.ptyTerm.pause();
} else {
this.magentaWrite('Resuming connection to gdb server...\n');
magentaWrite('Resuming connection to gdb server...\n', this.ptyTerm);
this.ptyTerm.resume();
}
}
Expand All @@ -60,7 +60,7 @@ export class GDBServerConsole {
console.log(msg)
if (this.ptyTerm) {
msg += msg.endsWith('\n') ? '' : '\n';
this.magentaWrite(msg);
magentaWrite(msg, this.ptyTerm);
}
}
finally {}
Expand Down Expand Up @@ -91,12 +91,6 @@ export class GDBServerConsole {
});
}

protected magentaWrite(msg: string) {
if (this.ptyTerm) {
this.ptyTerm.write(BR_MAGENTA_FG + msg + RESET);
}
}

// The gdb-server running in the backend
protected onBackendConnect(socket: net.Socket) {
this.toBackend = socket;
Expand All @@ -106,7 +100,7 @@ export class GDBServerConsole {
socket.setKeepAlive(true);
socket.on('close', () => {
this.debugMsg('onBackendConnect: gdb-server program closed');
this.magentaWrite('GDB server exited. Waiting for next server to start...');
magentaWrite('GDB server exited. Waiting for next server to start...', this.ptyTerm);
this.toBackend = null;
this.ptyTerm.pause();
});
Expand Down
5 changes: 5 additions & 0 deletions src/frontend/swo/decoders/binary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ export class SWOBinaryProcessor implements SWORTTDecoder {
public dispose() {
if (this.output) {
this.output.dispose();
this.output = null;
}
if (this.ptyTerm) {
this.ptyTerm.dispose();
this.ptyTerm = null;
}
}
}
9 changes: 6 additions & 3 deletions src/frontend/swo/decoders/console.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class SWOConsoleProcessor implements SWORTTDecoder {
const basic = `SWO:${config.label || ''}[port:${this.port}`;

if (this.useTerminal) {
return basic + ']';
return basic + '] console';
} else {
return basic + ', type: console]';
}
Expand Down Expand Up @@ -75,8 +75,6 @@ export class SWOConsoleProcessor implements SWORTTDecoder {
const letters = packet.data.toString(this.encoding);

if (this.useTerminal) {
// Not sure why writing to the channel has a 5 second timeout. Thinking it was a left
// over but it was done three years ago. Also, not sure attaching timestamps is worth it
this.ptyTerm.write(letters);
return;
}
Expand Down Expand Up @@ -120,6 +118,11 @@ export class SWOConsoleProcessor implements SWORTTDecoder {
public dispose() {
if (this.output) {
this.output.dispose();
this.output = null;
}
if (this.ptyTerm) {
this.ptyTerm.dispose();
this.ptyTerm = null;
}
}
}

0 comments on commit 7172679

Please sign in to comment.