Add -defer-examine option to target create command
The '-defer-examine' option to target create allows declaring targets that are present on the chain, but not fully functional. They will be skipped by the initial arp_examine as well as arp_examine after reset. Manual examine using 'arp_examine' is needed to examine them, with the idea that some kind of actions is neeed to bring them to a state where examine will succeed (if at all possible). In order to allow value less options to target command, I had to relax the goi.argc check in jim_target_configure(). Change-Id: I9bf4e8d27eb6476dd9353d15f48965a8cfd5c122 Signed-off-by: Esben Haabendal <esben@haabendal.dk> Signed-off-by: Matthias Welwarsky <matthias.welwarsky@sysgo.com> Reviewed-on: http://openocd.zylin.com/3076 Tested-by: jenkins Reviewed-by: Tomas Vanek <vanekt@fbl.cz>gitignore-build
parent
ab9d92490c
commit
53a936afc0
|
@ -4126,6 +4126,10 @@ The value should normally correspond to a static mapping for the
|
||||||
@option{FreeRTOS}|@option{linux}|@option{ChibiOS}|@option{embKernel}|@option{mqx}
|
@option{FreeRTOS}|@option{linux}|@option{ChibiOS}|@option{embKernel}|@option{mqx}
|
||||||
@xref{gdbrtossupport,,RTOS Support}.
|
@xref{gdbrtossupport,,RTOS Support}.
|
||||||
|
|
||||||
|
@item @code{-defer-examine} -- skip target examination at initial JTAG chain
|
||||||
|
scan and after a reset. A manual call to arp_examine is required to
|
||||||
|
access the target for debugging.
|
||||||
|
|
||||||
@end itemize
|
@end itemize
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@ -4162,7 +4166,7 @@ omap3530.cpu mww 0x5555 123
|
||||||
|
|
||||||
The commands supported by OpenOCD target objects are:
|
The commands supported by OpenOCD target objects are:
|
||||||
|
|
||||||
@deffn Command {$target_name arp_examine}
|
@deffn Command {$target_name arp_examine} @option{allow-defer}
|
||||||
@deffnx Command {$target_name arp_halt}
|
@deffnx Command {$target_name arp_halt}
|
||||||
@deffnx Command {$target_name arp_poll}
|
@deffnx Command {$target_name arp_poll}
|
||||||
@deffnx Command {$target_name arp_reset}
|
@deffnx Command {$target_name arp_reset}
|
||||||
|
|
|
@ -104,6 +104,7 @@ int rtos_create(Jim_GetOptInfo *goi, struct target *target)
|
||||||
int x;
|
int x;
|
||||||
const char *cp;
|
const char *cp;
|
||||||
struct Jim_Obj *res;
|
struct Jim_Obj *res;
|
||||||
|
int e;
|
||||||
|
|
||||||
if (!goi->isconfigure && goi->argc != 0) {
|
if (!goi->isconfigure && goi->argc != 0) {
|
||||||
Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "NO PARAMS");
|
Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "NO PARAMS");
|
||||||
|
@ -112,7 +113,9 @@ int rtos_create(Jim_GetOptInfo *goi, struct target *target)
|
||||||
|
|
||||||
os_free(target);
|
os_free(target);
|
||||||
|
|
||||||
Jim_GetOpt_String(goi, &cp, NULL);
|
e = Jim_GetOpt_String(goi, &cp, NULL);
|
||||||
|
if (e != JIM_OK)
|
||||||
|
return e;
|
||||||
|
|
||||||
if (0 == strcmp(cp, "auto")) {
|
if (0 == strcmp(cp, "auto")) {
|
||||||
/* Auto detect tries to look up all symbols for each RTOS,
|
/* Auto detect tries to look up all symbols for each RTOS,
|
||||||
|
|
|
@ -65,7 +65,7 @@ proc ocd_process_reset_inner { MODE } {
|
||||||
foreach t $targets {
|
foreach t $targets {
|
||||||
if {![using_jtag] || [jtag tapisenabled [$t cget -chain-position]]} {
|
if {![using_jtag] || [jtag tapisenabled [$t cget -chain-position]]} {
|
||||||
$t invoke-event examine-start
|
$t invoke-event examine-start
|
||||||
set err [catch "$t arp_examine"]
|
set err [catch "$t arp_examine allow-defer"]
|
||||||
if { $err == 0 } {
|
if { $err == 0 } {
|
||||||
$t invoke-event examine-end
|
$t invoke-event examine-end
|
||||||
}
|
}
|
||||||
|
@ -111,6 +111,12 @@ proc ocd_process_reset_inner { MODE } {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# don't wait for targets where examination is deferred
|
||||||
|
# they can not be halted anyway at this point
|
||||||
|
if { ![$t was_examined] && [$t examine_deferred] } {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
# Wait upto 1 second for target to halt. Why 1sec? Cause
|
# Wait upto 1 second for target to halt. Why 1sec? Cause
|
||||||
# the JTAG tap reset signal might be hooked to a slow
|
# the JTAG tap reset signal might be hooked to a slow
|
||||||
# resistor/capacitor circuit - and it might take a while
|
# resistor/capacitor circuit - and it might take a while
|
||||||
|
@ -135,6 +141,12 @@ proc ocd_process_reset_inner { MODE } {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# don't wait for targets where examination is deferred
|
||||||
|
# they can not be halted anyway at this point
|
||||||
|
if { ![$t was_examined] && [$t examine_deferred] } {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
set err [catch "$t arp_waitstate halted 5000"]
|
set err [catch "$t arp_waitstate halted 5000"]
|
||||||
# Did it halt?
|
# Did it halt?
|
||||||
if { $err == 0 } {
|
if { $err == 0 } {
|
||||||
|
|
|
@ -283,6 +283,10 @@ const char *target_state_name(struct target *t)
|
||||||
LOG_ERROR("Invalid target state: %d", (int)(t->state));
|
LOG_ERROR("Invalid target state: %d", (int)(t->state));
|
||||||
cp = "(*BUG*unknown*BUG*)";
|
cp = "(*BUG*unknown*BUG*)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!target_was_examined(t) && t->defer_examine)
|
||||||
|
cp = "examine deferred";
|
||||||
|
|
||||||
return cp;
|
return cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -731,6 +735,9 @@ int target_examine(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (target->defer_examine)
|
||||||
|
continue;
|
||||||
|
|
||||||
retval = target_examine_one(target);
|
retval = target_examine_one(target);
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -4325,6 +4332,7 @@ enum target_cfg_param {
|
||||||
TCFG_CHAIN_POSITION,
|
TCFG_CHAIN_POSITION,
|
||||||
TCFG_DBGBASE,
|
TCFG_DBGBASE,
|
||||||
TCFG_RTOS,
|
TCFG_RTOS,
|
||||||
|
TCFG_DEFER_EXAMINE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static Jim_Nvp nvp_config_opts[] = {
|
static Jim_Nvp nvp_config_opts[] = {
|
||||||
|
@ -4339,6 +4347,7 @@ static Jim_Nvp nvp_config_opts[] = {
|
||||||
{ .name = "-chain-position", .value = TCFG_CHAIN_POSITION },
|
{ .name = "-chain-position", .value = TCFG_CHAIN_POSITION },
|
||||||
{ .name = "-dbgbase", .value = TCFG_DBGBASE },
|
{ .name = "-dbgbase", .value = TCFG_DBGBASE },
|
||||||
{ .name = "-rtos", .value = TCFG_RTOS },
|
{ .name = "-rtos", .value = TCFG_RTOS },
|
||||||
|
{ .name = "-defer-examine", .value = TCFG_DEFER_EXAMINE },
|
||||||
{ .name = NULL, .value = -1 }
|
{ .name = NULL, .value = -1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4613,6 +4622,13 @@ no_params:
|
||||||
}
|
}
|
||||||
/* loop for more */
|
/* loop for more */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TCFG_DEFER_EXAMINE:
|
||||||
|
/* DEFER_EXAMINE */
|
||||||
|
target->defer_examine = true;
|
||||||
|
/* loop for more */
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
} /* while (goi->argc) */
|
} /* while (goi->argc) */
|
||||||
|
|
||||||
|
@ -4627,12 +4643,9 @@ static int jim_target_configure(Jim_Interp *interp, int argc, Jim_Obj * const *a
|
||||||
|
|
||||||
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
|
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
|
||||||
goi.isconfigure = !strcmp(Jim_GetString(argv[0], NULL), "configure");
|
goi.isconfigure = !strcmp(Jim_GetString(argv[0], NULL), "configure");
|
||||||
int need_args = 1 + goi.isconfigure;
|
if (goi.argc < 1) {
|
||||||
if (goi.argc < need_args) {
|
|
||||||
Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
|
Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
|
||||||
goi.isconfigure
|
"missing: -option ...");
|
||||||
? "missing: -option VALUE ..."
|
|
||||||
: "missing: -option ...");
|
|
||||||
return JIM_ERR;
|
return JIM_ERR;
|
||||||
}
|
}
|
||||||
struct target *target = Jim_CmdPrivData(goi.interp);
|
struct target *target = Jim_CmdPrivData(goi.interp);
|
||||||
|
@ -4883,20 +4896,58 @@ static int jim_target_tap_disabled(Jim_Interp *interp)
|
||||||
|
|
||||||
static int jim_target_examine(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
static int jim_target_examine(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||||
{
|
{
|
||||||
if (argc != 1) {
|
bool allow_defer = false;
|
||||||
Jim_WrongNumArgs(interp, 1, argv, "[no parameters]");
|
|
||||||
|
Jim_GetOptInfo goi;
|
||||||
|
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
|
||||||
|
if (goi.argc > 1) {
|
||||||
|
const char *cmd_name = Jim_GetString(argv[0], NULL);
|
||||||
|
Jim_SetResultFormatted(goi.interp,
|
||||||
|
"usage: %s ['allow-defer']", cmd_name);
|
||||||
return JIM_ERR;
|
return JIM_ERR;
|
||||||
}
|
}
|
||||||
|
if (goi.argc > 0 &&
|
||||||
|
strcmp(Jim_GetString(argv[1], NULL), "allow-defer") == 0) {
|
||||||
|
/* consume it */
|
||||||
|
struct Jim_Obj *obj;
|
||||||
|
int e = Jim_GetOpt_Obj(&goi, &obj);
|
||||||
|
if (e != JIM_OK)
|
||||||
|
return e;
|
||||||
|
allow_defer = true;
|
||||||
|
}
|
||||||
|
|
||||||
struct target *target = Jim_CmdPrivData(interp);
|
struct target *target = Jim_CmdPrivData(interp);
|
||||||
if (!target->tap->enabled)
|
if (!target->tap->enabled)
|
||||||
return jim_target_tap_disabled(interp);
|
return jim_target_tap_disabled(interp);
|
||||||
|
|
||||||
|
if (allow_defer && target->defer_examine) {
|
||||||
|
LOG_INFO("Deferring arp_examine of %s", target_name(target));
|
||||||
|
LOG_INFO("Use arp_examine command to examine it manually!");
|
||||||
|
return JIM_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int e = target->type->examine(target);
|
int e = target->type->examine(target);
|
||||||
if (e != ERROR_OK)
|
if (e != ERROR_OK)
|
||||||
return JIM_ERR;
|
return JIM_ERR;
|
||||||
return JIM_OK;
|
return JIM_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int jim_target_was_examined(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
|
||||||
|
{
|
||||||
|
struct target *target = Jim_CmdPrivData(interp);
|
||||||
|
|
||||||
|
Jim_SetResultBool(interp, target_was_examined(target));
|
||||||
|
return JIM_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jim_target_examine_deferred(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
|
||||||
|
{
|
||||||
|
struct target *target = Jim_CmdPrivData(interp);
|
||||||
|
|
||||||
|
Jim_SetResultBool(interp, target->defer_examine);
|
||||||
|
return JIM_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static int jim_target_halt_gdb(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
static int jim_target_halt_gdb(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||||
{
|
{
|
||||||
if (argc != 1) {
|
if (argc != 1) {
|
||||||
|
@ -4964,6 +5015,10 @@ static int jim_target_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||||
target_name(target));
|
target_name(target));
|
||||||
return JIM_ERR;
|
return JIM_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (target->defer_examine)
|
||||||
|
target_reset_examined(target);
|
||||||
|
|
||||||
/* determine if we should halt or not. */
|
/* determine if we should halt or not. */
|
||||||
target->reset_halt = !!a;
|
target->reset_halt = !!a;
|
||||||
/* When this happens - all workareas are invalid. */
|
/* When this happens - all workareas are invalid. */
|
||||||
|
@ -5174,6 +5229,21 @@ static const struct command_registration target_instance_command_handlers[] = {
|
||||||
.mode = COMMAND_EXEC,
|
.mode = COMMAND_EXEC,
|
||||||
.jim_handler = jim_target_examine,
|
.jim_handler = jim_target_examine,
|
||||||
.help = "used internally for reset processing",
|
.help = "used internally for reset processing",
|
||||||
|
.usage = "arp_examine ['allow-defer']",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "was_examined",
|
||||||
|
.mode = COMMAND_EXEC,
|
||||||
|
.jim_handler = jim_target_was_examined,
|
||||||
|
.help = "used internally for reset processing",
|
||||||
|
.usage = "was_examined",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "examine_deferred",
|
||||||
|
.mode = COMMAND_EXEC,
|
||||||
|
.jim_handler = jim_target_examine_deferred,
|
||||||
|
.help = "used internally for reset processing",
|
||||||
|
.usage = "examine_deferred",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "arp_halt_gdb",
|
.name = "arp_halt_gdb",
|
||||||
|
|
|
@ -130,6 +130,9 @@ struct target {
|
||||||
struct jtag_tap *tap; /* where on the jtag chain is this */
|
struct jtag_tap *tap; /* where on the jtag chain is this */
|
||||||
int32_t coreid; /* which device on the TAP? */
|
int32_t coreid; /* which device on the TAP? */
|
||||||
|
|
||||||
|
/** Should we defer examine to later */
|
||||||
|
bool defer_examine;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether this target has been examined.
|
* Indicates whether this target has been examined.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue