Skip to content

Commit bf9e455

Browse files
committed
allow no merge of SVD registers addresses
1 parent 4b73034 commit bf9e455

File tree

11 files changed

+95
-20
lines changed

11 files changed

+95
-20
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ ChangeLog
44
* Store register/peripheral settings in the appropriate folder instead of the first folder
55
* Kill gdb-server if the user kills/exits gdb without using the proper disconnect/Stop buttons/process/commands
66
* VSCode was terminating Cortex-Debug before it was done. st-util exit behavior was also not clean as it did not exit on a disconnect.
7+
* Preliminary support for data watchpoints
8+
* svd now can allow no merge of consequtive addresses with a -1 specified for `svdAddrGapThreshold`
9+
* You can now save the output of a gdb-server into a text file by specifying `cortex-debug.dbgServerLogfile` in User/Workspace settings. This will save output from the servers from all sessions (not just the recent). This is primarily for debugging and for users when submitting issues.
10+
* Path names for gdb-servers can be OS specific. For instance `cortex-debug.openocdPath` can be suffixed with one of `.linux`, `.osx` or `.windows`. For instance `cortex-debug.openocdPath.windows` is used only on Windows and if that is missing, it will default looking for cortex-debug.openocdPath`.
11+
* SWO output can now be logged (saved) to a file just like RTT output
712

813
#V0.4.7
914
* Fixed a regression for STLink gdbserver. It was in fact accidentally working in prior releases. The real bug is now fixed. Issue #494

debug_attributes.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@
3131
| serverArgs | Common | Additional arguments to pass to gdb-server command line
3232
| serverpath | Common | This setting can be used to override the gdb-server path user/workspace setting for a particular launch configuration. It is the full pathname to the executable or name of executable if it is in your PATH
3333
| servertype | Common | GDB Server type - supported types are jlink, openocd, pyocd, pe, stlink, stutil, qemu and external
34-
| showDevDebugOutput | Common | Prints all GDB responses to the console
35-
| showDevDebugTimestamps | Common | Show timestamps when 'showDevDebugOutput' is true
36-
| svdAddrGapThreshold | Common | If the gap between registers is less than this threshold (multiple of 8), combine into a single read from device
34+
| showDevDebugOutput | Common | Prints all GDB (parsed) responses to the console. Can also be a string 'raw' or 'raw-only'
35+
| showDevDebugTimestamps | Common | Show timestamps when 'showDevDebugOutput' is enabled
36+
| svdAddrGapThreshold | Common | If the gap between registers is less than this threshold (multiple of 8), combine into a single read from device. -1 means never combine registers and is very slow
3737
| svdFile | Common | Path to an SVD file describing the peripherals of the microcontroller; if not supplied then one may be selected based upon the 'device' entered.
3838
| swoConfig | Common | (unknown)
3939
| targetId | Common | On BMP this is the ID number that should be passed to the attach command (defaults to 1); for PyOCD this is the target identifier (only needed for custom hardware)

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "0.4.8-pre3",
2+
"version": "0.4.8-pre4",
33
"activationEvents": [
44
"onDebugResolve:cortex-debug"
55
],

src/frontend/svd.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ export class SVDParser {
8888
peripherials.sort(PeripheralNode.compare);
8989

9090
for (const p of peripherials) {
91-
p.markAddresses();
91+
// p.markAddresses();
92+
p.collectRanges([]);
9293
}
9394

9495
resolve(peripherials);
@@ -212,16 +213,16 @@ export class SVDParser {
212213
return fields;
213214
}
214215

215-
private static parseRegisters(regInfo_: any[], parent: PeripheralNode | PeripheralClusterNode): PeripheralRegisterNode[] {
216-
const regInfo = [...regInfo_]; // Make a shallow copy,. we will work on this
216+
private static parseRegisters(regInfoOrig: any[], parent: PeripheralNode | PeripheralClusterNode): PeripheralRegisterNode[] {
217+
const regInfo = [...regInfoOrig]; // Make a shallow copy,. we will work on this
217218
const registers: PeripheralRegisterNode[] = [];
218219

219220
const localRegisterMap = {};
220221
for (const r of regInfo) {
221222
const nm = r.name[0];
222223
localRegisterMap[nm] = r;
223224
SVDParser.peripheralRegisterMap[parent.name + '.' + nm] = r;
224-
};
225+
}
225226

226227
// It is wierd to iterate this way but it can handle forward references, are they legal? not sure
227228
// Or we could have done this work in the loop above. Not the best way, but it is more resilient to
@@ -386,7 +387,7 @@ export class SVDParser {
386387
}
387388

388389
private static parsePeripheral(p: any, defaults: { accessType: AccessType, size: number, resetValue: number }): PeripheralNode {
389-
let totalLength = 0
390+
let totalLength = 0;
390391
if (p.addressBlock) {
391392
for (const ab of p.addressBlock) {
392393
const offset = parseInteger(ab.offset[0]);

src/frontend/views/nodes/basenode.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Command, TreeItem } from 'vscode';
22
import { NumberFormat, NodeSetting } from '../../../common';
3-
import { AddressRangesInUse } from '../../addrranges';
3+
import { AddressRangesInUse, AddrRange } from '../../addrranges';
44

55
export abstract class BaseNode {
66
public expanded: boolean;
@@ -45,6 +45,7 @@ export abstract class PeripheralBaseNode extends BaseNode {
4545
public abstract getPeripheral(): PeripheralBaseNode;
4646

4747
public abstract markAddresses(a: AddressRangesInUse): void;
48+
public abstract collectRanges(ary: AddrRange[]): void; // Append addr range(s) to array
4849

4950
public abstract saveState(path?: string): NodeSetting[];
5051
public abstract findByPath(path: string[]): PeripheralBaseNode;

src/frontend/views/nodes/messagenode.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { PeripheralBaseNode, BaseNode } from './basenode';
22
import { TreeItem, TreeItemCollapsibleState } from 'vscode';
3-
import { AddressRangesInUse } from '../../addrranges';
3+
import { AddressRangesInUse, AddrRange } from '../../addrranges';
44
import { NodeSetting } from '../../../common';
55

66
export class MessageNode extends PeripheralBaseNode {
@@ -38,6 +38,9 @@ export class MessageNode extends PeripheralBaseNode {
3838
public markAddresses(a: AddressRangesInUse): void {
3939
}
4040

41+
public collectRanges(ary: AddrRange[]): void {
42+
}
43+
4144
public saveState(path?: string): NodeSetting[] {
4245
return [];
4346
}

src/frontend/views/nodes/peripheralclusternode.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { AccessType } from '../../svd';
44
import { PeripheralRegisterNode } from './peripheralregisternode';
55
import { PeripheralNode } from './peripheralnode';
66
import { NodeSetting, NumberFormat } from '../../../common';
7-
import { AddressRangesInUse } from '../../addrranges';
7+
import { AddressRangesInUse, AddrRange } from '../../addrranges';
88
import { hexFormat } from '../../utils';
99

1010
export interface ClusterOptions {
@@ -116,6 +116,10 @@ export class PeripheralClusterNode extends PeripheralBaseNode {
116116
this.children.map((r) => { r.markAddresses(addrs); });
117117
}
118118

119+
public collectRanges(ary: AddrRange[]): void {
120+
this.children.map((r) => { r.collectRanges(ary); });
121+
}
122+
119123
public getPeripheral(): PeripheralBaseNode {
120124
return this.parent.getPeripheral();
121125
}

src/frontend/views/nodes/peripheralfieldnode.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { TreeItem, TreeItemCollapsibleState, window, debug, MarkdownString, Tree
22
import { PeripheralBaseNode } from './basenode';
33
import { AccessType } from '../../svd';
44
import { PeripheralRegisterNode } from './peripheralregisternode';
5-
import { AddressRangesInUse } from '../../addrranges';
5+
import { AddressRangesInUse, AddrRange } from '../../addrranges';
66
import { NumberFormat, NodeSetting } from '../../../common';
77
import { parseInteger, binaryFormat, hexFormat } from '../../utils';
88

@@ -85,11 +85,11 @@ export class PeripheralFieldNode extends PeripheralBaseNode {
8585
const displayValue = this.getFormattedValue(this.getFormat());
8686
const labelItem: TreeItemLabel = {
8787
label: label + ' ' + displayValue
88-
}
88+
};
8989
if (displayValue !== this.prevValue) {
9090
labelItem.highlights = [[label.length + 1, labelItem.label.length]];
9191
this.prevValue = displayValue;
92-
}
92+
}
9393
const item = new TreeItem(labelItem, TreeItemCollapsibleState.None);
9494

9595
item.contextValue = context;
@@ -289,4 +289,8 @@ export class PeripheralFieldNode extends PeripheralBaseNode {
289289
public markAddresses(a: AddressRangesInUse): void {
290290
throw new Error('Method not implemented.');
291291
}
292+
293+
public collectRanges(a: AddrRange[]): void {
294+
throw new Error('Method not implemented.');
295+
}
292296
}

src/frontend/views/nodes/peripheralnode.ts

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ export class PeripheralNode extends PeripheralBaseNode {
149149
return MemReadUtils.readMemoryChunks(this.baseAddress, this.addrRanges, this.currentValue);
150150
}
151151

152-
public markAddresses(): void {
152+
private pvt_markAddresses(): AddrRange[] {
153153
let ranges = [new AddrRange(this.baseAddress, this.totalLength)]; // Default range
154154
const skipAddressGaps = true;
155155

@@ -161,12 +161,61 @@ export class PeripheralNode extends PeripheralBaseNode {
161161
ranges = addresses.getAddressRangesOptimized(this.baseAddress, false, this.gapThreshold);
162162
}
163163

164+
// OpenOCD has an issue where the max number of bytes readable are 8191 (instead of 8192)
165+
// which causes unaligned reads (via gdb) and silent failures. There is patch for this in OpenOCD
166+
// but in general, it is good to split the reads up. see http://openocd.zylin.com/#/c/5109/
167+
// Another benefit, we can minimize gdb timeouts
168+
const maxBytes = (4 * 1024); // Should be a multiple of 4 to be safe for MMIO reads
169+
return AddressRangesInUse.splitIntoChunks(ranges, maxBytes, this.name, this.totalLength);
170+
}
171+
172+
public markAddresses(): void {
173+
this.addrRanges = this.pvt_markAddresses();
174+
}
175+
176+
public collectRanges(): void {
177+
const addresses: AddrRange[] = [];
178+
this.children.map((child) => child.collectRanges(addresses));
179+
addresses.sort((a, b) => (a.base < b.base) ? -1 : ((a.base > b.base) ? 1 : 0));
180+
addresses.map((r) => r.base += this.baseAddress);
181+
182+
const maxGap = this.gapThreshold;
183+
let ranges: AddrRange[] = [];
184+
if (maxGap >= 0) {
185+
let last: AddrRange = null;
186+
for (const r of addresses) {
187+
if (last && ((last.nxtAddr() + maxGap) >= r.base)) {
188+
const max = Math.max(last.nxtAddr(), r.nxtAddr());
189+
last.length = max - last.base;
190+
} else {
191+
ranges.push(r);
192+
last = r;
193+
}
194+
}
195+
} else {
196+
ranges = addresses;
197+
}
198+
164199
// OpenOCD has an issue where the max number of bytes readable are 8191 (instead of 8192)
165200
// which causes unaligned reads (via gdb) and silent failures. There is patch for this in OpenOCD
166201
// but in general, it is good to split the reads up. see http://openocd.zylin.com/#/c/5109/
167202
// Another benefit, we can minimize gdb timeouts
168203
const maxBytes = (4 * 1024); // Should be a multiple of 4 to be safe for MMIO reads
169204
this.addrRanges = AddressRangesInUse.splitIntoChunks(ranges, maxBytes, this.name, this.totalLength);
205+
206+
const verify = true; // TODO: turn this off
207+
if (verify && (maxGap >= 0)) {
208+
const msg = 'PeripheralNode.collectRanges: address-range verification failed. Please report this problem to Cortex-Debug repo';
209+
const golden = this.pvt_markAddresses();
210+
if (this.addrRanges.length !== golden.length) {
211+
throw new Error('1. ' + msg);
212+
}
213+
this.addrRanges.map((r, ix) => {
214+
if ((r.base !== golden[ix].base) || (r.length !== golden[ix].length)) {
215+
throw new Error('2. ' + msg);
216+
}
217+
});
218+
}
170219
}
171220

172221
public getPeripheralNode(): PeripheralNode {

src/frontend/views/nodes/peripheralregisternode.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { PeripheralFieldNode } from './peripheralfieldnode';
66
import { AccessType } from '../../svd';
77
import { extractBits, createMask, hexFormat, binaryFormat } from '../../utils';
88
import { NumberFormat, NodeSetting } from '../../../common';
9-
import { AddressRangesInUse } from '../../addrranges';
9+
import { AddressRangesInUse, AddrRange } from '../../addrranges';
1010

1111
export interface PeripheralRegisterOptions {
1212
name: string;
@@ -85,7 +85,7 @@ export class PeripheralRegisterNode extends PeripheralBaseNode {
8585
const displayValue = this.getFormattedValue(this.getFormat());
8686
const labelItem: TreeItemLabel = {
8787
label: label + ' ' + displayValue
88-
}
88+
};
8989
if (displayValue !== this.prevValue) {
9090
labelItem.highlights = [[label.length + 1, labelItem.label.length]];
9191
this.prevValue = displayValue;
@@ -305,4 +305,8 @@ export class PeripheralRegisterNode extends PeripheralBaseNode {
305305
const finalOffset = this.parent.getOffset(this.offset);
306306
addrs.setAddrRange(finalOffset, this.size / 8);
307307
}
308+
public collectRanges(addrs: AddrRange[]): void {
309+
const finalOffset = this.parent.getOffset(this.offset);
310+
addrs.push(new AddrRange(finalOffset, this.size / 8));
311+
}
308312
}

0 commit comments

Comments
 (0)