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 <andreas.fritiofson@gmail.com>__archive__
parent
e56e5a3929
commit
3f6ef7a40b
|
@ -732,6 +732,81 @@ done:
|
||||||
return retval;
|
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,
|
int target_read_memory(struct target *target,
|
||||||
uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
|
uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
|
||||||
|
|
|
@ -431,6 +431,28 @@ int target_run_algorithm(struct target *target,
|
||||||
uint32_t entry_point, uint32_t exit_point,
|
uint32_t entry_point, uint32_t exit_point,
|
||||||
int timeout_ms, void *arch_info);
|
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
|
* Read @a count items of @a size bytes from the memory of @a target at
|
||||||
* the @a address given.
|
* the @a address given.
|
||||||
|
|
|
@ -171,6 +171,8 @@ struct target_type
|
||||||
* use target_run_algorithm() instead.
|
* 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 (*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;
|
const struct command_registration *commands;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue