script: add jtag_close to release the current probe

Lets a session hand a probe back (frees its USB handle) without opening
another, e.g. to flash two FPGAs on different probes in turn:
jtag_close, then jtag_open the next one and jtag_autoinit. Mirrors the
DeInit teardown jtagcore_loaddriver already does when switching drivers.

Also fix the help printer: no-arg commands (whose params slot is "")
printed an empty body because "" was treated as the terminator. Params
are now optional and the description always shows.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-24 10:48:01 +02:00
parent 70091cc4d3
commit 00320d87ec
2 changed files with 46 additions and 11 deletions

View File

@@ -1157,18 +1157,19 @@ static int cmd_help(script_ctx *ctx, char *line)
not_found = 0;
ctx->script_printf(ctx, MSG_NONE, "Documentation of command '%s' :\n", cmdlist[i].command);
ctx->script_printf(ctx, MSG_NONE, "---------------------------------------------------\n");
j = 0;
while (strcmp(cmdlist[i].help[j], "")) {
if (j == 0) {
ctx->script_printf(ctx, MSG_NONE, "Parameters :\n");
ctx->script_printf(ctx, MSG_NONE, " %s\n", cmdlist[i].help[j]);
} else {
if (j == 1) {
ctx->script_printf(ctx, MSG_NONE, "Description :\n");
}
// help[0] is the parameter list ("" when the command takes
// none); description lines follow, terminated by "".
if (cmdlist[i].help[0][0]) {
ctx->script_printf(ctx, MSG_NONE, "Parameters :\n");
ctx->script_printf(ctx, MSG_NONE, " %s\n", cmdlist[i].help[0]);
}
j = 1;
if (strcmp(cmdlist[i].help[j], "")) {
ctx->script_printf(ctx, MSG_NONE, "Description :\n");
while (strcmp(cmdlist[i].help[j], "")) {
ctx->script_printf(ctx, MSG_NONE, " %s\n", cmdlist[i].help[j]);
j++;
}
j++;
}
break;
}
@@ -1855,6 +1856,39 @@ static int cmd_open_probe(script_ctx *ctx, char *line)
}
}
const char *cmd_close_probe_help[] = {
"", // Arguments "1<arg>(type) ..."
"Release the currently open probe, freeing its USB handle.",
"Use it to hand the probe to another tool, or before driving a",
"second target on a different probe: jtag_close, then jtag_open the",
"other one and jtag_autoinit to rescan. (Opening another probe also",
"releases the current one, so jtag_close is only needed to fully let",
"go without immediately reopening.)",
""
};
static int cmd_close_probe(script_ctx *ctx, char *line)
{
jtag_core *jc;
(void)line;
jc = (jtag_core *)ctx->app_ctx;
if (jc->io_functions.drv_DeInit)
{
// Same teardown jtagcore_loaddriver does before switching drivers:
// call the driver's DeInit, then forget its function table so the
// chain looks probe-less until the next jtag_open.
jc->io_functions.drv_DeInit(jc);
memset(&jc->io_functions, 0, sizeof(jc->io_functions));
ctx->script_printf(ctx, MSG_INFO_0, "Probe released.\n");
}
else
{
ctx->script_printf(ctx, MSG_INFO_0, "No probe is open.\n");
}
return JTAG_CORE_NO_ERROR;
}
const char *cmd_load_bsdl_help[] = {
"<file>(string) <device>(int)",
"Load/attach a bsdl file to a device into the chain.",
@@ -3333,6 +3367,7 @@ cmd_list script_commands_list[] =
{"init_array", cmd_initarray, cmd_initarray_help},
{"jtag_probes", cmd_print_probes_list, cmd_print_probes_list_help},
{"jtag_open", cmd_open_probe, cmd_open_probe_help},
{"jtag_close", cmd_close_probe, cmd_close_probe_help},
{"jtag_autoinit", cmd_autoinit, cmd_autoinit_help},
{"jtag_scan", cmd_init_and_scan, cmd_init_and_scan_help},
{"jtag_ndev", cmd_print_nb_dev, cmd_print_nb_dev_help},