Skip to content

Commit 2da1274

Browse files
authored
Merge pull request #1072 from minuteos/feat/stlink-swo
SWO support when using ST-LINK GDB server
2 parents 767476a + a992b46 commit 2da1274

File tree

6 files changed

+84
-17
lines changed

6 files changed

+84
-17
lines changed

CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* It is not clear what (should) happens when you use the `Restart` button when multiple debuggers are active at the same time. For instance in a multi-core session. It may work, but we have not tested it.
1111
* This is the reason why we implemented the `Reset` button a while ago because VSCode `Restart` meant different (undocumented) behaviors at different times.
1212
* As a result, all the Restart related launch.json properties no longer apply. But, for compatibility reasons, they still exist and used by the `Reset` functionality when a `Reset` specific property does not exist. This is what used to happen in the previous releases.
13+
* ST-LINK GDB server (*not* st-util) now supports SWO functionality, using standard configuration options.
1314

1415
# V1.12.1
1516
* Fix for [#923: Local variables with same name between functions not tracking or updating context](https://github.com/Marus/cortex-debug/issues/923)
@@ -27,9 +28,9 @@ This is a major release. It has been in pre-release for quite a while and some o
2728
* [RTOS Views](https://marketplace.visualstudio.com/items?itemName=mcu-debug.rtos-views)
2829
* [Memory View](https://marketplace.visualstudio.com/items?itemName=mcu-debug.memory-view)
2930
* [Peripheral Viewer](https://marketplace.visualstudio.com/items?itemName=mcu-debug.peripheral-viewer)
30-
31+
3132
*Note: Please install this extension using VSCode with a working internet connection. Do not try to install it manually. If you install it manually, then also make sure all the other dependent extensions are installed.*
32-
33+
3334
# V1.11.3
3435
* Issue #861: Potential fix
3536
* Issue #867: STLink make it so that user has to enable `-shared` if needed. Before it was automatically added to the command-line and there was no (good) way to remove it

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
Debugging support for ARM Cortex-M Microcontrollers with the following features:
66

77
* Highly configurable. See https://github.com/Marus/cortex-debug/blob/master/debug_attributes.md
8-
* Support J-Link, OpenOCD GDB Server, STMicroelectronic's ST-LINK GDB server (no SWO support yet), pyOCD
8+
* Support J-Link, OpenOCD GDB Server, STMicroelectronic's ST-LINK GDB server, pyOCD
99
* Initial support for the Black Magic Probe (This has not been as heavily tested; SWO can only be captured via a serial port)
1010
* Partial support textane/stlink (st-util) GDB Servers (SWO can only be captured via a serial port)
1111
* Multi-core and multi-session debugging. See https://github.com/Marus/cortex-debug/wiki/Multi-core-debugging

src/frontend/configprovider.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -589,12 +589,6 @@ export class CortexDebugConfigurationProvider implements vscode.DebugConfigurati
589589
return 'The ST-Link GDB Server does not have support for the rtos option.';
590590
}
591591

592-
if (config.swoConfig.enabled && config.swoConfig.source === 'probe') {
593-
vscode.window.showWarningMessage('SWO support is not available from the probe when using the ST-Link GDB server. Disabling SWO.');
594-
config.swoConfig = { enabled: false, ports: [], cpuFrequency: 0, swoFrequency: 0 };
595-
config.graphConfig = [];
596-
}
597-
598592
return null;
599593
}
600594

src/frontend/swo/core.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,9 +289,14 @@ export class SWOCore extends SWORTTCoreBase {
289289
}, (error) => {
290290
this.functionSymbols = [];
291291
});
292-
293-
if (this.source.connected) { this.connected = true; }
294-
else { this.source.on('connected', () => { this.connected = true; }); }
292+
293+
const onConnected = () => {
294+
this.connected = true;
295+
session.customRequest('swo-connected');
296+
};
297+
298+
if (this.source.connected) { onConnected(); }
299+
else { this.source.on('connected', onConnected); }
295300
this.source.on('data', this.handleData.bind(this));
296301
this.source.on('disconnected', this.handleDisconnected.bind(this));
297302

src/gdb.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import { extractBits, hexFormat } from './frontend/utils';
1515
import { Variable, VariableObject, MIError, OurDataBreakpoint, OurInstructionBreakpoint, OurSourceBreakpoint } from './backend/backend';
1616
import {
1717
TelemetryEvent, ConfigurationArguments, StoppedEvent, GDBServerController, SymbolFile,
18-
createPortName, GenericCustomEvent, quoteShellCmdLine, toStringDecHexOctBin, ADAPTER_DEBUG_MODE, defSymbolFile, CTIAction, getPathRelative
18+
createPortName, GenericCustomEvent, quoteShellCmdLine, toStringDecHexOctBin, ADAPTER_DEBUG_MODE, defSymbolFile, CTIAction, getPathRelative,
19+
SWOConfigureEvent
1920
} from './common';
2021
import { GDBServer, ServerConsoleLog } from './backend/server';
2122
import { MINode } from './backend/mi_parse';
@@ -267,6 +268,9 @@ export class GDBDebugSession extends LoggingDebugSession {
267268

268269
protected tcpPortAllocatedListner = this.tcpPortsAllocated.bind(this);
269270

271+
private swoLaunchPromise = Promise.resolve();
272+
private swoLaunched?: () => void;
273+
270274
public constructor(debuggerLinesStartAt1: boolean, public readonly isServer: boolean = false, threadID: number = 1) {
271275
super(undefined, debuggerLinesStartAt1, isServer); // Use if deriving from LogDebugSession
272276
// super(debuggerLinesStartAt1, isServer); // Use if deriving from DebugSession
@@ -660,6 +664,9 @@ export class GDBDebugSession extends LoggingDebugSession {
660664
if (showTimes) { this.handleMsg('log', 'Debug Time: objdump and nm done...\n'); }
661665
if (showTimes) { this.handleMsg('log', 'Debug Time: All pending items done, proceed to gdb connect...\n'); }
662666

667+
// if SWO launch was requested by the server controller, we wait for it to connect before starting actual debug
668+
await this.swoLaunchPromise;
669+
663670
// This is the last of the place where ports are allocated
664671
this.sendEvent(new GenericCustomEvent('post-start-server', this.args));
665672
commands.push(...this.serverController.initCommands());
@@ -1211,6 +1218,11 @@ export class GDBDebugSession extends LoggingDebugSession {
12111218
}
12121219
break;
12131220
}
1221+
case 'swo-connected': {
1222+
this.swoLaunched?.();
1223+
this.swoLaunched = undefined;
1224+
break;
1225+
}
12141226
default:
12151227
response.body = { error: 'Invalid command.' };
12161228
this.sendResponse(response);
@@ -1674,6 +1686,16 @@ export class GDBDebugSession extends LoggingDebugSession {
16741686
}
16751687

16761688
private serverControllerEvent(event: DebugProtocol.Event) {
1689+
if (event instanceof SWOConfigureEvent) {
1690+
this.swoLaunchPromise = new Promise((resolve, reject) => {
1691+
const timeout = setTimeout(() => reject(new Error('Timeout waiting for SWV connection')), 1000);
1692+
this.swoLaunched = () => {
1693+
clearTimeout(timeout);
1694+
resolve();
1695+
};
1696+
});
1697+
}
1698+
16771699
this.sendEvent(event);
16781700
}
16791701

src/stlink.ts

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,34 @@ export class STLinkServerController extends EventEmitter implements GDBServerCon
134134
return commands;
135135
}
136136

137-
public swoAndRTTCommands(): string[] {
138-
return [];
137+
public swoAndRTTCommands(): string[]{
138+
const commands = [];
139+
if (this.args.swoConfig.enabled) {
140+
const swocommands = this.SWOConfigurationCommands();
141+
commands.push(...swocommands);
142+
}
143+
return commands;
144+
}
145+
146+
private SWOConfigurationCommands(): string[] {
147+
const { decoders, swoFrequency, cpuFrequency } = this.args.swoConfig;
148+
const portMask = '0x' + calculatePortMask(decoders).toString(16);
149+
const ratio = Math.floor(cpuFrequency / swoFrequency) - 1;
150+
151+
const commands = [
152+
'EnableITMAccess',
153+
`BaseSWOSetup ${ratio}`,
154+
'SetITMId 1',
155+
'ITMDWTTransferEnable',
156+
'DisableITMPorts 0xFFFFFFFF',
157+
`EnableITMPorts ${portMask}`,
158+
'EnableDWTSync',
159+
this.args.swoConfig.profile ? 'EnablePCSample' : 'DisablePCSample',
160+
'ITMSyncEnable',
161+
'ITMGlobalEnable'
162+
];
163+
164+
return commands.map((c) => `interpreter-exec console "${c}"`);
139165
}
140166

141167
public serverExecutable(): string {
@@ -176,6 +202,17 @@ export class STLinkServerController extends EventEmitter implements GDBServerCon
176202
serverargs.push('--swd');
177203
}
178204

205+
if (this.args.swoConfig.enabled)
206+
{
207+
const swoport = this.ports['swoPort'];
208+
serverargs.push('--swo-port', swoport.toString());
209+
210+
const { cpuFrequency, swoFrequency } = this.args.swoConfig;
211+
212+
serverargs.push('--cpu-clock', cpuFrequency.toString());
213+
serverargs.push('--swo-clock-div', Math.floor(cpuFrequency / swoFrequency).toString());
214+
}
215+
179216
if (this.args.serialNumber) {
180217
serverargs.push('--serial-number', this.args.serialNumber);
181218
}
@@ -196,8 +233,16 @@ export class STLinkServerController extends EventEmitter implements GDBServerCon
196233
}
197234

198235
public serverLaunchStarted(): void {}
199-
public serverLaunchCompleted(): void {}
200-
236+
public serverLaunchCompleted(): void {
237+
if (this.args.swoConfig.enabled) {
238+
this.emit('event', new SWOConfigureEvent({
239+
type: 'socket',
240+
args: this.args,
241+
port: this.ports['swoPort'].toString()
242+
}));
243+
}
244+
}
245+
201246
public debuggerLaunchStarted(): void {}
202247
public debuggerLaunchCompleted(): void {}
203248
}

0 commit comments

Comments
 (0)