diff --git a/.gitignore b/.gitignore
index 4bdda144..c47d0c82 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,7 @@
out
/node_modules
/webview/node_modules
-/binary_modules/*/node_modules
+/binary_modules/**/node_modules
*.vsix
.vscode-test
.DS_Store
diff --git a/.vscodeignore b/.vscodeignore
index b54e6e44..9665623b 100644
--- a/.vscodeignore
+++ b/.vscodeignore
@@ -10,6 +10,6 @@ tsconfig.json
vsc-extension-quickstart.md
webpack.config.js
node_modules
-binary_modules/electron*
+binary_modules
!node_modules/@vscode/webview-ui-toolkit
diff --git a/binary_modules/package-lock.json b/binary_modules/package-lock.json
index 33314022..68b3781c 100644
--- a/binary_modules/package-lock.json
+++ b/binary_modules/package-lock.json
@@ -9,7 +9,8 @@
"version": "1.0.0",
"license": "MIT",
"dependencies": {
- "serialport": "^10.4.0"
+ "serialport": "^10.4.0",
+ "usb": "^2.14.0"
},
"devDependencies": {
"electron-rebuild": "^3.2.8"
@@ -335,6 +336,12 @@
"@types/node": "*"
}
},
+ "node_modules/@types/w3c-web-usb": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/@types/w3c-web-usb/-/w3c-web-usb-1.0.10.tgz",
+ "integrity": "sha512-CHgUI5kTc/QLMP8hODUHhge0D4vx+9UiAwIGiT0sTy/B2XpdX1U5rJt6JSISgr6ikRT7vxV9EVAFeYZqUnl1gQ==",
+ "license": "MIT"
+ },
"node_modules/abbrev": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
@@ -2044,6 +2051,30 @@
"node": ">= 10.0.0"
}
},
+ "node_modules/usb": {
+ "version": "2.14.0",
+ "resolved": "https://registry.npmjs.org/usb/-/usb-2.14.0.tgz",
+ "integrity": "sha512-I3lzVOH21BsO6qPYvx1C7Ji08lbuM0qmsEtNGAphqlhNME5cz/vExY+jIXZl+HQIRybI/sTxdyLab5tALsL69w==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/w3c-web-usb": "^1.0.6",
+ "node-addon-api": "^8.0.0",
+ "node-gyp-build": "^4.5.0"
+ },
+ "engines": {
+ "node": ">=12.22.0 <13.0 || >=14.17.0"
+ }
+ },
+ "node_modules/usb/node_modules/node-addon-api": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.1.0.tgz",
+ "integrity": "sha512-yBY+qqWSv3dWKGODD6OGE6GnTX7Q2r+4+DfpqxHSHh8x0B4EKP9+wVGLS6U/AM1vxSNNmUEuIV5EGhYwPpfOwQ==",
+ "license": "MIT",
+ "engines": {
+ "node": "^18 || ^20 || >= 21"
+ }
+ },
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -2361,6 +2392,11 @@
"@types/node": "*"
}
},
+ "@types/w3c-web-usb": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/@types/w3c-web-usb/-/w3c-web-usb-1.0.10.tgz",
+ "integrity": "sha512-CHgUI5kTc/QLMP8hODUHhge0D4vx+9UiAwIGiT0sTy/B2XpdX1U5rJt6JSISgr6ikRT7vxV9EVAFeYZqUnl1gQ=="
+ },
"abbrev": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
@@ -3637,6 +3673,23 @@
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
"dev": true
},
+ "usb": {
+ "version": "2.14.0",
+ "resolved": "https://registry.npmjs.org/usb/-/usb-2.14.0.tgz",
+ "integrity": "sha512-I3lzVOH21BsO6qPYvx1C7Ji08lbuM0qmsEtNGAphqlhNME5cz/vExY+jIXZl+HQIRybI/sTxdyLab5tALsL69w==",
+ "requires": {
+ "@types/w3c-web-usb": "^1.0.6",
+ "node-addon-api": "^8.0.0",
+ "node-gyp-build": "^4.5.0"
+ },
+ "dependencies": {
+ "node-addon-api": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.1.0.tgz",
+ "integrity": "sha512-yBY+qqWSv3dWKGODD6OGE6GnTX7Q2r+4+DfpqxHSHh8x0B4EKP9+wVGLS6U/AM1vxSNNmUEuIV5EGhYwPpfOwQ=="
+ }
+ }
+ },
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
diff --git a/binary_modules/package.json b/binary_modules/package.json
index cfd83917..e18d1d61 100644
--- a/binary_modules/package.json
+++ b/binary_modules/package.json
@@ -11,6 +11,7 @@
"electron-rebuild": "^3.2.8"
},
"dependencies": {
- "serialport": "^10.4.0"
+ "serialport": "^10.4.0",
+ "usb": "^2.14.0"
}
}
diff --git a/debug_attributes.md b/debug_attributes.md
index 30078505..a3ac46f1 100644
--- a/debug_attributes.md
+++ b/debug_attributes.md
@@ -88,8 +88,8 @@ If the type is marked as `{...}` it means that it is a complex item can have mul
| swoConfig
.enabled | boolean | Both | Enable SWO decoding. |
| swoConfig
.source | string | Both | Source for SWO data. Can either be "probe" to get directly from debug probe, or a serial port device to use a serial port external to the debug probe. |
| swoConfig
.swoFrequency | number | Both | SWO frequency in Hz. |
-| swoConfig
.swoPath | string | Both | Path name when source is "file" or "serial". Typically a /path-name or a serial-port-name |
-| swoConfig
.swoPort | string | Both | When server is "external" && source is "socket", port to connect to. Format [host:]port |
+| swoConfig
.swoPath | string | Both | Path name when source is "file" or "serial", device name regex match when source is "probe" for BMP. Typically a /path-name or a serial-port-name |
+| swoConfig
.swoPort | string | Both | When server is "external" && source is "socket", port to connect to. Format [host:]port. For BMP, specifies the regex match of the USB interface contianing raw SWO data. |
| symbolFiles | object[] | Both | Array of ELF files to load symbols from instead of the executable file. Each item in the array cab be a string or an object. Program information is ignored (see `loadFiles`). Can be an empty list to specify none. If this property does not exist, then the executable is used for symbols |
| targetId | string | number | Both | 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) |
| targetProcessor | number | Both | The processor you want to debug. Zero based integer index. Must be less than 'numberOfProcessors' |
diff --git a/package-lock.json b/package-lock.json
index 6623fdf7..cd1d7919 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -24,9 +24,11 @@
"prebuild-install": "^7.0.1",
"ringbufferjs": "^1.1.0",
"safe-buffer": "^5.2.1",
+ "serialport": "^10.4.0",
"stream-json": "^1.7.3",
"tmp": "^0.2.1",
"universal-analytics": "^0.5.3",
+ "usb": "^2.14.0",
"uuid": "^8.3.2",
"vscode-jsonrpc": "^6.0.0"
},
@@ -259,6 +261,208 @@
"exenv-es6": "^1.1.1"
}
},
+ "node_modules/@serialport/binding-mock": {
+ "version": "10.2.2",
+ "resolved": "https://registry.npmjs.org/@serialport/binding-mock/-/binding-mock-10.2.2.tgz",
+ "integrity": "sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw==",
+ "license": "MIT",
+ "dependencies": {
+ "@serialport/bindings-interface": "^1.2.1",
+ "debug": "^4.3.3"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/@serialport/bindings-cpp": {
+ "version": "10.7.0",
+ "resolved": "https://registry.npmjs.org/@serialport/bindings-cpp/-/bindings-cpp-10.7.0.tgz",
+ "integrity": "sha512-Xx1wA2UCG2loS32hxNvWJI4smCzGKhWqE85//fLRzHoGgE1lSLe3Nk7W40/ebrlGFHWRbQZmeaIF4chb2XLliA==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "@serialport/bindings-interface": "1.2.1",
+ "@serialport/parser-readline": "^10.2.1",
+ "debug": "^4.3.2",
+ "node-addon-api": "^4.3.0",
+ "node-gyp-build": "^4.3.0"
+ },
+ "engines": {
+ "node": ">=12.17.0 <13.0 || >=14.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/serialport/donate"
+ }
+ },
+ "node_modules/@serialport/bindings-cpp/node_modules/@serialport/bindings-interface": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.1.tgz",
+ "integrity": "sha512-63Dyqz2gtryRDDckFusOYqLYhR3Hq/M4sEdbF9i/VsvDb6T+tNVgoAKUZ+FMrXXKnCSu+hYbk+MTc0XQANszxw==",
+ "license": "MIT",
+ "engines": {
+ "node": "^12.22 || ^14.13 || >=16"
+ }
+ },
+ "node_modules/@serialport/bindings-cpp/node_modules/node-addon-api": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
+ "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==",
+ "license": "MIT"
+ },
+ "node_modules/@serialport/bindings-interface": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.2.tgz",
+ "integrity": "sha512-CJaUd5bLvtM9c5dmO9rPBHPXTa9R2UwpkJ0wdh9JCYcbrPWsKz+ErvR0hBLeo7NPeiFdjFO4sonRljiw4d2XiA==",
+ "license": "MIT",
+ "engines": {
+ "node": "^12.22 || ^14.13 || >=16"
+ }
+ },
+ "node_modules/@serialport/parser-byte-length": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-10.3.0.tgz",
+ "integrity": "sha512-pJ/VoFemzKRRNDHLhFfPThwP40QrGaEnm9TtwL7o2GihEPwzBg3T0bN13ew5TpbbUYZdMpUtpm3CGfl6av9rUQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/serialport/donate"
+ }
+ },
+ "node_modules/@serialport/parser-cctalk": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-10.3.0.tgz",
+ "integrity": "sha512-8ujmk8EvVbDPrNF4mM33bWvUYJOZ0wXbY3WCRazHRWvyCdL0VO0DQvW81ZqgoTpiDQZm5r8wQu9rmuemahF6vQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/serialport/donate"
+ }
+ },
+ "node_modules/@serialport/parser-delimiter": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-10.3.0.tgz",
+ "integrity": "sha512-9E4Vj6s0UbbcCCTclwegHGPYjJhdm9qLCS0lowXQDEQC5naZnbsELemMHs93nD9jHPcyx1B4oXkMnVZLxX5TYw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/serialport/donate"
+ }
+ },
+ "node_modules/@serialport/parser-inter-byte-timeout": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-10.3.0.tgz",
+ "integrity": "sha512-wKP0QK85NHgvT6BBB1qBfKBBU4pf8kespNXAZBUYmFT+P4n8r8IZE2mqigCD+AiZcfWNQoAizwOsT/Jx/qeVig==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/serialport/donate"
+ }
+ },
+ "node_modules/@serialport/parser-packet-length": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/parser-packet-length/-/parser-packet-length-10.3.0.tgz",
+ "integrity": "sha512-bj0cWzt8YSQj/E5fRQVYdi4TsfTlZQrXlXrUwjyTsCONv8IPOHzsz+yY0fw5SEMiJtaLyqvPkCHLsttOd/zFsg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/@serialport/parser-readline": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-10.3.0.tgz",
+ "integrity": "sha512-ki3ATZ3/RAqnqGROBKE7k+OeZ0DZXZ53GTca4q71OU5RazbbNhTOBQLKLXD3v9QZXCMJdg4hGW/2Y0DuMUqMQg==",
+ "license": "MIT",
+ "dependencies": {
+ "@serialport/parser-delimiter": "10.3.0"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/serialport/donate"
+ }
+ },
+ "node_modules/@serialport/parser-ready": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-10.3.0.tgz",
+ "integrity": "sha512-1owywJ4p592dJyVrEJZPIh6pUZ3/y/LN6kGTDH2wxdewRUITo/sGvDy0er5i2+dJD3yuowiAz0dOHSdz8tevJA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/serialport/donate"
+ }
+ },
+ "node_modules/@serialport/parser-regex": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-10.3.0.tgz",
+ "integrity": "sha512-tIogTs7CvTH+UUFnsvE7i33MSISyTPTGPWlglWYH2/5coipXY503jlaYS1YGe818wWNcSx6YAjMZRdhTWwM39w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/serialport/donate"
+ }
+ },
+ "node_modules/@serialport/parser-slip-encoder": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/parser-slip-encoder/-/parser-slip-encoder-10.3.0.tgz",
+ "integrity": "sha512-JI0ILF5sylWn8f0MuMzHFBix/iMUTa79/Z95KaPZYnVaEdA7h7hh/o21Jmon/26P3RJwL1SNJCjZ81zfan+LtQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/serialport/donate"
+ }
+ },
+ "node_modules/@serialport/parser-spacepacket": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/parser-spacepacket/-/parser-spacepacket-10.3.0.tgz",
+ "integrity": "sha512-PDF73ClEPsClD1FEJZHNuBevDKsJCkqy/XD5+S5eA6+tY5D4HLrVgSWsg+3qqB6+dlpwf2CzHe+uO8D3teuKHA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/serialport/donate"
+ }
+ },
+ "node_modules/@serialport/stream": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/stream/-/stream-10.3.0.tgz",
+ "integrity": "sha512-7sooi5fHogYNVEJwxVdg872xO6TuMgQd2E9iRmv+o8pk/1dbBnPkmH6Ka3st1mVE+0KnIJqVlgei+ncSsqXIGw==",
+ "license": "MIT",
+ "dependencies": {
+ "@serialport/bindings-interface": "1.2.1",
+ "debug": "^4.3.2"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/serialport/donate"
+ }
+ },
+ "node_modules/@serialport/stream/node_modules/@serialport/bindings-interface": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.1.tgz",
+ "integrity": "sha512-63Dyqz2gtryRDDckFusOYqLYhR3Hq/M4sEdbF9i/VsvDb6T+tNVgoAKUZ+FMrXXKnCSu+hYbk+MTc0XQANszxw==",
+ "license": "MIT",
+ "engines": {
+ "node": "^12.22 || ^14.13 || >=16"
+ }
+ },
"node_modules/@tootallnate/once": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
@@ -327,6 +531,12 @@
"integrity": "sha512-CQcY3+Fe5hNewHnOEAVYj4dd1do/QHliXaknAEYSXx2KEHUzFibDZSKptCon+HPgK55xx20pR+PBJjf0MomnBA==",
"dev": true
},
+ "node_modules/@types/w3c-web-usb": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/@types/w3c-web-usb/-/w3c-web-usb-1.0.10.tgz",
+ "integrity": "sha512-CHgUI5kTc/QLMP8hODUHhge0D4vx+9UiAwIGiT0sTy/B2XpdX1U5rJt6JSISgr6ikRT7vxV9EVAFeYZqUnl1gQ==",
+ "license": "MIT"
+ },
"node_modules/@ungap/promise-all-settled": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
@@ -2458,6 +2668,26 @@
"node": ">=10"
}
},
+ "node_modules/node-addon-api": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.1.0.tgz",
+ "integrity": "sha512-yBY+qqWSv3dWKGODD6OGE6GnTX7Q2r+4+DfpqxHSHh8x0B4EKP9+wVGLS6U/AM1vxSNNmUEuIV5EGhYwPpfOwQ==",
+ "license": "MIT",
+ "engines": {
+ "node": "^18 || ^20 || >= 21"
+ }
+ },
+ "node_modules/node-gyp-build": {
+ "version": "4.8.2",
+ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz",
+ "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==",
+ "license": "MIT",
+ "bin": {
+ "node-gyp-build": "bin.js",
+ "node-gyp-build-optional": "optional.js",
+ "node-gyp-build-test": "build-test.js"
+ }
+ },
"node_modules/node-interval-tree": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/node-interval-tree/-/node-interval-tree-1.3.3.tgz",
@@ -2935,6 +3165,34 @@
"randombytes": "^2.1.0"
}
},
+ "node_modules/serialport": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/serialport/-/serialport-10.4.0.tgz",
+ "integrity": "sha512-PszPM5SnFMgSXom60PkKS2A9nMlNbHkuoyRBlzdSWw9rmgOn258+V0dYbWMrETJMM+TJV32vqBzjg5MmmUMwMw==",
+ "license": "MIT",
+ "dependencies": {
+ "@serialport/binding-mock": "10.2.2",
+ "@serialport/bindings-cpp": "10.7.0",
+ "@serialport/parser-byte-length": "10.3.0",
+ "@serialport/parser-cctalk": "10.3.0",
+ "@serialport/parser-delimiter": "10.3.0",
+ "@serialport/parser-inter-byte-timeout": "10.3.0",
+ "@serialport/parser-packet-length": "10.3.0",
+ "@serialport/parser-readline": "10.3.0",
+ "@serialport/parser-ready": "10.3.0",
+ "@serialport/parser-regex": "10.3.0",
+ "@serialport/parser-slip-encoder": "10.3.0",
+ "@serialport/parser-spacepacket": "10.3.0",
+ "@serialport/stream": "10.3.0",
+ "debug": "^4.3.3"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/serialport/donate"
+ }
+ },
"node_modules/setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
@@ -3550,6 +3808,21 @@
"punycode": "^2.1.0"
}
},
+ "node_modules/usb": {
+ "version": "2.14.0",
+ "resolved": "https://registry.npmjs.org/usb/-/usb-2.14.0.tgz",
+ "integrity": "sha512-I3lzVOH21BsO6qPYvx1C7Ji08lbuM0qmsEtNGAphqlhNME5cz/vExY+jIXZl+HQIRybI/sTxdyLab5tALsL69w==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/w3c-web-usb": "^1.0.6",
+ "node-addon-api": "^8.0.0",
+ "node-gyp-build": "^4.5.0"
+ },
+ "engines": {
+ "node": ">=12.22.0 <13.0 || >=14.17.0"
+ }
+ },
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -4053,6 +4326,113 @@
"exenv-es6": "^1.1.1"
}
},
+ "@serialport/binding-mock": {
+ "version": "10.2.2",
+ "resolved": "https://registry.npmjs.org/@serialport/binding-mock/-/binding-mock-10.2.2.tgz",
+ "integrity": "sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw==",
+ "requires": {
+ "@serialport/bindings-interface": "^1.2.1",
+ "debug": "^4.3.3"
+ }
+ },
+ "@serialport/bindings-cpp": {
+ "version": "10.7.0",
+ "resolved": "https://registry.npmjs.org/@serialport/bindings-cpp/-/bindings-cpp-10.7.0.tgz",
+ "integrity": "sha512-Xx1wA2UCG2loS32hxNvWJI4smCzGKhWqE85//fLRzHoGgE1lSLe3Nk7W40/ebrlGFHWRbQZmeaIF4chb2XLliA==",
+ "requires": {
+ "@serialport/bindings-interface": "1.2.1",
+ "@serialport/parser-readline": "^10.2.1",
+ "debug": "^4.3.2",
+ "node-addon-api": "^4.3.0",
+ "node-gyp-build": "^4.3.0"
+ },
+ "dependencies": {
+ "@serialport/bindings-interface": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.1.tgz",
+ "integrity": "sha512-63Dyqz2gtryRDDckFusOYqLYhR3Hq/M4sEdbF9i/VsvDb6T+tNVgoAKUZ+FMrXXKnCSu+hYbk+MTc0XQANszxw=="
+ },
+ "node-addon-api": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
+ "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ=="
+ }
+ }
+ },
+ "@serialport/bindings-interface": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.2.tgz",
+ "integrity": "sha512-CJaUd5bLvtM9c5dmO9rPBHPXTa9R2UwpkJ0wdh9JCYcbrPWsKz+ErvR0hBLeo7NPeiFdjFO4sonRljiw4d2XiA=="
+ },
+ "@serialport/parser-byte-length": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-10.3.0.tgz",
+ "integrity": "sha512-pJ/VoFemzKRRNDHLhFfPThwP40QrGaEnm9TtwL7o2GihEPwzBg3T0bN13ew5TpbbUYZdMpUtpm3CGfl6av9rUQ=="
+ },
+ "@serialport/parser-cctalk": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-10.3.0.tgz",
+ "integrity": "sha512-8ujmk8EvVbDPrNF4mM33bWvUYJOZ0wXbY3WCRazHRWvyCdL0VO0DQvW81ZqgoTpiDQZm5r8wQu9rmuemahF6vQ=="
+ },
+ "@serialport/parser-delimiter": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-10.3.0.tgz",
+ "integrity": "sha512-9E4Vj6s0UbbcCCTclwegHGPYjJhdm9qLCS0lowXQDEQC5naZnbsELemMHs93nD9jHPcyx1B4oXkMnVZLxX5TYw=="
+ },
+ "@serialport/parser-inter-byte-timeout": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-10.3.0.tgz",
+ "integrity": "sha512-wKP0QK85NHgvT6BBB1qBfKBBU4pf8kespNXAZBUYmFT+P4n8r8IZE2mqigCD+AiZcfWNQoAizwOsT/Jx/qeVig=="
+ },
+ "@serialport/parser-packet-length": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/parser-packet-length/-/parser-packet-length-10.3.0.tgz",
+ "integrity": "sha512-bj0cWzt8YSQj/E5fRQVYdi4TsfTlZQrXlXrUwjyTsCONv8IPOHzsz+yY0fw5SEMiJtaLyqvPkCHLsttOd/zFsg=="
+ },
+ "@serialport/parser-readline": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-10.3.0.tgz",
+ "integrity": "sha512-ki3ATZ3/RAqnqGROBKE7k+OeZ0DZXZ53GTca4q71OU5RazbbNhTOBQLKLXD3v9QZXCMJdg4hGW/2Y0DuMUqMQg==",
+ "requires": {
+ "@serialport/parser-delimiter": "10.3.0"
+ }
+ },
+ "@serialport/parser-ready": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-10.3.0.tgz",
+ "integrity": "sha512-1owywJ4p592dJyVrEJZPIh6pUZ3/y/LN6kGTDH2wxdewRUITo/sGvDy0er5i2+dJD3yuowiAz0dOHSdz8tevJA=="
+ },
+ "@serialport/parser-regex": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-10.3.0.tgz",
+ "integrity": "sha512-tIogTs7CvTH+UUFnsvE7i33MSISyTPTGPWlglWYH2/5coipXY503jlaYS1YGe818wWNcSx6YAjMZRdhTWwM39w=="
+ },
+ "@serialport/parser-slip-encoder": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/parser-slip-encoder/-/parser-slip-encoder-10.3.0.tgz",
+ "integrity": "sha512-JI0ILF5sylWn8f0MuMzHFBix/iMUTa79/Z95KaPZYnVaEdA7h7hh/o21Jmon/26P3RJwL1SNJCjZ81zfan+LtQ=="
+ },
+ "@serialport/parser-spacepacket": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/parser-spacepacket/-/parser-spacepacket-10.3.0.tgz",
+ "integrity": "sha512-PDF73ClEPsClD1FEJZHNuBevDKsJCkqy/XD5+S5eA6+tY5D4HLrVgSWsg+3qqB6+dlpwf2CzHe+uO8D3teuKHA=="
+ },
+ "@serialport/stream": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@serialport/stream/-/stream-10.3.0.tgz",
+ "integrity": "sha512-7sooi5fHogYNVEJwxVdg872xO6TuMgQd2E9iRmv+o8pk/1dbBnPkmH6Ka3st1mVE+0KnIJqVlgei+ncSsqXIGw==",
+ "requires": {
+ "@serialport/bindings-interface": "1.2.1",
+ "debug": "^4.3.2"
+ },
+ "dependencies": {
+ "@serialport/bindings-interface": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.1.tgz",
+ "integrity": "sha512-63Dyqz2gtryRDDckFusOYqLYhR3Hq/M4sEdbF9i/VsvDb6T+tNVgoAKUZ+FMrXXKnCSu+hYbk+MTc0XQANszxw=="
+ }
+ }
+ },
"@tootallnate/once": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
@@ -4118,6 +4498,11 @@
"integrity": "sha512-CQcY3+Fe5hNewHnOEAVYj4dd1do/QHliXaknAEYSXx2KEHUzFibDZSKptCon+HPgK55xx20pR+PBJjf0MomnBA==",
"dev": true
},
+ "@types/w3c-web-usb": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/@types/w3c-web-usb/-/w3c-web-usb-1.0.10.tgz",
+ "integrity": "sha512-CHgUI5kTc/QLMP8hODUHhge0D4vx+9UiAwIGiT0sTy/B2XpdX1U5rJt6JSISgr6ikRT7vxV9EVAFeYZqUnl1gQ=="
+ },
"@ungap/promise-all-settled": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
@@ -5711,6 +6096,16 @@
"semver": "^7.3.5"
}
},
+ "node-addon-api": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.1.0.tgz",
+ "integrity": "sha512-yBY+qqWSv3dWKGODD6OGE6GnTX7Q2r+4+DfpqxHSHh8x0B4EKP9+wVGLS6U/AM1vxSNNmUEuIV5EGhYwPpfOwQ=="
+ },
+ "node-gyp-build": {
+ "version": "4.8.2",
+ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz",
+ "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw=="
+ },
"node-interval-tree": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/node-interval-tree/-/node-interval-tree-1.3.3.tgz",
@@ -6068,6 +6463,27 @@
"randombytes": "^2.1.0"
}
},
+ "serialport": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/serialport/-/serialport-10.4.0.tgz",
+ "integrity": "sha512-PszPM5SnFMgSXom60PkKS2A9nMlNbHkuoyRBlzdSWw9rmgOn258+V0dYbWMrETJMM+TJV32vqBzjg5MmmUMwMw==",
+ "requires": {
+ "@serialport/binding-mock": "10.2.2",
+ "@serialport/bindings-cpp": "10.7.0",
+ "@serialport/parser-byte-length": "10.3.0",
+ "@serialport/parser-cctalk": "10.3.0",
+ "@serialport/parser-delimiter": "10.3.0",
+ "@serialport/parser-inter-byte-timeout": "10.3.0",
+ "@serialport/parser-packet-length": "10.3.0",
+ "@serialport/parser-readline": "10.3.0",
+ "@serialport/parser-ready": "10.3.0",
+ "@serialport/parser-regex": "10.3.0",
+ "@serialport/parser-slip-encoder": "10.3.0",
+ "@serialport/parser-spacepacket": "10.3.0",
+ "@serialport/stream": "10.3.0",
+ "debug": "^4.3.3"
+ }
+ },
"setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
@@ -6506,6 +6922,16 @@
"punycode": "^2.1.0"
}
},
+ "usb": {
+ "version": "2.14.0",
+ "resolved": "https://registry.npmjs.org/usb/-/usb-2.14.0.tgz",
+ "integrity": "sha512-I3lzVOH21BsO6qPYvx1C7Ji08lbuM0qmsEtNGAphqlhNME5cz/vExY+jIXZl+HQIRybI/sTxdyLab5tALsL69w==",
+ "requires": {
+ "@types/w3c-web-usb": "^1.0.6",
+ "node-addon-api": "^8.0.0",
+ "node-gyp-build": "^4.5.0"
+ }
+ },
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
diff --git a/package.json b/package.json
index 11776e1a..074dfc7e 100644
--- a/package.json
+++ b/package.json
@@ -2493,12 +2493,12 @@
"swoPath": {
"type": "string",
"default": "",
- "description": "Path name when source is \"file\" or \"serial\". Typically a /path-name or a serial-port-name"
+ "description": "Path name when source is \"file\" or \"serial\", device name regex match when source is \"probe\" for BMP. Typically a /path-name or a serial-port-name"
},
"swoPort": {
"type": "string",
"default": "",
- "description": "When server is \"external\" && source is \"socket\", port to connect to. Format [host:]port"
+ "description": "When server is \"external\" && source is \"socket\", port to connect to. Format [host:]port. For BMP, specifies the regex match of the USB interface contianing raw SWO data."
},
"decoders": {
"description": "SWO Decoder Configuration",
@@ -3005,9 +3005,11 @@
"prebuild-install": "^7.0.1",
"ringbufferjs": "^1.1.0",
"safe-buffer": "^5.2.1",
+ "serialport": "^10.4.0",
"stream-json": "^1.7.3",
"tmp": "^0.2.1",
"universal-analytics": "^0.5.3",
+ "usb": "^2.14.0",
"uuid": "^8.3.2",
"vscode-jsonrpc": "^6.0.0"
},
@@ -3057,7 +3059,7 @@
"url": "https://github.com/Marus/cortex-debug/issues"
},
"scripts": {
- "vscode:prepublish": "npm run lint && webpack --mode production && node dist/docgen.js",
+ "vscode:prepublish": "npm run lint && webpack --mode production && node dist/docgen.js && npm ci -C binary_modules --omit dev && cp -a binary_modules/node_modules dist/",
"watch": "webpack --mode development --watch",
"compile": "webpack --mode development && node dist/docgen.js",
"test-compile": "tsc -p ./",
diff --git a/src/bmp.ts b/src/bmp.ts
index 6b6bf34a..dfb72f0b 100644
--- a/src/bmp.ts
+++ b/src/bmp.ts
@@ -109,6 +109,10 @@ export class BMPServerController extends EventEmitter implements GDBServerContro
);
commands.push(this.args.swoConfig.profile ? 'EnablePCSample' : 'DisablePCSample');
+
+ if (this.args.swoConfig.source === 'probe') {
+ commands.push('monitor traceswo');
+ }
return commands.map((c) => `interpreter-exec console "${c}"`);
}
@@ -131,13 +135,22 @@ export class BMPServerController extends EventEmitter implements GDBServerContro
public serverLaunchStarted(): void {}
public serverLaunchCompleted(): void {
- if (this.args.swoConfig.enabled && this.args.swoConfig.source !== 'probe') {
- this.emit('event', new SWOConfigureEvent({
- type: 'serial',
- args: this.args,
- device: this.args.swoConfig.source,
- baudRate: this.args.swoConfig.swoFrequency
- }));
+ if (this.args.swoConfig.enabled) {
+ if (this.args.swoConfig.source === 'probe') {
+ this.emit('event', new SWOConfigureEvent({
+ type: 'usb',
+ args: this.args,
+ device: this.args.swoConfig.swoPath || 'Black Magic Probe',
+ port: this.args.swoConfig.swoPort || 'Black Magic Trace Capture'
+ }));
+ } else {
+ this.emit('event', new SWOConfigureEvent({
+ type: 'serial',
+ args: this.args,
+ device: this.args.swoConfig.source,
+ baudRate: this.args.swoConfig.swoFrequency
+ }));
+ }
}
}
diff --git a/src/frontend/configprovider.ts b/src/frontend/configprovider.ts
index 8b359f2a..538c955a 100644
--- a/src/frontend/configprovider.ts
+++ b/src/frontend/configprovider.ts
@@ -622,12 +622,6 @@ export class CortexDebugConfigurationProvider implements vscode.DebugConfigurati
return 'The Black Magic Probe GDB Server does not have support for the rtos option.';
}
- if (config.swoConfig.enabled && config.swoConfig.source === 'probe') {
- vscode.window.showWarningMessage('SWO support is not available from the probe when using the BMP GDB server. Disabling SWO.');
- config.swoConfig = { enabled: false, ports: [], cpuFrequency: 0, swoFrequency: 0 };
- config.graphConfig = [];
- }
-
return null;
}
diff --git a/src/frontend/extension.ts b/src/frontend/extension.ts
index 89212063..f445f917 100644
--- a/src/frontend/extension.ts
+++ b/src/frontend/extension.ts
@@ -16,6 +16,7 @@ import { JLinkSocketRTTSource, SocketRTTSource, SocketSWOSource, PeMicroSocketSo
import { FifoSWOSource } from './swo/sources/fifo';
import { FileSWOSource } from './swo/sources/file';
import { SerialSWOSource } from './swo/sources/serial';
+import { UsbSWOSource } from './swo/sources/usb';
import { SymbolInformation, SymbolScope } from '../symbols';
import { RTTTerminal } from './rtt_terminal';
import { GDBServerConsole } from './server_console';
@@ -760,9 +761,13 @@ export class CortexDebugExtension {
Reporting.sendEvent('SWO', 'Source', 'File');
}
else if (e.body.type === 'serial') {
- mySession.swoSource = new SerialSWOSource(e.body.device, e.body.baudRate, this.context.extensionPath);
+ mySession.swoSource = new SerialSWOSource(e.body.device, e.body.baudRate);
Reporting.sendEvent('SWO', 'Source', 'Serial');
}
+ else if (e.body.type === 'usb') {
+ mySession.swoSource = new UsbSWOSource(e.body.device, e.body.port);
+ Reporting.sendEvent('SWO', 'Source', 'USB');
+ }
this.initializeSWO(e.session, e.body.args);
}
diff --git a/src/frontend/swo/sources/serial.ts b/src/frontend/swo/sources/serial.ts
index 90c2ddd1..7f58a834 100644
--- a/src/frontend/swo/sources/serial.ts
+++ b/src/frontend/swo/sources/serial.ts
@@ -1,82 +1,17 @@
import { SWORTTSource } from './common';
import { EventEmitter } from 'events';
-import * as fs from 'fs';
-import * as os from 'os';
+import type { SerialPort } from 'serialport';
import * as vscode from 'vscode';
-import * as path from 'path';
-
-export function findSerialPortModuleHelp(extensionPath: string) {
- return 'Node/npm module "serialport" not found. You can install this in one of two ways\n' +
- '1. Install "Serial Monitor" VSCode extension. https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-serial-monitor\n' +
- '2. or, you can compile the serialport module locally on your computer. Follow these instructions on a shell prompt\n' +
- ` cd ${extensionPath}/binary_modules\n` +
- ` bash ./build.sh ${process.versions['electron']}\n` +
- 'If you chose to compile locally, make sure NodeJS is installed on your system. Visit https://nodejs.org/en/download/';
-}
-
-export function findSerialPortModule(extensionPath: string, useModule) {
- const paths = [];
- const p = path.normalize(path.join(extensionPath, 'binary_modules', 'electron-' + process.versions['electron'], 'node_modules'));
- if (fs.existsSync(p) && fs.existsSync(path.join(p, 'serialport'))) {
- paths.push(p);
- } else {
- const serMonitorExt = 'ms-vscode.vscode-serial-monitor';
- const serialMonitor: vscode.Extension = vscode.extensions.getExtension(serMonitorExt);
- if (serialMonitor) {
- paths.push(path.join(serialMonitor.extensionPath, 'dist', 'node_modules'));
- paths.push(path.join(serialMonitor.extensionPath, 'node_modules'));
- }
- }
-
- let added = false;
- for (const p of paths) {
- if (fs.existsSync(path.join(p, 'serialport'))) {
- if (useModule.paths.indexOf(p) === -1) {
- console.log(`Adding ${p} to module search path`);
- useModule.paths.push(p);
- }
- added = true;
- }
- }
- return added;
-}
-
-declare function __webpack_require__(name: string): any;
-declare function __non_webpack_require__(name: string): any;
export class SerialSWOSource extends EventEmitter implements SWORTTSource {
- private serialPort: any = null;
+ private serialPort: SerialPort = null;
public connected: boolean = false;
- constructor(private device: string, private baudRate: number, extensionPath: string) {
+ constructor(private device: string, private baudRate: number) {
super();
- /* While this is a bit ugly - it works around WebPack's mangling of the require statements. eval('require.main') gets us
- the main module in a non-mangled form (instead of the current module - but that is not important for our purposes here)
- and allows us to modify the paths and load in the serial port from there. We have to wrap it in an eval statement to avoid
- webpack mangling */
- // tslint:disable-next-line: no-eval
- const mainModule = eval('require.main');
- const added = findSerialPortModule(extensionPath, mainModule);
- if (!added) {
- vscode.window.showErrorMessage(findSerialPortModuleHelp(extensionPath));
- return;
- }
-
- let SerialPort;
- try {
- SerialPort = mainModule.require('serialport').SerialPort;
- if (!SerialPort) {
- vscode.window.showErrorMessage(findSerialPortModuleHelp(extensionPath));
- return;
- }
- }
- catch (e) {
- vscode.window.showErrorMessage(findSerialPortModuleHelp(extensionPath));
- return;
- }
-
- this.serialPort = new SerialPort(device, { baudRate: baudRate, autoOpen: false });
+ const { SerialPort } = require('serialport');
+ this.serialPort = new SerialPort({ path: device, baudRate: baudRate, autoOpen: false });
this.serialPort.on('data', (buffer) => {
this.emit('data', buffer);
});
diff --git a/src/frontend/swo/sources/usb.ts b/src/frontend/swo/sources/usb.ts
new file mode 100644
index 00000000..e94ba867
--- /dev/null
+++ b/src/frontend/swo/sources/usb.ts
@@ -0,0 +1,158 @@
+import { EventEmitter } from 'stream';
+import { SWORTTSource } from './common';
+import { promisify } from 'util';
+import * as vscode from 'vscode';
+import * as usb from 'usb';
+
+/*
+ * NOTE: using legacy node-usb interface, because the modern
+ * WebUSB-compatible version doesn't contain a way to interrupt pending
+ * transfer, leading to problems with getting rid of the connection
+ */
+
+export class UsbSWOSource extends EventEmitter implements SWORTTSource {
+ private dev?: usb.Device;
+ private iface?: usb.Interface;
+ private ep?: usb.InEndpoint;
+
+ constructor(
+ private readonly device: string,
+ private readonly port: string
+ ) {
+ super();
+
+ this.start();
+ }
+
+ private async findDevice(): Promise<
+ | {
+ dev: usb.Device;
+ config: usb.ConfigDescriptor;
+ iface: usb.InterfaceDescriptor;
+ endpoint: usb.EndpointDescriptor;
+ productName: string
+ }
+ | undefined
+ > {
+ console.info('Looking for USB devices matching', this.device);
+ const devs = usb.getDeviceList();
+ for (const dev of devs) {
+ dev.open();
+ const { deviceDescriptor: dd } = dev;
+ const getStringDescriptor: (index: number) => Promise =
+ promisify(dev.getStringDescriptor).bind(dev);
+ const productName = await getStringDescriptor(dd.iProduct);
+ if (productName.match(this.device)) {
+ console.info(
+ 'Found device',
+ productName,
+ 'VID',
+ dd.idVendor.toString(16),
+ 'PID',
+ dd.idProduct.toString(16),
+ 'Serial',
+ await getStringDescriptor(dd.iSerialNumber)
+ );
+
+ for (const cfg of dev.allConfigDescriptors) {
+ for (const iface of cfg.interfaces) {
+ for (const alt of iface) {
+ const interfaceName = await getStringDescriptor(alt.iInterface);
+ if (interfaceName?.match(this.port)) {
+ for (const ep of alt.endpoints) {
+ if ((ep.bmAttributes & 3) === usb.usb.LIBUSB_TRANSFER_TYPE_BULK &&
+ ep.bEndpointAddress & usb.usb.LIBUSB_ENDPOINT_IN) {
+ console.info(
+ 'Matched config',
+ cfg.bConfigurationValue,
+ 'interface',
+ alt.bInterfaceNumber,
+ 'alternate',
+ alt.bAlternateSetting,
+ 'endpoint',
+ ep.bEndpointAddress
+ );
+ return {
+ dev,
+ config: cfg,
+ iface: alt,
+ endpoint: ep,
+ productName
+ };
+ }
+ }
+ }
+ }
+ }
+ }
+
+ console.warn('Couldn\'t match interface named', this.port);
+ }
+ dev.close();
+ }
+ console.warn('Matching device not found');
+ return undefined;
+ }
+
+ public async start() {
+ const { dev, config, iface, endpoint, productName } = (await this.findDevice()) ?? {};
+ if (!dev) {
+ vscode.window.showErrorMessage(
+ `Couldn't find a device matching '${this.device}' with interface '${this.port}`
+ );
+ return;
+ }
+
+ console.debug('Connecting to', productName);
+ await dev.open();
+ this.dev = dev;
+ console.debug('Selecting configuration', config.bConfigurationValue);
+ await promisify(dev.setConfiguration).bind(dev)(config.bConfigurationValue);
+ console.debug('Claiming interface', iface.bInterfaceNumber);
+ this.iface = dev.interface(iface.bInterfaceNumber);
+ this.iface.claim();
+ if (iface.bAlternateSetting) {
+ console.debug('Selecting alternate', iface.bAlternateSetting);
+ await dev.interface(iface.iInterface).setAltSettingAsync(iface.bAlternateSetting);
+ }
+ console.debug('Reading from endpoint', endpoint.bEndpointAddress);
+
+ this.ep = this.iface.endpoint(endpoint.bEndpointAddress) as usb.InEndpoint;
+ this.ep.on('data', (buffer: Buffer) => {
+ console.debug(buffer.length, 'bytes received');
+ this.emit('data', buffer);
+ });
+ this.ep.on('error', (error) => {
+ console.error('Unexpected polling error', error);
+ });
+ this.ep.startPoll();
+
+ this.emit('connected');
+ }
+
+ public get connected() {
+ return !!this.ep;
+ }
+
+ public async dispose() {
+ if (this.ep) {
+ console.debug('Stopping polling...');
+ await promisify(this.ep.stopPoll).bind(this.ep)();
+ this.ep = undefined;
+ console.debug('Polling stopped');
+ }
+ if (this.iface) {
+ console.debug('Releasing interface...');
+ await this.iface.releaseAsync();
+ this.iface = undefined;
+ console.debug('Interface released');
+ }
+ if (this.dev) {
+ console.debug('Closing device...');
+ this.dev.close();
+ this.dev = undefined;
+ console.debug('Device closed');
+ }
+ this.emit('disconnected');
+ }
+}
diff --git a/test/suite/serialport.test.ts b/test/suite/serialport.test.ts
index af5f8342..b750934c 100644
--- a/test/suite/serialport.test.ts
+++ b/test/suite/serialport.test.ts
@@ -1,17 +1,6 @@
import * as assert from 'assert';
-import * as vscode from 'vscode';
-import { findSerialPortModule, findSerialPortModuleHelp } from '../../src/frontend/swo/sources/serial';
suite('Serial Port tests', () => {
- const extensionPath = vscode.extensions.getExtension('marus25.cortex-debug').extensionPath;
- const added = findSerialPortModule(extensionPath, module);
- // console.log(findSerialPortModuleHelp(extensionPath));
- test('Serial Port exists', async () => {
- if (!added) {
- console.log(findSerialPortModuleHelp(extensionPath));
- assert.fail('Could not find serialport module');
- }
- });
test('Serial Port list', async () => {
let SerialPort;
try {
diff --git a/webpack.config.js b/webpack.config.js
index 3cba17b5..e62f4867 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -25,7 +25,8 @@ const extensionConfig = {
devtool: 'source-map',
externals: {
vscode: 'vscode',
- serialport: 'serialport'
+ serialport: 'serialport',
+ usb: 'usb'
},
resolve: {
extensions: ['.ts', '.js']
@@ -57,7 +58,8 @@ const adapterConfig = {
devtool: 'source-map',
externals: {
vscode: 'vscode',
- serialport: 'serialport'
+ serialport: 'serialport',
+ usb: 'usb',
},
resolve: {
extensions: ['.ts', '.js']