X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fflash%2Fflash.c;h=fecb89b72d3d23c749c341bf3c0fc40b0bea92eb;hp=736d3fca12484243e5831e5f0a85645448d293a3;hb=53d1f9b2ca5718e4996e9cf3406f857d0ed26df2;hpb=a582e9a8d183c56d1aa8ae18afc1c11e2cbd6d2d diff --git a/src/flash/flash.c b/src/flash/flash.c index 736d3fca12..fecb89b72d 100644 --- a/src/flash/flash.c +++ b/src/flash/flash.c @@ -34,6 +34,9 @@ #include #include +#include +#include + /* command handlers */ int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int handle_flash_banks_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); @@ -471,6 +474,10 @@ int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, c command_print(cmd_ctx, "unknown error"); } } + else + { + command_print(cmd_ctx, "%s protection for sectors %i through %i on flash bank %i", (set) ? "set" : "cleared", first, last, strtoul(args[0], 0, 0)); + } } else { @@ -482,24 +489,33 @@ int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, c int handle_flash_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { - FILE *binary; u32 offset; - struct stat binary_stat; - u32 binary_size; u8 *buffer; u32 buf_cnt; + u32 image_size; + int i; + + image_t image; + + duration_t duration; + char *duration_text; + int retval; flash_bank_t *p; - struct timeval start, end, duration; - gettimeofday(&start, NULL); - if (argc < 3) { - command_print(cmd_ctx, "usage: flash write "); + command_print(cmd_ctx, "usage: flash write [type]"); return ERROR_OK; } + duration_start_measure(&duration); + + image.base_address_set = 1; + image.base_address = strtoul(args[1], NULL, 0); + + image.start_address_set = 0; + offset = strtoul(args[2], NULL, 0); p = get_flash_bank_by_num(strtoul(args[0], NULL, 0)); if (!p) @@ -508,77 +524,69 @@ int handle_flash_write_command(struct command_context_s *cmd_ctx, char *cmd, cha return ERROR_OK; } - if (stat(args[1], &binary_stat) == -1) + if (image_open(&image, args[1], (argc == 4) ? args[3] : NULL) != ERROR_OK) { - ERROR("couldn't stat() %s: %s", args[1], strerror(errno)); + command_print(cmd_ctx, "flash write error: %s", image.error_str); return ERROR_OK; } - - if (S_ISDIR(binary_stat.st_mode)) - { - ERROR("%s is a directory", args[1]); - command_print(cmd_ctx,"%s is a directory", args[1]); - return ERROR_OK; - } - - if (binary_stat.st_size == 0){ - ERROR("Empty file %s", args[1]); - command_print(cmd_ctx,"Empty file %s", args[1]); - return ERROR_OK; - } - - if (!(binary = fopen(args[1], "rb"))) - { - ERROR("couldn't open %s: %s", args[1], strerror(errno)); - command_print(cmd_ctx, "couldn't open %s", args[1]); - return ERROR_OK; - } - - binary_size = binary_stat.st_size; - buffer = malloc(binary_size); - buf_cnt = fread(buffer, 1, binary_size, binary); - - if ((retval = p->driver->write(p, buffer, offset, buf_cnt)) != ERROR_OK) + + image_size = 0x0; + for (i = 0; i < image.num_sections; i++) { - command_print(cmd_ctx, "failed writing file %s to flash bank %i at offset 0x%8.8x", - args[1], strtoul(args[0], NULL, 0), strtoul(args[2], NULL, 0)); - switch (retval) + buffer = malloc(image.sections[i].size); + if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK) { - case ERROR_TARGET_NOT_HALTED: - command_print(cmd_ctx, "can't work with this flash while target is running"); - break; - case ERROR_INVALID_ARGUMENTS: - command_print(cmd_ctx, "usage: flash write "); - break; - case ERROR_FLASH_BANK_INVALID: - command_print(cmd_ctx, "no '%s' flash found at 0x%8.8x", p->driver->name, p->base); - break; - case ERROR_FLASH_OPERATION_FAILED: - command_print(cmd_ctx, "flash program error"); - break; - case ERROR_FLASH_DST_BREAKS_ALIGNMENT: - command_print(cmd_ctx, "offset breaks required alignment"); - break; - case ERROR_FLASH_DST_OUT_OF_BANK: - command_print(cmd_ctx, "destination is out of flash bank (offset and/or file too large)"); - break; - case ERROR_FLASH_SECTOR_NOT_ERASED: - command_print(cmd_ctx, "destination sector(s) not erased"); - break; - default: - command_print(cmd_ctx, "unknown error"); + ERROR("image_read_section failed with error code: %i", retval); + command_print(cmd_ctx, "image reading failed, flash write aborted"); + free(buffer); + image_close(&image); + return ERROR_OK; } - } - else - { - gettimeofday(&end, NULL); - timeval_subtract(&duration, &end, &start); - command_print(cmd_ctx, "wrote file %s to flash bank %i at offset 0x%8.8x in %is %ius", args[1], strtoul(args[0], NULL, 0), strtoul(args[2], NULL, 0), duration.tv_sec, duration.tv_usec); + if ((retval = p->driver->write(p, buffer, offset, buf_cnt)) != ERROR_OK) + { + command_print(cmd_ctx, "failed writing file %s to flash bank %i at offset 0x%8.8x", + args[1], strtoul(args[0], NULL, 0), strtoul(args[2], NULL, 0)); + switch (retval) + { + case ERROR_TARGET_NOT_HALTED: + command_print(cmd_ctx, "can't work with this flash while target is running"); + break; + case ERROR_INVALID_ARGUMENTS: + command_print(cmd_ctx, "usage: flash write "); + break; + case ERROR_FLASH_BANK_INVALID: + command_print(cmd_ctx, "no '%s' flash found at 0x%8.8x", p->driver->name, p->base); + break; + case ERROR_FLASH_OPERATION_FAILED: + command_print(cmd_ctx, "flash program error"); + break; + case ERROR_FLASH_DST_BREAKS_ALIGNMENT: + command_print(cmd_ctx, "offset breaks required alignment"); + break; + case ERROR_FLASH_DST_OUT_OF_BANK: + command_print(cmd_ctx, "destination is out of flash bank (offset and/or file too large)"); + break; + case ERROR_FLASH_SECTOR_NOT_ERASED: + command_print(cmd_ctx, "destination sector(s) not erased"); + break; + default: + command_print(cmd_ctx, "unknown error"); + } + } + image_size += buf_cnt; + + free(buffer); } + - free(buffer); - fclose(binary); + duration_stop_measure(&duration, &duration_text); + command_print(cmd_ctx, "wrote %u byte from file %s to flash bank %i at offset 0x%8.8x in %s (%f kb/s)", + image_size, args[1], strtoul(args[0], NULL, 0), offset, duration_text, + (float)image_size / 1024.0 / ((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0))); + free(duration_text); + + image_close(&image); return ERROR_OK; }