-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from cortex-debug/pack-asset-service
Pack asset service
- Loading branch information
Showing
13 changed files
with
552 additions
and
107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/** | ||
* Copyright (C) 2023 Arm Limited | ||
*/ | ||
|
||
import * as vscode from 'vscode'; | ||
|
||
const MAIN_DELIMITER = '::'; | ||
const VERSION_DELIMITER = '@'; | ||
|
||
export interface Pack { | ||
vendor: string; | ||
pack: string; | ||
version?: string; | ||
} | ||
|
||
export const parsePackString = (packString: string): Pack | undefined => { | ||
let parts = packString.split(MAIN_DELIMITER); | ||
|
||
if (parts.length < 2) { | ||
return undefined; | ||
} | ||
|
||
const vendor = parts[0]; | ||
let pack = parts[1]; | ||
|
||
parts = pack.split(VERSION_DELIMITER); | ||
let version: string | undefined; | ||
|
||
if (parts.length > 1) { | ||
pack = parts[0]; | ||
version = parts[1]; | ||
} | ||
|
||
return { | ||
vendor, | ||
pack, | ||
version | ||
}; | ||
}; | ||
|
||
export const pdscFromPack = (basePath: string, pack: Pack): vscode.Uri => { | ||
const pdscFile = `${pack.vendor}.${pack.pack}.pdsc`; | ||
return fileFromPack(basePath, pack, pdscFile); | ||
}; | ||
|
||
export const fileFromPack = (basePath: string, pack: Pack, file: string): vscode.Uri => { | ||
if (!pack.version) { | ||
throw new Error('CMSIS pack version is required'); | ||
} | ||
|
||
const baseUri = vscode.Uri.parse(basePath); | ||
return vscode.Uri.joinPath(baseUri, pack.vendor, pack.pack, pack.version, file); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
/** | ||
* Copyright (C) 2023 Arm Limited | ||
*/ | ||
|
||
/** | ||
* Interface describing raw PDSC data returned from xml2js | ||
*/ | ||
export interface PDSC { | ||
package: { | ||
devices?: Array<{ | ||
family: DeviceFamily[]; | ||
}>; | ||
}; | ||
} | ||
|
||
export interface DeviceProperties { | ||
processor?: Array<{ | ||
$: { | ||
Pname: string; | ||
Punits: string; | ||
Dclock: string; | ||
DcoreVersion: string; | ||
}; | ||
}>; | ||
debug?: Array<{ | ||
$?: { | ||
__dp?: string; | ||
__ap?: string; | ||
__apid?: string; | ||
address?: string; | ||
svd?: string; | ||
Pname?: string; | ||
Punit?: string; | ||
defaultResetSequence?: string; | ||
}; | ||
}>; | ||
} | ||
|
||
export interface DeviceVariant extends DeviceProperties { | ||
$: { | ||
Dvariant: string; | ||
Dname: string; | ||
}; | ||
} | ||
|
||
export interface Device extends DeviceProperties { | ||
$: { | ||
Dname: string; | ||
}; | ||
variant?: DeviceVariant[]; | ||
} | ||
|
||
export interface DeviceSubFamily extends DeviceProperties { | ||
$: { | ||
DsubFamily: string; | ||
}; | ||
device?: Device[]; | ||
} | ||
|
||
export interface DeviceFamily extends DeviceProperties { | ||
$: { | ||
Dfamily: string; | ||
Dvendor: string; | ||
}; | ||
subFamily?: DeviceSubFamily[]; | ||
device?: Device[]; | ||
} | ||
|
||
// Return whether an item is an object | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const isObject = (item: any): boolean => item && typeof item === 'object' && !Array.isArray(item); | ||
|
||
// Merge two objects recursively, with source overwriting target when there's a conflict | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const deepMerge = <T extends { [key: string]: any }>(target: { [key: string]: any }, source: T): T => { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const output = Object.assign({} as any, target); | ||
|
||
Object.keys(source).forEach(key => { | ||
if (isObject(source[key]) && key in target) { | ||
output[key] = deepMerge(target[key], source[key]); | ||
} else { | ||
Object.assign(output, { [key]: source[key] }); | ||
} | ||
}); | ||
|
||
return output; | ||
}; | ||
|
||
// Recurse DeviceFamily and DeviceSubFamily to find Devices and DeviceVariants, merging them as we go | ||
export const getDevices = (pack: PDSC): Array<Device | DeviceVariant> => { | ||
const result: Device[] = []; | ||
|
||
const addDevice = (device: Device, parent: DeviceProperties = {}) => { | ||
const entry = deepMerge(parent, device); | ||
result.push(entry); | ||
}; | ||
|
||
const walkDevices = (devices?: Device[], parent: DeviceProperties = {}) => { | ||
if (devices) { | ||
for (const device of devices) { | ||
if (device.variant) { | ||
// If there are variants, add them instead of the parent device | ||
for (const variant of device.variant) { | ||
// Merge in device | ||
const variantParent = deepMerge(parent, device); | ||
addDevice(variant, variantParent); | ||
} | ||
} else { | ||
addDevice(device, parent); | ||
} | ||
} | ||
} | ||
}; | ||
|
||
// Walk the DeviceFamily array | ||
if (pack.package.devices) { | ||
for (const device of pack.package.devices) { | ||
for (const family of device.family) { | ||
walkDevices(family.device, family); | ||
|
||
// Walk the DeviceSubFamily array | ||
if (family.subFamily) { | ||
for (const sub of family.subFamily) { | ||
const parent = deepMerge(family, sub); | ||
walkDevices(sub.device, parent); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
return result; | ||
}; | ||
|
||
/** | ||
* Return list of processor names available for specified device | ||
*/ | ||
export const getProcessors = (device: Device): string[] => { | ||
const processors: string[] = []; | ||
|
||
if (device.processor) { | ||
for (const processor of device.processor) { | ||
if (processor.$ && processor.$.Pname) { | ||
processors.push(processor.$.Pname); | ||
} | ||
} | ||
} | ||
|
||
return processors; | ||
}; | ||
|
||
/** | ||
* Return svd path (or undefined) for specified device | ||
* If processorName specified, matching svd file is returned, else the first one | ||
*/ | ||
export const getSvdPath = (device: Device, processorName?: string): string | undefined => { | ||
if (device.debug) { | ||
const filtered = filterByProcessor(device.debug, processorName); | ||
for (const debug of filtered) { | ||
if (debug.$ && debug.$.svd) { | ||
return debug.$.svd; | ||
} | ||
} | ||
} | ||
|
||
return undefined; | ||
}; | ||
|
||
const filterByProcessor = <T extends { $?: { Pname?: string } }>(theArray: T[], processorName: string | undefined): T[] => { | ||
// If processorName not specified, return all items | ||
if (!processorName) { | ||
return theArray; | ||
} | ||
|
||
return filter(theArray, item => item.$?.Pname === processorName) as T[]; | ||
}; | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const filter = <T extends { $?: { [key: string]: any } }>(theArray: T[], predicate: (item: T) => boolean): T[] => { | ||
const filtered = theArray.filter(item => item.$ && predicate(item)); | ||
|
||
// If no items match, return them all | ||
return filtered.length > 0 ? filtered as T[] : theArray; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,15 @@ | ||
/* | ||
* Copyright 2017-2019 Marcel Ball | ||
* https://github.com/Marus/cortex-debug | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated | ||
* documentation files (the "Software"), to deal in the Software without restriction, including without | ||
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the | ||
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED | ||
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | ||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
* IN THE SOFTWARE. | ||
/** | ||
* Copyright (C) 2023 Arm Limited | ||
*/ | ||
|
||
export const PACKAGE_NAME = 'svd-viewer'; | ||
export const CONFIG_SVD_PATH = 'svdPathConfig'; | ||
export const DEFAULT_SVD_PATH = 'svdPath'; | ||
export const CONFIG_DEVICE = 'deviceConfig'; | ||
export const DEFAULT_DEVICE = 'device'; | ||
export const DEFAULT_DEVICE = 'deviceName'; | ||
export const CONFIG_PROCESSOR = 'processorConfig'; | ||
export const DEFAULT_PROCESSOR = 'processorName'; | ||
export const CONFIG_ADDRGAP = 'svdAddrGapThreshold'; | ||
export const DEFAULT_ADDRGAP = 16; | ||
export const CONFIG_ASSET_PATH = 'packAssetUrl'; | ||
export const DEFAULT_ASSET_PATH = 'https://pack-asset-service.keil.arm.com'; |
Oops, something went wrong.