From 470c8e8cf14eb0765997413635aa3a84c0ae94c7 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 10 Dec 2019 14:20:31 +0100 Subject: [PATCH] target_flash_erase: Do not crash when requesting erase of unavailable flash. Allow to erase from command line. --- src/platforms/pc/cl_utils.c | 16 +++++++++++++++- src/platforms/pc/cl_utils.h | 1 + src/target/target.c | 4 ++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/platforms/pc/cl_utils.c b/src/platforms/pc/cl_utils.c index 0f4fc04d..2bdac9fc 100644 --- a/src/platforms/pc/cl_utils.c +++ b/src/platforms/pc/cl_utils.c @@ -121,6 +121,7 @@ static void cl_help(char **argv, BMP_CL_OPTIONS_t *opt) printf("\t-n\t\t: Exit immediate if no device found\n"); printf("\tRun mode related options:\n"); printf("\t-t\t\t: Scan SWD, with no target found scan jtag and exit\n"); + printf("\t-E\t\t: Erase flash until flash end or for given size\n"); printf("\t-V\t\t: Verify flash against binary file\n"); printf("\t-r\t\t: Read flash and write to binary file\n"); printf("\t-R\t\t: Reset device\n"); @@ -141,7 +142,7 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv) opt->opt_target_dev = 1; opt->opt_flash_start = 0x08000000; opt->opt_flash_size = 16 * 1024 *1024; - while((c = getopt(argc, argv, "hv::s:c:nN:tVta:S:jrR")) != -1) { + while((c = getopt(argc, argv, "Ehv::s:c:nN:tVta:S:jrR")) != -1) { switch(c) { case 'c': if (optarg) @@ -164,6 +165,9 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv) if (optarg) opt->opt_serial = optarg; break; + case 'E': + opt->opt_mode = BMP_MODE_FLASH_ERASE; + break; case 't': opt->opt_mode = BMP_MODE_TEST; break; @@ -273,6 +277,16 @@ int cl_execute(BMP_CL_OPTIONS_t *opt) map.size = opt->opt_flash_size; if (opt->opt_mode == BMP_MODE_RESET) { target_reset(t); + } else if (opt->opt_mode == BMP_MODE_FLASH_ERASE) { + DEBUG("Erase %zu bytes at 0x%08" PRIx32 "\n", opt->opt_flash_size, + opt->opt_flash_start); + unsigned int erased = target_flash_erase(t, opt->opt_flash_start, + opt->opt_flash_size); + if (erased) { + DEBUG("Erased failed!\n"); + goto free_map; + } + target_reset(t); } else if (opt->opt_mode == BMP_MODE_FLASH_WRITE) { DEBUG("Erase %zu bytes at 0x%08" PRIx32 "\n", map.size, opt->opt_flash_start); diff --git a/src/platforms/pc/cl_utils.h b/src/platforms/pc/cl_utils.h index ede73b8f..cd0c0727 100644 --- a/src/platforms/pc/cl_utils.h +++ b/src/platforms/pc/cl_utils.h @@ -28,6 +28,7 @@ enum bmp_cl_mode { BMP_MODE_DEBUG, BMP_MODE_TEST, BMP_MODE_RESET, + BMP_MODE_FLASH_ERASE, BMP_MODE_FLASH_WRITE, BMP_MODE_FLASH_READ, BMP_MODE_FLASH_VERIFY diff --git a/src/target/target.c b/src/target/target.c index 9ae1e9e0..56e54b0f 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -237,6 +237,10 @@ int target_flash_erase(target *t, target_addr addr, size_t len) int ret = 0; while (len) { struct target_flash *f = flash_for_addr(t, addr); + if (!f) { + DEBUG("Erase stopped at 0x%06" PRIx32 "\n", addr); + return ret; + } size_t tmptarget = MIN(addr + len, f->start + f->length); size_t tmplen = tmptarget - addr; ret |= f->erase(f, addr, tmplen);