X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Ftarget.c;h=16caea5fc9a04c37a38106bf0c7b7905de185ea3;hp=d6efe5b24ed22325c47b623048be9b1728648ca2;hb=8f779cf66bf459616b7dad88e871c2f4a7315371;hpb=8b82171f75df84c1eb51e4824852079cb601df80 diff --git a/src/target/target.c b/src/target/target.c index d6efe5b24e..16caea5fc9 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -96,6 +96,7 @@ static struct target_type *target_types[] = struct target *all_targets = NULL; static struct target_event_callback *target_event_callbacks = NULL; static struct target_timer_callback *target_timer_callbacks = NULL; +static const int polling_interval = 100; static const Jim_Nvp nvp_assert[] = { { .name = "assert", NVP_ASSERT }, @@ -862,7 +863,7 @@ static int target_init(struct command_context *cmd_ctx) return retval; retval = target_register_timer_callback(&handle_target, - 100, 1, cmd_ctx->interp); + polling_interval, 1, cmd_ctx->interp); if (ERROR_OK != retval) return retval; @@ -1800,6 +1801,9 @@ static int sense_handler(void) return ERROR_OK; } +static int backoff_times = 0; +static int backoff_count = 0; + /* process target state changes */ static int handle_target(void *priv) { @@ -1862,6 +1866,14 @@ static int handle_target(void *priv) recursive = 0; } + if (backoff_times > backoff_count) + { + /* do not poll this time as we failed previously */ + backoff_count++; + return ERROR_OK; + } + backoff_count = 0; + /* Poll targets for state changes unless that's globally disabled. * Skip targets that are currently disabled. */ @@ -1878,17 +1890,26 @@ static int handle_target(void *priv) /* polling may fail silently until the target has been examined */ if ((retval = target_poll(target)) != ERROR_OK) { - /* FIX!!!!! If we add a LOG_INFO() here to output a line in GDB - * *why* we are aborting GDB, then we'll spam telnet when the - * poll is failing persistently. - * - * If we could implement an event that detected the - * target going from non-pollable to pollable, we could issue - * an error only upon the transition. + /* 100ms polling interval. Increase interval between polling up to 5000ms */ + if (backoff_times * polling_interval < 5000) + { + backoff_times *= 2; + backoff_times++; + } + LOG_USER("Polling target failed, GDB will be halted. Polling again in %dms", backoff_times * polling_interval); + + /* Tell GDB to halt the debugger. This allows the user to + * run monitor commands to handle the situation. */ target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT); return retval; } + /* Since we succeeded, we reset backoff count */ + if (backoff_times > 0) + { + LOG_USER("Polling succeeded again"); + } + backoff_times = 0; } } @@ -2703,7 +2724,12 @@ static COMMAND_HELPER(handle_verify_image_command_internal, int verify) if (verify) { /* calculate checksum of image */ - image_calculate_checksum(buffer, buf_cnt, &checksum); + retval = image_calculate_checksum(buffer, buf_cnt, &checksum); + if (retval != ERROR_OK) + { + free(buffer); + break; + } retval = target_checksum_memory(target, image.sections[i].base_address, buf_cnt, &mem_checksum); if (retval != ERROR_OK) @@ -2769,6 +2795,10 @@ static COMMAND_HELPER(handle_verify_image_command_internal, int verify) free(buffer); image_size += buf_cnt; } + if (diffs > 0) + { + command_print(CMD_CTX, "No more differences found."); + } done: if (diffs > 0) { @@ -4021,23 +4051,36 @@ static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv) Jim_GetOptInfo goi; Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); - /* danger! goi.argc will be modified below! */ - argc = goi.argc; - - if ((argc != 1) && (argc != 2)) + if ((goi.argc < 1) || (goi.argc > 3)) { Jim_SetResult_sprintf(goi.interp, - "usage: %s
[]", cmd_name); + "usage: %s [phys]
[]", cmd_name); return JIM_ERR; } + int (*fn)(struct target *target, + uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer); + fn=target_read_memory; + + int e; + if (strcmp(Jim_GetString(argv[1], NULL), "phys") == 0) + { + /* consume it */ + struct Jim_Obj *obj; + e = Jim_GetOpt_Obj(&goi, &obj); + if (e != JIM_OK) + return e; + + fn=target_read_phys_memory; + } + jim_wide a; - int e = Jim_GetOpt_Wide(&goi, &a); + e = Jim_GetOpt_Wide(&goi, &a); if (e != JIM_OK) { return JIM_ERR; } jim_wide c; - if (argc == 2) { + if (goi.argc == 1) { e = Jim_GetOpt_Wide(&goi, &c); if (e != JIM_OK) { return JIM_ERR; @@ -4045,6 +4088,13 @@ static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } else { c = 1; } + + /* all args must be consumed */ + if (goi.argc != 0) + { + return JIM_ERR; + } + jim_wide b = 1; /* shut up gcc */ if (strcasecmp(cmd_name, "mdw") == 0) b = 4; @@ -4068,7 +4118,7 @@ static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv) if (y > 16) { y = 16; } - e = target_read_memory(target, a, b, y / b, target_buf); + e = fn(target, a, b, y / b, target_buf); if (e != ERROR_OK) { Jim_SetResult_sprintf(interp, "error reading target @ 0x%08lx", (int)(a)); return JIM_ERR; @@ -5246,7 +5296,7 @@ static const struct command_registration target_exec_command_handlers[] = { .usage = "filename [offset [type]]", }, { - .name = "ocd_mem2array", + .name = "mem2array", .mode = COMMAND_EXEC, .jim_handler = jim_mem2array, .help = "read 8/16/32 bit memory and return as a TCL array " @@ -5254,7 +5304,7 @@ static const struct command_registration target_exec_command_handlers[] = { .usage = "arrayname bitwidth address count", }, { - .name = "ocd_array2mem", + .name = "array2mem", .mode = COMMAND_EXEC, .jim_handler = jim_array2mem, .help = "convert a TCL array to memory locations "