Skip to content

Commit

Permalink
Extension API Update
Browse files Browse the repository at this point in the history
  • Loading branch information
asimgunes committed Nov 28, 2023
1 parent 4a80637 commit da15dec
Show file tree
Hide file tree
Showing 19 changed files with 281 additions and 96 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,20 @@ Once you have the SVD file, specify the location of it in your `launch.json` usi
}
```

### Extending Peripheral Inspector

It is possible to extend the Peripheral Inspector with new file extension providers in your VSCode extension. This method will provide reading new file formats and load the peripherals information into the Peripheral Inspector.

```json
{
...
"definitionPath": "${workspaceFolder}/STM32F103.<customFileExtension>"
...
}
```

For more details about the implementation, please check the [Extending Peripheral Inspector](./docs/extending-peripheral-inspector.md) document.

## Settings

All variable key names used to extract data from debug launch configurations can be modified. This allows variable name clashes to be avoided as well as the need to duplicate configuration entries.
Expand Down
1 change: 1 addition & 0 deletions api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './src/api-types';
74 changes: 74 additions & 0 deletions docs/extending-peripheral-inspector.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Extending Peripheral Inspector

It is possible to extend the Peripheral Inspector with new file extension providers in your VSCode extension. This method will provide reading new file formats and load the peripherals information into the Peripheral Inspector.

## Building your VSCode Extension to extend Peripheral Inspector

This is a guide about how you can register new peripheral providers to Peripheral Inspector in your VSCode extension. Please refer to [VSCode Extension API](https://code.visualstudio.com/api) for more information about developing VSCode extensions.

### Adding Peripheral Inspector to your VSCode extension

You need to install eclipse-cdt-cloud/vscode-peripheral-inspector to access the types information. You can use `npm` or `yarn` with the following arguments described below:

Using with npm:
```bash
npm install github:eclipse-cdt-cloud/vscode-peripheral-inspector
```
Using with yarn:
```bash
yarn add github:eclipse-cdt-cloud/vscode-peripheral-inspector
```

### Developing your extension

To provide the peripherals information to Peripheral Inspector on debug session time, you need register your command which is going to construct the peripherals information. The command will receive `DebugSession` object as an input parameter and expects to return array of type `PeripheralOptions[]`.

You can find the example command implementation below:

```js
import { ExtensionContext } from 'vscode';
import type * as api from "peripheral-inspector/api";


class MyExtensionProvider implements api.IPeripheralsProvider {
public async getPeripherals (data: string, options: api.IGetPeripheralsArguments): Promise<api.PeripheralOptions[]> {
// Load your peripherals data
const peripherals: api.PeripheralOptions[] = ...
return peripherals;
}
}

export async function activate(context: ExtensionContext) {
...
// Get the eclipse-cdt.peripheral-inspector extension
const peripheralInspectorExtention = extensions.getExtension<api.IPeripheralInspectorAPI>('eclipse-cdt.peripheral-inspector');

// Check if the eclipse-cdt.peripheral-inspector extension is installed
if (peripheralInspectorExtention) {
const peripheralInspectorAPI = await peripheralInspectorExtention.activate();

// Invoke registerPeripheralsProvider method in eclipse-cdt.peripheral-inspector extension api
// Register 'MyExtensionProvider' for files *.myext
peripheralInspectorAPI.registerPeripheralsProvider('myext', new MyExtensionProvider());
}
...
}
```

For further information about the api definitions, review the [Peripheral Inspector API Definitions](../src/api-types.ts).

### Modifying your package.json

In `package.json` of your VSCode extension project, you need to define the dependency between Peripheral Inspector and your extension.

You need to define Peripheral Inspector in the `extensionDependencies` as shown below:

```json
{
...
"extensionDependencies": [
"eclipse-cdt.peripheral-inspector"
],
...
}
```
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"license": "MIT",
"main": "dist/desktop/extension.js",
"browser": "dist/browser/extension.js",
"types": "dist/desktop/extension.d.ts",
"repository": "https://github.com/eclipse-cdt-cloud/vscode-peripheral-inspector",
"qna": "https://github.com/eclipse-cdt-cloud/vscode-peripheral-inspector/issues",
"icon": "media/cdtcloud.png",
Expand Down
83 changes: 83 additions & 0 deletions src/api-types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Peripheral Inspector API
export interface IPeripheralInspectorAPI {
registerSVDFile: (expression: RegExp | string, path: string) => void;
getSVDFile: (device: string) => string | undefined;
getSVDFileFromCortexDebug: (device: string) => Promise<string | undefined>;
registerPeripheralsProvider: (fileExtension: string, provider: IPeripheralsProvider) => void;
}

export interface IPeripheralsProvider {
getPeripherals: (data: string, options: IGetPeripheralsArguments) => Promise<PeripheralOptions[]>;
}

export interface IGetPeripheralsArguments {
gapThreshold: number;
}

export interface PeripheralOptions {
name: string;
baseAddress: number;
totalLength: number;
description: string;
groupName?: string;
accessType?: AccessType;
size?: number;
resetValue?: number;
registers?: PeripheralRegisterOptions[];
clusters?: ClusterOptions[];
}

export interface PeripheralRegisterOptions {
name: string;
description?: string;
addressOffset: number;
accessType?: AccessType;
size?: number;
resetValue?: number;
fields?: FieldOptions[];
}

export interface ClusterOptions {
name: string;
description?: string;
addressOffset: number;
accessType?: AccessType;
size?: number;
resetValue?: number;
registers?: PeripheralRegisterOptions[];
clusters?: ClusterOptions[];
}

export interface FieldOptions {
name: string;
description: string;
offset: number;
width: number;
enumeration?: EnumerationMap;
derivedFrom?: string; // Set this if unresolved
accessType?: AccessType;
}

export interface IGetPeripheralsArguments {
gapThreshold: number;
}

export interface IPeripheralsProvider {
getPeripherals: (data: string, options: IGetPeripheralsArguments) => Promise<PeripheralOptions[]>;
}

export declare enum AccessType {
ReadOnly = 1,
ReadWrite = 2,
WriteOnly = 3
}

export interface EnumerationMap {
[value: number]: IEnumeratedValue;
}

export interface IEnumeratedValue {
name: string;
description: string;
value: number;
}
14 changes: 8 additions & 6 deletions src/browser/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,23 @@ import * as vscode from 'vscode';
import { PeripheralTreeProvider } from '../views/peripheral';
import { Commands } from '../commands';
import { DebugTracker } from '../debug-tracker';
import { SvdRegistry } from '../svd-registry';
import { PeripheralInspectorAPI } from '../peripheral-inspector-api';
import { SvdResolver } from '../svd-resolver';
import { IPeripheralInspectorAPI } from '../api-types';
export * as api from '../api-types';

export const activate = async (context: vscode.ExtensionContext): Promise<SvdRegistry> => {
export const activate = async (context: vscode.ExtensionContext): Promise<IPeripheralInspectorAPI> => {
const tracker = new DebugTracker();
const registry = new SvdRegistry();
const resolver = new SvdResolver(registry);
const peripheralTree = new PeripheralTreeProvider(tracker, resolver, context);
const api = new PeripheralInspectorAPI();
const resolver = new SvdResolver(api);
const peripheralTree = new PeripheralTreeProvider(tracker, resolver, api, context);
const commands = new Commands(peripheralTree);

await tracker.activate(context);
await peripheralTree.activate();
await commands.activate(context);

return registry;
return api;
};

export const deactivate = async (): Promise<void> => {
Expand Down
14 changes: 8 additions & 6 deletions src/desktop/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,23 @@ import * as vscode from 'vscode';
import { PeripheralTreeProvider } from '../views/peripheral';
import { Commands } from '../commands';
import { DebugTracker } from '../debug-tracker';
import { SvdRegistry } from '../svd-registry';
import { PeripheralInspectorAPI } from '../peripheral-inspector-api';
import { SvdResolver } from '../svd-resolver';
import { IPeripheralInspectorAPI } from '../api-types';
export * as api from '../api-types';

export const activate = async (context: vscode.ExtensionContext): Promise<SvdRegistry> => {
export const activate = async (context: vscode.ExtensionContext): Promise<IPeripheralInspectorAPI> => {
const tracker = new DebugTracker();
const registry = new SvdRegistry();
const resolver = new SvdResolver(registry);
const peripheralTree = new PeripheralTreeProvider(tracker, resolver, context);
const api = new PeripheralInspectorAPI();
const resolver = new SvdResolver(api);
const peripheralTree = new PeripheralTreeProvider(tracker, resolver, api, context);
const commands = new Commands(peripheralTree);

await tracker.activate(context);
await peripheralTree.activate();
await commands.activate(context);

return registry;
return api;
};

export const deactivate = async (): Promise<void> => {
Expand Down
3 changes: 3 additions & 0 deletions src/enumerated-value.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export class EnumeratedValue {
constructor(public name: string, public description: string, public value: number) {}
}
2 changes: 1 addition & 1 deletion src/memreadutils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class MemUtils {
storeTo[dst++] = byte;
}
}
} catch (e: unknown) {
} catch (e: any) {

Check warning on line 41 in src/memreadutils.ts

View workflow job for this annotation

GitHub Actions / Build

Unexpected any. Specify a different type
const err = e ? e.toString() : 'Unknown error';
errors.push(new Error(`readMemory failed @ ${memoryReference} for ${request.count} bytes: ${err}, session=${session.id}`));
}
Expand Down
15 changes: 13 additions & 2 deletions src/svd-registry.ts → src/peripheral-inspector-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
********************************************************************************/

import * as vscode from 'vscode';
import { IPeripheralsProvider, IPeripheralInspectorAPI } from './api-types';

const CORTEX_EXTENSION = 'marus25.cortex-debug';

Expand All @@ -14,8 +15,9 @@ interface SVDInfo {
path: string;
}

export class SvdRegistry {
export class PeripheralInspectorAPI implements IPeripheralInspectorAPI {
private SVDDirectory: SVDInfo[] = [];
private PeripheralProviders: Record<string, IPeripheralsProvider> = {};

public registerSVDFile(expression: RegExp | string, path: string): void {
if (typeof expression === 'string') {
Expand All @@ -38,7 +40,7 @@ export class SvdRegistry {
public async getSVDFileFromCortexDebug(device: string): Promise<string | undefined> {
try {
// Try loading from device support pack registered with this extension
const cortexDebug = vscode.extensions.getExtension<SvdRegistry>(CORTEX_EXTENSION);
const cortexDebug = vscode.extensions.getExtension<IPeripheralInspectorAPI>(CORTEX_EXTENSION);
if (cortexDebug) {
const cdbg = await cortexDebug.activate();
if (cdbg) {
Expand All @@ -51,4 +53,13 @@ export class SvdRegistry {

return undefined;
}

public registerPeripheralsProvider(fileExtension: string, provider: IPeripheralsProvider) {
this.PeripheralProviders[fileExtension] = provider;
}

public getPeripheralsProvider(svdPath: string) : IPeripheralsProvider | undefined {
const ext = Object.keys(this.PeripheralProviders).filter((extension) => svdPath.endsWith(`.${extension}`))[0];
return ext ? this.PeripheralProviders[ext] : undefined;
}
}
15 changes: 8 additions & 7 deletions src/svd-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@

import { PeripheralRegisterNode } from './views/nodes/peripheralregisternode';
import { PeripheralClusterNode, PeripheralOrClusterNode } from './views/nodes/peripheralclusternode';
import { PeripheralFieldNode, EnumerationMap, EnumeratedValue } from './views/nodes/peripheralfieldnode';
import { PeripheralFieldNode } from './views/nodes/peripheralfieldnode';
import { PeripheralNode } from './views/nodes/peripheralnode';
import { parseInteger, parseDimIndex } from './utils';
import { parseStringPromise } from 'xml2js';
import { AccessType, EnumerationMap } from './api-types';
import { EnumeratedValue } from './enumerated-value';

export enum AccessType {
ReadOnly = 1,
ReadWrite,
WriteOnly
}

const accessTypeFromString = (type: string): AccessType => {
switch (type) {
Expand Down Expand Up @@ -62,7 +60,8 @@ export class SVDParser {
constructor() {}

public async parseSVD(
svdData: SvdData, gapThreshold: number): Promise<PeripheralNode[]> {
data: string, gapThreshold: number): Promise<PeripheralNode[]> {
const svdData: SvdData = await parseStringPromise(data);
this.gapThreshold = gapThreshold;
this.enumTypeValuesMap = {};
this.peripheralRegisterMap = {};
Expand Down Expand Up @@ -479,3 +478,5 @@ export class SVDParser {
return peripheral;
}
}


8 changes: 4 additions & 4 deletions src/svd-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import * as vscode from 'vscode';
import * as manifest from './manifest';
import { isAbsolute, join, normalize } from 'path';
import { parseStringPromise } from 'xml2js';
import { SvdRegistry } from './svd-registry';
import { PeripheralInspectorAPI } from './peripheral-inspector-api';
import { parsePackString, pdscFromPack, fileFromPack, Pack } from './cmsis-pack/pack-utils';
import { PDSC, Device, DeviceVariant, getDevices, getSvdPath, getProcessors } from './cmsis-pack/pdsc';
import { readFromUrl } from './utils';

export class SvdResolver {
public constructor(protected registry: SvdRegistry) {
public constructor(protected api: PeripheralInspectorAPI) {
}

public async resolve(session: vscode.DebugSession, wsFolderPath?: vscode.Uri): Promise<string | undefined> {
Expand Down Expand Up @@ -45,9 +45,9 @@ export class SvdResolver {
}
}
} else if (deviceName) {
svdPath = this.registry.getSVDFile(deviceName);
svdPath = this.api.getSVDFile(deviceName);
if (!svdPath) {
svdPath = await this.registry.getSVDFileFromCortexDebug(deviceName);
svdPath = await this.api.getSVDFileFromCortexDebug(deviceName);
}
}
} catch(e) {
Expand Down
2 changes: 1 addition & 1 deletion src/views/nodes/basenode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import { Command, TreeItem, DebugSession } from 'vscode';
import { NumberFormat, NodeSetting } from '../../common';
import { AddrRange } from '../../addrranges';
import { EnumerationMap } from './peripheralfieldnode';
import { EnumerationMap } from '../../api-types';

export abstract class BaseNode {
public expanded: boolean;
Expand Down
Loading

0 comments on commit da15dec

Please sign in to comment.