fix: auto-detect devicepod uart ports
This commit is contained in:
@@ -1362,7 +1362,7 @@ async function runKeilDownload(profile, payload = {}) {
|
||||
}
|
||||
|
||||
async function runKeilDownloadWithUartCapture(profile, uv4Path, uv4Args, cwd, payload = {}) {
|
||||
const uart = resolveUart(profile, payload['capture-uart'] || payload.captureUart, payload);
|
||||
const uart = await resolveUart(profile, payload['capture-uart'] || payload.captureUart, payload);
|
||||
const captureDurationMs = Number(payload['capture-duration-ms'] || payload.captureDurationMs || payload['duration-ms'] || payload.durationMs || 8000);
|
||||
const timeoutMs = Number(payload.timeoutMs || 300000);
|
||||
const logDir = path.join(stateRoot(profile.__workspaceRoot), 'serial');
|
||||
@@ -1551,12 +1551,56 @@ async function serialPorts() {
|
||||
ok('io-probe.ports', { configured: profile.ioInterface?.uart || [], ports, stderr: result.stderr, exitCode: result.exitCode });
|
||||
}
|
||||
|
||||
function resolveUart(profile, uartId, options = {}) {
|
||||
async function resolveSerialPortNames() {
|
||||
const script = "[System.IO.Ports.SerialPort]::GetPortNames() | Sort-Object | ConvertTo-Json -Compress";
|
||||
const result = await runPowerShell(script, 15000);
|
||||
if (result.exitCode !== 0) return { ports: [], error: shortTail(result.stderr || result.stdout) };
|
||||
const text = result.stdout.trim();
|
||||
if (!text) return { ports: [], error: null };
|
||||
try {
|
||||
const parsed = JSON.parse(text);
|
||||
const ports = (Array.isArray(parsed) ? parsed : [parsed]).map((item) => String(item || '').trim()).filter(Boolean);
|
||||
return { ports, error: null };
|
||||
} catch (error) {
|
||||
return { ports: [], error: `unable to parse serial port list: ${error instanceof Error ? error.message : String(error)}` };
|
||||
}
|
||||
}
|
||||
|
||||
function sameSerialPort(left, right) {
|
||||
return String(left || '').trim().toUpperCase() === String(right || '').trim().toUpperCase();
|
||||
}
|
||||
|
||||
async function resolveUartPort(configuredPort, options = {}) {
|
||||
if (options.port) return { port: String(options.port), source: 'explicit-option', configuredPort: configuredPort || null, availablePorts: null, resolutionWarning: null };
|
||||
const configured = String(configuredPort || '').trim();
|
||||
const discovery = await resolveSerialPortNames();
|
||||
const availablePorts = discovery.ports;
|
||||
if (configured && availablePorts.some((port) => sameSerialPort(port, configured))) {
|
||||
return { port: configured, source: 'profile', configuredPort: configured, availablePorts, resolutionWarning: null };
|
||||
}
|
||||
if (availablePorts.length > 0) {
|
||||
return {
|
||||
port: availablePorts[0],
|
||||
source: configured ? 'host-auto-detected-profile-missing' : 'host-auto-detected',
|
||||
configuredPort: configured || null,
|
||||
availablePorts,
|
||||
resolutionWarning: configured ? `configured UART port ${configured} is not present on this host; using ${availablePorts[0]}` : null,
|
||||
};
|
||||
}
|
||||
return { port: configured, source: configured ? 'profile-unverified' : 'missing', configuredPort: configured || null, availablePorts, resolutionWarning: discovery.error || 'no serial ports detected on this host' };
|
||||
}
|
||||
|
||||
async function resolveUart(profile, uartId, options = {}) {
|
||||
const normalized = String(uartId || 'uart/1').trim().replace(/\\/gu, '/').replace(/\s*\/\s*/gu, '/').replace(/^\/+/, '');
|
||||
const item = (profile.ioInterface?.uart || []).find((entry) => entry.id === normalized);
|
||||
if (!item) throw new Error(`uart profile not found: ${normalized}`);
|
||||
const resolved = { ...item };
|
||||
if (options.port) resolved.port = String(options.port);
|
||||
const portResolution = await resolveUartPort(resolved.port, options);
|
||||
resolved.port = portResolution.port;
|
||||
resolved.resolvedPortSource = portResolution.source;
|
||||
resolved.configuredPort = portResolution.configuredPort;
|
||||
resolved.availablePorts = portResolution.availablePorts;
|
||||
if (portResolution.resolutionWarning) resolved.resolutionWarning = portResolution.resolutionWarning;
|
||||
const baudRate = options['baud-rate'] || options.baudRate;
|
||||
if (baudRate !== undefined) {
|
||||
const parsed = Number(baudRate);
|
||||
@@ -1568,7 +1612,7 @@ function resolveUart(profile, uartId, options = {}) {
|
||||
|
||||
async function serialRead(uartId, options) {
|
||||
const profile = loadProfile();
|
||||
const uart = resolveUart(profile, uartId, options);
|
||||
const uart = await resolveUart(profile, uartId, options);
|
||||
const durationMs = Number(options['duration-ms'] || options.durationMs || 1000);
|
||||
const script = [
|
||||
'$ErrorActionPreference = \'Stop\';',
|
||||
@@ -1593,7 +1637,7 @@ async function serialRead(uartId, options) {
|
||||
|
||||
async function serialReadAfterLaunchFlash(uartId, options) {
|
||||
const profile = loadProfile();
|
||||
const uart = resolveUart(profile, uartId, options);
|
||||
const uart = await resolveUart(profile, uartId, options);
|
||||
const tools = await toolInfo(profile);
|
||||
if (!tools.pyocd.found) throw new Error('pyOCD executable not found');
|
||||
const debug = profile.debugInterface || {};
|
||||
@@ -1660,7 +1704,7 @@ async function serialReadAfterLaunchFlash(uartId, options) {
|
||||
|
||||
async function serialWrite(uartId, options) {
|
||||
const profile = loadProfile();
|
||||
const uart = resolveUart(profile, uartId, options);
|
||||
const uart = await resolveUart(profile, uartId, options);
|
||||
const message = options.hex ? Buffer.from(String(options._[0] || ''), 'hex').toString('binary') : String(options._[0] || '');
|
||||
const encoded = Buffer.from(message, options.hex ? 'binary' : 'utf8').toString('base64');
|
||||
const script = [
|
||||
@@ -1759,7 +1803,7 @@ function serialLineEnding(options) {
|
||||
|
||||
async function serialJsonRpc(uartId, options) {
|
||||
const profile = loadProfile();
|
||||
const uart = resolveUart(profile, uartId, options);
|
||||
const uart = await resolveUart(profile, uartId, options);
|
||||
const request = buildJsonRpcRequest(options);
|
||||
const ending = serialLineEnding(options);
|
||||
const requestText = `${JSON.stringify(request)}${ending.text}`;
|
||||
|
||||
Reference in New Issue
Block a user