X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fflash%2Fflash.c;h=a8da5565c15e21a1beee8023d70713e557bfaba8;hp=329ade6364d0cb39378d4e2ba6baaceea5bcbc7d;hb=dfecfd5fd471708ac15af08b52964e8f8da9f4be;hpb=fb50efc6e712f413d109c3d77683d0358a557ed4 diff --git a/src/flash/flash.c b/src/flash/flash.c index 329ade6364..a8da5565c1 100644 --- a/src/flash/flash.c +++ b/src/flash/flash.c @@ -31,42 +31,30 @@ #include "image.h" #include "time_support.h" -/* command handlers */ -static int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -static int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -static int handle_flash_probe_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -static int handle_flash_erase_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -static int handle_flash_erase_address_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -static int handle_flash_protect_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -static int handle_flash_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -static int handle_flash_write_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -static int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -static int handle_flash_fill_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -static int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -static int flash_write_unlock(target_t *target, image_t *image, uint32_t *written, int erase, bool unlock); +static int flash_write_unlock(target_t *target, struct image *image, uint32_t *written, int erase, bool unlock); /* flash drivers */ -extern flash_driver_t lpc2000_flash; -extern flash_driver_t lpc288x_flash; -extern flash_driver_t lpc2900_flash; -extern flash_driver_t cfi_flash; -extern flash_driver_t at91sam3_flash; -extern flash_driver_t at91sam7_flash; -extern flash_driver_t str7x_flash; -extern flash_driver_t str9x_flash; -extern flash_driver_t aduc702x_flash; -extern flash_driver_t stellaris_flash; -extern flash_driver_t str9xpec_flash; -extern flash_driver_t stm32x_flash; -extern flash_driver_t tms470_flash; -extern flash_driver_t ecosflash_flash; -extern flash_driver_t ocl_flash; -extern flash_driver_t pic32mx_flash; -extern flash_driver_t avr_flash; -extern flash_driver_t faux_flash; - -flash_driver_t *flash_drivers[] = { +extern struct flash_driver lpc2000_flash; +extern struct flash_driver lpc288x_flash; +extern struct flash_driver lpc2900_flash; +extern struct flash_driver cfi_flash; +extern struct flash_driver at91sam3_flash; +extern struct flash_driver at91sam7_flash; +extern struct flash_driver str7x_flash; +extern struct flash_driver str9x_flash; +extern struct flash_driver aduc702x_flash; +extern struct flash_driver stellaris_flash; +extern struct flash_driver str9xpec_flash; +extern struct flash_driver stm32x_flash; +extern struct flash_driver tms470_flash; +extern struct flash_driver ecosflash_flash; +extern struct flash_driver ocl_flash; +extern struct flash_driver pic32mx_flash; +extern struct flash_driver avr_flash; +extern struct flash_driver faux_flash; + +struct flash_driver *flash_drivers[] = { &lpc2000_flash, &lpc288x_flash, &lpc2900_flash, @@ -132,14 +120,6 @@ int flash_driver_protect(struct flash_bank_s *bank, int set, int first, int last return retval; } -int flash_register_commands(struct command_context_s *cmd_ctx) -{ - flash_cmd = register_command(cmd_ctx, NULL, "flash", NULL, COMMAND_ANY, NULL); - - register_command(cmd_ctx, flash_cmd, "bank", handle_flash_bank_command, COMMAND_CONFIG, "flash bank [driver_options ...]"); - return ERROR_OK; -} - static int jim_flash_banks(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { flash_bank_t *p; @@ -173,43 +153,6 @@ static int jim_flash_banks(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return JIM_OK; } -int flash_init_drivers(struct command_context_s *cmd_ctx) -{ - register_jim(cmd_ctx, "ocd_flash_banks", jim_flash_banks, "return information about the flash banks"); - - if (!flash_banks) - return ERROR_OK; - - register_command(cmd_ctx, flash_cmd, "info", handle_flash_info_command, COMMAND_EXEC, - "print info about flash bank "); - register_command(cmd_ctx, flash_cmd, "probe", handle_flash_probe_command, COMMAND_EXEC, - "identify flash bank "); - register_command(cmd_ctx, flash_cmd, "erase_check", handle_flash_erase_check_command, COMMAND_EXEC, - "check erase state of sectors in flash bank "); - register_command(cmd_ctx, flash_cmd, "protect_check", handle_flash_protect_check_command, COMMAND_EXEC, - "check protection state of sectors in flash bank "); - register_command(cmd_ctx, flash_cmd, "erase_sector", handle_flash_erase_command, COMMAND_EXEC, - "erase sectors at "); - register_command(cmd_ctx, flash_cmd, "erase_address", handle_flash_erase_address_command, COMMAND_EXEC, - "erase address range
"); - - register_command(cmd_ctx, flash_cmd, "fillw", handle_flash_fill_command, COMMAND_EXEC, - "fill with pattern (no autoerase)
"); - register_command(cmd_ctx, flash_cmd, "fillh", handle_flash_fill_command, COMMAND_EXEC, - "fill with pattern
"); - register_command(cmd_ctx, flash_cmd, "fillb", handle_flash_fill_command, COMMAND_EXEC, - "fill with pattern
"); - - register_command(cmd_ctx, flash_cmd, "write_bank", handle_flash_write_bank_command, COMMAND_EXEC, - "write binary data to "); - register_command(cmd_ctx, flash_cmd, "write_image", handle_flash_write_image_command, COMMAND_EXEC, - "write_image [erase] [unlock] [offset] [type]"); - register_command(cmd_ctx, flash_cmd, "protect", handle_flash_protect_command, COMMAND_EXEC, - "set protection of sectors at "); - - return ERROR_OK; -} - flash_bank_t *get_flash_bank_by_num_noprobe(int num) { flash_bank_t *p; @@ -256,7 +199,7 @@ flash_bank_t *get_flash_bank_by_num(int num) } int flash_command_get_bank_by_num( - struct command_context_s *cmd_ctx, char *str, flash_bank_t **bank) + struct command_context_s *cmd_ctx, const char *str, flash_bank_t **bank) { unsigned bank_num; COMMAND_PARSE_NUMBER(uint, str, bank_num); @@ -272,7 +215,7 @@ int flash_command_get_bank_by_num( } -static int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_flash_bank_command) { int retval; int i; @@ -316,7 +259,8 @@ static int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cm c->sectors = NULL; c->next = NULL; - if ((retval = flash_drivers[i]->flash_bank_command(cmd_ctx, cmd, args, argc, c)) != ERROR_OK) + retval = CALL_COMMAND_HANDLER(flash_drivers[i]->flash_bank_command, c); + if (ERROR_OK != retval) { LOG_ERROR("'%s' driver rejected flash bank at 0x%8.8" PRIx32 , args[0], c->base); free(c); @@ -352,7 +296,7 @@ static int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cm return ERROR_OK; } -static int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_flash_info_command) { flash_bank_t *p; uint32_t i = 0; @@ -414,7 +358,7 @@ static int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cm return ERROR_OK; } -static int handle_flash_probe_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_flash_probe_command) { int retval; @@ -451,7 +395,7 @@ static int handle_flash_probe_command(struct command_context_s *cmd_ctx, char *c return ERROR_OK; } -static int handle_flash_erase_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_flash_erase_check_command) { if (argc != 1) { @@ -497,14 +441,12 @@ static int handle_flash_erase_check_command(struct command_context_s *cmd_ctx, c return ERROR_OK; } -static int handle_flash_erase_address_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_flash_erase_address_command) { flash_bank_t *p; int retval; int address; int length; - duration_t duration; - char *duration_text; target_t *target = get_current_target(cmd_ctx); @@ -528,22 +470,22 @@ static int handle_flash_erase_address_command(struct command_context_s *cmd_ctx, /* We can't know if we did a resume + halt, in which case we no longer know the erased state */ flash_set_dirty(); - duration_start_measure(&duration); + struct duration bench; + duration_start(&bench); + + retval = flash_erase_address_range(target, address, length); - if ((retval = flash_erase_address_range(target, address, length)) == ERROR_OK) + if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) { - if ((retval = duration_stop_measure(&duration, &duration_text)) != ERROR_OK) - { - return retval; - } - command_print(cmd_ctx, "erased address 0x%8.8x length %i in %s", address, length, duration_text); - free(duration_text); + command_print(cmd_ctx, "erased address 0x%8.8x (length %i)" + " in %fs (%0.3f kb/s)", address, length, + duration_elapsed(&bench), duration_kbps(&bench, length)); } return retval; } -static int handle_flash_protect_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_flash_protect_check_command) { if (argc != 1) return ERROR_COMMAND_SYNTAX_ERROR; @@ -587,8 +529,7 @@ static int flash_check_sector_parameters(struct command_context_s *cmd_ctx, return ERROR_OK; } -static int handle_flash_erase_command(struct command_context_s *cmd_ctx, - char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_flash_erase_command) { if (argc != 2) return ERROR_COMMAND_SYNTAX_ERROR; @@ -613,26 +554,22 @@ static int handle_flash_erase_command(struct command_context_s *cmd_ctx, first, last, p->num_sectors)) != ERROR_OK) return retval; - duration_t duration; - char *duration_text; - duration_start_measure(&duration); + struct duration bench; + duration_start(&bench); - if ((retval = flash_driver_erase(p, first, last)) == ERROR_OK) { - if ((retval = duration_stop_measure(&duration, - &duration_text)) != ERROR_OK) - return retval; - command_print(cmd_ctx, "erased sectors %i through %i " - "on flash bank %i in %s", - (int) first, (int) last, (int) bank_nr, - duration_text); - free(duration_text); + retval = flash_driver_erase(p, first, last); + + if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) + { + command_print(cmd_ctx, "erased sectors %" PRIu32 " " + "through %" PRIu32" on flash bank %" PRIu32 " " + "in %fs", first, last, bank_nr, duration_elapsed(&bench)); } return ERROR_OK; } -static int handle_flash_protect_command(struct command_context_s *cmd_ctx, - char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_flash_protect_command) { if (argc != 3) return ERROR_COMMAND_SYNTAX_ERROR; @@ -676,17 +613,14 @@ static int handle_flash_protect_command(struct command_context_s *cmd_ctx, return ERROR_OK; } -static int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_flash_write_image_command) { target_t *target = get_current_target(cmd_ctx); - image_t image; + struct image image; uint32_t written; - duration_t duration; - char *duration_text; - - int retval, retvaltemp; + int retval; if (argc < 1) { @@ -728,7 +662,8 @@ static int handle_flash_write_image_command(struct command_context_s *cmd_ctx, c return ERROR_FAIL; } - duration_start_measure(&duration); + struct duration bench; + duration_start(&bench); if (argc >= 2) { @@ -756,31 +691,21 @@ static int handle_flash_write_image_command(struct command_context_s *cmd_ctx, c return retval; } - if ((retvaltemp = duration_stop_measure(&duration, &duration_text)) != ERROR_OK) + if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) { - image_close(&image); - return retvaltemp; + command_print(cmd_ctx, "wrote %" PRIu32 " byte from file %s " + "in %fs (%0.3f kb/s)", written, args[0], + duration_elapsed(&bench), duration_kbps(&bench, written)); } - float speed; - - speed = written / 1024.0; - speed /= ((float)duration.duration.tv_sec - + ((float)duration.duration.tv_usec / 1000000.0)); - command_print(cmd_ctx, - "wrote %" PRIu32 " byte from file %s in %s (%f kb/s)", - written, args[0], duration_text, speed); - - free(duration_text); - image_close(&image); return retval; } -static int handle_flash_fill_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_flash_fill_command) { - int err = ERROR_OK, retval; + int err = ERROR_OK; uint32_t address; uint32_t pattern; uint32_t count; @@ -789,8 +714,6 @@ static int handle_flash_fill_command(struct command_context_s *cmd_ctx, char *cm uint32_t wrote = 0; uint32_t cur_size = 0; uint32_t chunk_count; - char *duration_text; - duration_t duration; target_t *target = get_current_target(cmd_ctx); uint32_t i; uint32_t wordsize; @@ -805,7 +728,7 @@ static int handle_flash_fill_command(struct command_context_s *cmd_ctx, char *cm if (count == 0) return ERROR_OK; - switch (cmd[4]) + switch (CMD_NAME[4]) { case 'w': wordsize = 4; @@ -843,7 +766,8 @@ static int handle_flash_fill_command(struct command_context_s *cmd_ctx, char *cm exit(-1); } - duration_start_measure(&duration); + struct duration bench; + duration_start(&bench); for (wrote = 0; wrote < (count*wordsize); wrote += cur_size) { @@ -872,43 +796,29 @@ static int handle_flash_fill_command(struct command_context_s *cmd_ctx, char *cm return ERROR_FAIL; } } - } - if ((retval = duration_stop_measure(&duration, &duration_text)) != ERROR_OK) + if (duration_measure(&bench) == ERROR_OK) { - return retval; + command_print(cmd_ctx, "wrote %" PRIu32 " bytes to 0x%8.8" PRIx32 + " in %fs (%0.3f kb/s)", wrote, address, + duration_elapsed(&bench), duration_kbps(&bench, wrote)); } - - float speed; - - speed = wrote / 1024.0; - speed /= ((float)duration.duration.tv_sec - + ((float)duration.duration.tv_usec / 1000000.0)); - command_print(cmd_ctx, - "wrote %" PRIu32 " bytes to 0x%8.8" PRIx32 " in %s (%f kb/s)", - wrote, address, duration_text, speed); - - free(duration_text); return ERROR_OK; } -static int handle_flash_write_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_flash_write_bank_command) { uint32_t offset; uint8_t *buffer; uint32_t buf_cnt; - - fileio_t fileio; - - duration_t duration; - char *duration_text; - + struct fileio fileio; if (argc != 3) return ERROR_COMMAND_SYNTAX_ERROR; - duration_start_measure(&duration); + struct duration bench; + duration_start(&bench); flash_bank_t *p; int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &p); @@ -935,24 +845,13 @@ static int handle_flash_write_bank_command(struct command_context_s *cmd_ctx, ch free(buffer); buffer = NULL; - int retvaltemp; - if ((retvaltemp = duration_stop_measure(&duration, &duration_text)) != ERROR_OK) - { - fileio_close(&fileio); - return retvaltemp; - } - if (retval == ERROR_OK) + if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) { - float elapsed = (float)duration.duration.tv_sec; - elapsed += (float)duration.duration.tv_usec / 1000000.0; - float speed = (float)fileio.size / elapsed; - command_print(cmd_ctx, - "wrote %lld byte from file %s to flash bank %u " - "at offset 0x%8.8" PRIx32 " in %s (%f kb/s)", + command_print(cmd_ctx, "wrote %lld byte from file %s to flash bank %u" + " at offset 0x%8.8" PRIx32 " in %fs (%0.3f kb/s)", fileio.size, args[1], p->bank_number, offset, - duration_text, speed / 1024); + duration_elapsed(&bench), duration_kbps(&bench, fileio.size)); } - free(duration_text); fileio_close(&fileio); @@ -1067,7 +966,7 @@ static int flash_unlock_address_range(target_t *target, uint32_t addr, uint32_t /* write (optional verify) an image to flash memory of the given target */ -static int flash_write_unlock(target_t *target, image_t *image, uint32_t *written, int erase, bool unlock) +static int flash_write_unlock(target_t *target, struct image *image, uint32_t *written, int erase, bool unlock) { int retval = ERROR_OK; @@ -1226,7 +1125,7 @@ static int flash_write_unlock(target_t *target, image_t *image, uint32_t *writte return retval; } -int flash_write(target_t *target, image_t *image, uint32_t *written, int erase) +int flash_write(target_t *target, struct image *image, uint32_t *written, int erase) { return flash_write_unlock(target, image, written, erase, false); } @@ -1317,3 +1216,65 @@ int default_flash_blank_check(struct flash_bank_s *bank) return ERROR_OK; } + +int flash_init_drivers(struct command_context_s *cmd_ctx) +{ + register_jim(cmd_ctx, "ocd_flash_banks", + jim_flash_banks, "return information about the flash banks"); + + if (!flash_banks) + return ERROR_OK; + + register_command(cmd_ctx, flash_cmd, "info", + handle_flash_info_command, COMMAND_EXEC, + "print info about flash bank "); + register_command(cmd_ctx, flash_cmd, "probe", + handle_flash_probe_command, COMMAND_EXEC, + "identify flash bank "); + register_command(cmd_ctx, flash_cmd, "erase_check", + handle_flash_erase_check_command, COMMAND_EXEC, + "check erase state of sectors in flash bank "); + register_command(cmd_ctx, flash_cmd, "protect_check", + handle_flash_protect_check_command, COMMAND_EXEC, + "check protection state of sectors in flash bank "); + register_command(cmd_ctx, flash_cmd, "erase_sector", + handle_flash_erase_command, COMMAND_EXEC, + "erase sectors at "); + register_command(cmd_ctx, flash_cmd, "erase_address", + handle_flash_erase_address_command, COMMAND_EXEC, + "erase address range
"); + + register_command(cmd_ctx, flash_cmd, "fillw", + handle_flash_fill_command, COMMAND_EXEC, + "fill with pattern (no autoerase)
"); + register_command(cmd_ctx, flash_cmd, "fillh", + handle_flash_fill_command, COMMAND_EXEC, + "fill with pattern
"); + register_command(cmd_ctx, flash_cmd, "fillb", + handle_flash_fill_command, COMMAND_EXEC, + "fill with pattern
"); + + register_command(cmd_ctx, flash_cmd, "write_bank", + handle_flash_write_bank_command, COMMAND_EXEC, + "write binary data to "); + register_command(cmd_ctx, flash_cmd, "write_image", + handle_flash_write_image_command, COMMAND_EXEC, + "write_image [erase] [unlock] [offset] [type]"); + register_command(cmd_ctx, flash_cmd, "protect", + handle_flash_protect_command, COMMAND_EXEC, + "set protection of sectors at "); + + return ERROR_OK; +} + +int flash_register_commands(struct command_context_s *cmd_ctx) +{ + flash_cmd = register_command(cmd_ctx, NULL, "flash", + NULL, COMMAND_ANY, NULL); + + register_command(cmd_ctx, flash_cmd, "bank", + handle_flash_bank_command, COMMAND_CONFIG, + "flash bank " + " [driver_options ...]"); + return ERROR_OK; +}