From: Andreas Fritiofson Date: Fri, 15 Jul 2011 20:18:39 +0000 (+0200) Subject: target: add async algorithm entries to the target type X-Git-Tag: v0.6.0-rc1~554 X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=commitdiff_plain;h=3f6ef7a40bcff5e1278b662248902c45a1dc8f81 target: add async algorithm entries to the target type On supported targets, this may be used to start a long running algorithm in the background so the target may be interacted with during execution and later wait for its completion. The most obvious use case is a double buffered flash algorithm that can upload the next block of data while the algorithm is flashing the current. Signed-off-by: Andreas Fritiofson --- diff --git a/src/target/target.c b/src/target/target.c index be9742f5c2..6a60b4ea47 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -732,6 +732,81 @@ done: return retval; } +/** + * Downloads a target-specific native code algorithm to the target, + * executes and leaves it running. + * + * @param target used to run the algorithm + * @param arch_info target-specific description of the algorithm. + */ +int target_start_algorithm(struct target *target, + int num_mem_params, struct mem_param *mem_params, + int num_reg_params, struct reg_param *reg_params, + uint32_t entry_point, uint32_t exit_point, + void *arch_info) +{ + int retval = ERROR_FAIL; + + if (!target_was_examined(target)) + { + LOG_ERROR("Target not examined yet"); + goto done; + } + if (!target->type->start_algorithm) { + LOG_ERROR("Target type '%s' does not support %s", + target_type_name(target), __func__); + goto done; + } + if (target->running_alg) { + LOG_ERROR("Target is already running an algorithm"); + goto done; + } + + target->running_alg = true; + retval = target->type->start_algorithm(target, + num_mem_params, mem_params, + num_reg_params, reg_params, + entry_point, exit_point, arch_info); + +done: + return retval; +} + +/** + * Waits for an algorithm started with target_start_algorithm() to complete. + * + * @param target used to run the algorithm + * @param arch_info target-specific description of the algorithm. + */ +int target_wait_algorithm(struct target *target, + int num_mem_params, struct mem_param *mem_params, + int num_reg_params, struct reg_param *reg_params, + uint32_t exit_point, int timeout_ms, + void *arch_info) +{ + int retval = ERROR_FAIL; + + if (!target->type->wait_algorithm) { + LOG_ERROR("Target type '%s' does not support %s", + target_type_name(target), __func__); + goto done; + } + if (!target->running_alg) { + LOG_ERROR("Target is not running an algorithm"); + goto done; + } + + retval = target->type->wait_algorithm(target, + num_mem_params, mem_params, + num_reg_params, reg_params, + exit_point, timeout_ms, arch_info); + if (retval != ERROR_TARGET_TIMEOUT) + target->running_alg = false; + +done: + return retval; +} + int target_read_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) diff --git a/src/target/target.h b/src/target/target.h index 5248d69ede..12726bd71b 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -431,6 +431,28 @@ int target_run_algorithm(struct target *target, uint32_t entry_point, uint32_t exit_point, int timeout_ms, void *arch_info); +/** + * Starts an algorithm in the background on the @a target given. + * + * This routine is a wrapper for target->type->start_algorithm. + */ +int target_start_algorithm(struct target *target, + int num_mem_params, struct mem_param *mem_params, + int num_reg_params, struct reg_param *reg_params, + uint32_t entry_point, uint32_t exit_point, + void *arch_info); + +/** + * Wait for an algorithm on the @a target given. + * + * This routine is a wrapper for target->type->wait_algorithm. + */ +int target_wait_algorithm(struct target *target, + int num_mem_params, struct mem_param *mem_params, + int num_reg_params, struct reg_param *reg_params, + uint32_t exit_point, int timeout_ms, + void *arch_info); + /** * Read @a count items of @a size bytes from the memory of @a target at * the @a address given. diff --git a/src/target/target_type.h b/src/target/target_type.h index fc062dabd6..10b6f33aa1 100644 --- a/src/target/target_type.h +++ b/src/target/target_type.h @@ -171,6 +171,8 @@ struct target_type * use target_run_algorithm() instead. */ int (*run_algorithm)(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, uint32_t entry_point, uint32_t exit_point, int timeout_ms, void *arch_info); + int (*start_algorithm)(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, uint32_t entry_point, uint32_t exit_point, void *arch_info); + int (*wait_algorithm)(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, uint32_t exit_point, int timeout_ms, void *arch_info); const struct command_registration *commands;