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

@@ -107,7 +107,7 @@ the full walkthrough (probe → proxy → flash) lives in
| Category | Commands |
|----------|----------|
| Script control | `set`, `print`, `print_env_var`, `if`, `goto`, `call`, `return`, `rand`, `init_array`, `system`, `pause` |
| Probe / chain | `jtag_probes`, `jtag_open`, `jtag_scan`, `jtag_autoinit`, `jtag_ndev`, `jtag_devices` |
| Probe / chain | `jtag_probes`, `jtag_open`, `jtag_close`, `jtag_scan`, `jtag_autoinit`, `jtag_ndev`, `jtag_devices` |
| BSDL / pins | `jtag_bsdl`, `jtag_pins`, `jtag_mode`, `jtag_pin_dir`, `jtag_pin_set`, `jtag_pin_get`, `jtag_push_pop` |
| I²C / MDIO / SPI over BS pins (EXTEST) | `jtag_i2c_scl`, `jtag_i2c_sda`, `jtag_i2c_rd`, `jtag_i2c_wr`, `jtag_mdio_mdc`, `jtag_mdio_io`, `jtag_mdio_rd`, `jtag_mdio_wr`, `jtag_spi_cs/mosi/miso/clk`, `jtag_spi_xfer` |
| FPGA registry | `fpga_list`, `fpga_info` |

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},