kopia lustrzana https://github.com/stlink-org/stlink
Merge pull request #1397 from hannesweisbach/mass-erase
[feature] --mass-erase for st-flash write commandspull/1406/head
commit
a7fa1ae47c
|
@ -119,6 +119,7 @@ int32_t main(int32_t ac, char** av) {
|
|||
|
||||
sl->verbose = o.log_level;
|
||||
sl->opt = o.opt;
|
||||
const enum erase_type_t erase_type = o.mass_erase ? MASS_ERASE : SECTION_ERASE;
|
||||
|
||||
connected_stlink = sl;
|
||||
signal(SIGINT, &cleanup);
|
||||
|
@ -139,6 +140,14 @@ int32_t main(int32_t ac, char** av) {
|
|||
if (o.cmd == FLASH_CMD_WRITE) {
|
||||
uint32_t size = 0;
|
||||
|
||||
if (erase_type == MASS_ERASE) {
|
||||
err = stlink_erase_flash_mass(sl);
|
||||
if (err == -1) {
|
||||
printf("stlink_erase_flash_mass() == -1\n");
|
||||
goto on_error;
|
||||
}
|
||||
}
|
||||
|
||||
// write
|
||||
if (o.format == FLASH_FORMAT_IHEX) {
|
||||
err = stlink_parse_ihex(o.filename, stlink_get_erased_pattern(sl), &mem, &size, &o.addr);
|
||||
|
@ -150,9 +159,9 @@ int32_t main(int32_t ac, char** av) {
|
|||
}
|
||||
if ((o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) {
|
||||
if (o.format == FLASH_FORMAT_IHEX) {
|
||||
err = stlink_mwrite_flash(sl, mem, size, o.addr);
|
||||
err = stlink_mwrite_flash(sl, mem, size, o.addr, erase_type);
|
||||
} else {
|
||||
err = stlink_fwrite_flash(sl, o.filename, o.addr);
|
||||
err = stlink_fwrite_flash(sl, o.filename, o.addr, erase_type);
|
||||
}
|
||||
|
||||
if (err == -1) {
|
||||
|
@ -207,7 +216,7 @@ int32_t main(int32_t ac, char** av) {
|
|||
printf("OTP Write NOT implemented\n");
|
||||
goto on_error;
|
||||
}
|
||||
err = stlink_fwrite_flash(sl, o.filename, o.addr);
|
||||
err = stlink_fwrite_flash(sl, o.filename, o.addr, NO_ERASE);
|
||||
|
||||
if (err == -1) {
|
||||
printf("stlink_fwrite_flash() == -1\n");
|
||||
|
@ -222,16 +231,21 @@ int32_t main(int32_t ac, char** av) {
|
|||
} else if (o.cmd == FLASH_CMD_ERASE) {
|
||||
|
||||
// erase
|
||||
if (o.size > 0 && o.addr > 0) {
|
||||
err = stlink_erase_flash_section(sl, o.addr, o.size, false);
|
||||
if ((erase_type == MASS_ERASE) || (o.size == 0 || o.addr == 0)) {
|
||||
err = stlink_erase_flash_mass(sl);
|
||||
if (err == -1) {
|
||||
printf("stlink_erase_flash_mass() == -1\n");
|
||||
goto on_error;
|
||||
}
|
||||
printf("Mass erase completed successfully.\n");
|
||||
} else {
|
||||
err = stlink_erase_flash_mass(sl);
|
||||
err = stlink_erase_flash_section(sl, o.addr, o.size, false);
|
||||
if (err == -1) {
|
||||
printf("stlink_erase_flash_section() == -1\n");
|
||||
goto on_error;
|
||||
}
|
||||
printf("Section erase completed successfully.\n");
|
||||
}
|
||||
if (err == -1) {
|
||||
printf("stlink_erase_flash_mass() == -1\n");
|
||||
goto on_error;
|
||||
}
|
||||
printf("Mass erase completed successfully.\n");
|
||||
|
||||
// reset after erase
|
||||
if (stlink_reset(sl, RESET_AUTO)) {
|
||||
|
|
|
@ -104,6 +104,8 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) {
|
|||
o->log_level = DEBUG_LOG_LEVEL;
|
||||
} else if (strcmp(av[0], "--opt") == 0) {
|
||||
o->opt = ENABLE_OPT;
|
||||
} else if (strcmp(av[0], "--mass-erase") == 0) {
|
||||
o->mass_erase = ENABLE_OPT;
|
||||
} else if (strcmp(av[0], "--reset") == 0) {
|
||||
o->reset = 1;
|
||||
} else if (strcmp(av[0], "--serial") == 0 || starts_with(av[0], "--serial=")) {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef FLASH_OPTS_H
|
||||
#define FLASH_OPTS_H
|
||||
|
||||
#define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
|
||||
enum flash_cmd {FLASH_CMD_NONE = 0, FLASH_CMD_WRITE = 1, FLASH_CMD_READ = 2, FLASH_CMD_ERASE = 3, CMD_RESET = 4};
|
||||
enum flash_format {FLASH_FORMAT_BINARY = 0, FLASH_FORMAT_IHEX = 1};
|
||||
|
@ -26,6 +26,7 @@ struct flash_opts {
|
|||
uint32_t val;
|
||||
uint32_t flash_size; // --flash=n[k, M]
|
||||
int32_t opt; // enable empty tail data drop optimization
|
||||
int32_t mass_erase; // Use mass-erase when programming flash instead of sector-erase
|
||||
int32_t freq; // --freq=n[k, M] frequency of JTAG/SWD
|
||||
enum connect_type connect;
|
||||
};
|
||||
|
|
|
@ -593,8 +593,9 @@ static gpointer stlink_gui_write_flash(gpointer data) {
|
|||
g_return_val_if_fail((gui->sl != NULL), NULL);
|
||||
g_return_val_if_fail((gui->filename != NULL), NULL);
|
||||
|
||||
if (stlink_mwrite_flash(
|
||||
gui->sl, gui->file_mem.memory, (uint32_t) gui->file_mem.size, gui->sl->flash_base) < 0) {
|
||||
if (stlink_mwrite_flash(gui->sl, gui->file_mem.memory,
|
||||
(uint32_t) gui->file_mem.size, gui->sl->flash_base,
|
||||
SECTION_ERASE) < 0) {
|
||||
stlink_gui_set_info_error_message(gui, "Failed to write to flash");
|
||||
}
|
||||
|
||||
|
|
|
@ -1281,7 +1281,9 @@ int32_t stlink_erase_flash_mass(stlink_t *sl) {
|
|||
return (err);
|
||||
}
|
||||
|
||||
int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, stm32_addr_t addr) {
|
||||
int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length,
|
||||
stm32_addr_t addr,
|
||||
const enum erase_type_t erase_type) {
|
||||
/* Write the block in flash at addr */
|
||||
int32_t err;
|
||||
uint32_t num_empty, idx;
|
||||
|
@ -1315,7 +1317,7 @@ int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, stm32_
|
|||
*/
|
||||
err = stlink_write_flash(sl, addr, data,
|
||||
(num_empty == length) ? length : length - num_empty,
|
||||
num_empty == length);
|
||||
num_empty == length, erase_type);
|
||||
stlink_fwrite_finalize(sl, addr);
|
||||
return (err);
|
||||
}
|
||||
|
@ -1327,7 +1329,8 @@ int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, stm32_
|
|||
* @param addr where to start writing
|
||||
* @return 0 on success, -ve on failure.
|
||||
*/
|
||||
int32_t stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) {
|
||||
int32_t stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr,
|
||||
const enum erase_type_t erase_type) {
|
||||
/* Write the file in flash at addr */
|
||||
int32_t err;
|
||||
uint32_t num_empty, idx;
|
||||
|
@ -1373,8 +1376,8 @@ int32_t stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) {
|
|||
(num_empty == mf.len) ? (uint32_t) mf.len : (uint32_t) mf.len - num_empty);
|
||||
} else {
|
||||
err = stlink_write_flash(sl, addr, mf.base,
|
||||
(num_empty == mf.len) ? (uint32_t) mf.len : (uint32_t) mf.len - num_empty,
|
||||
num_empty == mf.len);
|
||||
(num_empty == mf.len) ? (uint32_t) mf.len : (uint32_t)mf.len - num_empty,
|
||||
num_empty == mf.len, erase_type);
|
||||
}
|
||||
stlink_fwrite_finalize(sl, addr);
|
||||
unmap_file(&mf);
|
||||
|
@ -1483,7 +1486,9 @@ int32_t stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint8_t eraseonly) {
|
||||
int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base,
|
||||
uint32_t len, uint8_t eraseonly,
|
||||
const enum erase_type_t erase_type) {
|
||||
int32_t ret;
|
||||
flash_loader_t fl;
|
||||
ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, len, addr, addr);
|
||||
|
@ -1509,7 +1514,8 @@ int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint3
|
|||
stlink_core_id(sl);
|
||||
|
||||
// Erase this section of the flash
|
||||
if (stlink_erase_flash_section(sl, addr, len, true) < 0) {
|
||||
if ((erase_type == SECTION_ERASE) &&
|
||||
stlink_erase_flash_section(sl, addr, len, true) < 0) {
|
||||
ELOG("Failed to erase the flash prior to writing\n");
|
||||
return (-1);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,12 @@
|
|||
#define BANK_1 0
|
||||
#define BANK_2 1
|
||||
|
||||
enum erase_type_t {
|
||||
NO_ERASE = 0,
|
||||
SECTION_ERASE = 1,
|
||||
MASS_ERASE = 2,
|
||||
};
|
||||
|
||||
uint32_t get_stm32l0_flash_base(stlink_t *);
|
||||
uint32_t read_flash_cr(stlink_t *, uint32_t);
|
||||
void lock_flash(stlink_t *);
|
||||
|
@ -39,15 +45,20 @@ void clear_flash_cr_pg(stlink_t *, uint32_t);
|
|||
int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr);
|
||||
int32_t stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, uint32_t size, bool align_size);
|
||||
int32_t stlink_erase_flash_mass(stlink_t *sl);
|
||||
int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, stm32_addr_t addr);
|
||||
int32_t stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr);
|
||||
int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length,
|
||||
stm32_addr_t addr, const enum erase_type_t erase);
|
||||
int32_t stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr,
|
||||
const enum erase_type_t erase);
|
||||
int32_t stlink_fcheck_flash(stlink_t *sl, const char *path, stm32_addr_t addr);
|
||||
int32_t stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, uint32_t length);
|
||||
int32_t stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, uint32_t size);
|
||||
int32_t stlink_check_address_range_validity_otp(stlink_t *sl, stm32_addr_t addr, uint32_t size);
|
||||
int32_t stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr);
|
||||
int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint8_t eraseonly);
|
||||
int32_t stlink_write_otp(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len);
|
||||
int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base,
|
||||
uint32_t len, uint8_t erase_only,
|
||||
const enum erase_type_t erase);
|
||||
int32_t stlink_write_otp(stlink_t *sl, stm32_addr_t addr, uint8_t *base,
|
||||
uint32_t len);
|
||||
void stlink_fwrite_finalize(stlink_t *, stm32_addr_t);
|
||||
|
||||
#endif // COMMON_FLASH_H
|
||||
|
|
|
@ -91,7 +91,7 @@ static struct Test tests[] = {
|
|||
.freq = 0,
|
||||
.format = FLASH_FORMAT_BINARY }
|
||||
},
|
||||
{ "--debug --reset write test.bin 0x80000000", 0,
|
||||
{ "--debug --mass-erase --reset write test.bin 0x80000000", 0,
|
||||
{ .cmd = FLASH_CMD_WRITE,
|
||||
.serial = { 0 },
|
||||
.filename = "test.bin",
|
||||
|
@ -99,6 +99,7 @@ static struct Test tests[] = {
|
|||
.size = 0,
|
||||
.reset = 1,
|
||||
.log_level = DEBUG_LOG_LEVEL,
|
||||
.mass_erase = 1,
|
||||
.freq = 0,
|
||||
.format = FLASH_FORMAT_BINARY }
|
||||
},
|
||||
|
@ -187,6 +188,19 @@ static struct Test tests[] = {
|
|||
.size = 0,
|
||||
.reset = 0,
|
||||
.log_level = STND_LOG_LEVEL,
|
||||
.mass_erase = 1,
|
||||
.freq = 0,
|
||||
.format = FLASH_FORMAT_BINARY }
|
||||
},
|
||||
{ "--mass-erase erase", 0,
|
||||
{ .cmd = FLASH_CMD_ERASE,
|
||||
.serial = { 0 },
|
||||
.filename = NULL,
|
||||
.addr = 0,
|
||||
.size = 0,
|
||||
.reset = 0,
|
||||
.log_level = STND_LOG_LEVEL,
|
||||
.mass_erase = 1,
|
||||
.freq = 0,
|
||||
.format = FLASH_FORMAT_BINARY }
|
||||
},
|
||||
|
|
Ładowanie…
Reference in New Issue