Skip to content

Commit

Permalink
Merge pull request #1397 from hannesweisbach/mass-erase
Browse files Browse the repository at this point in the history
[feature] --mass-erase for st-flash write commands
  • Loading branch information
Nightwalker-87 committed May 29, 2024
2 parents 3520d73 + 794f889 commit a7fa1ae
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 26 deletions.
36 changes: 25 additions & 11 deletions src/st-flash/flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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) {
Expand Down Expand Up @@ -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");
Expand All @@ -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);
}
if (err == -1) {
printf("stlink_erase_flash_mass() == -1\n");
goto on_error;
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");
}
printf("Mass erase completed successfully.\n");

// reset after erase
if (stlink_reset(sl, RESET_AUTO)) {
Expand Down
2 changes: 2 additions & 0 deletions src/st-flash/flash_opts.c
Original file line number Diff line number Diff line change
Expand Up @@ -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=")) {
Expand Down
3 changes: 2 additions & 1 deletion src/st-flash/flash_opts.h
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -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;
};
Expand Down
5 changes: 3 additions & 2 deletions src/stlink-gui/gui.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}

Expand Down
20 changes: 13 additions & 7 deletions src/stlink-lib/common_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
}
Expand Down
19 changes: 15 additions & 4 deletions src/stlink-lib/common_flash.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down Expand Up @@ -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
16 changes: 15 additions & 1 deletion tests/flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,15 @@ 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",
.addr = 0x80000000,
.size = 0,
.reset = 1,
.log_level = DEBUG_LOG_LEVEL,
.mass_erase = 1,
.freq = 0,
.format = FLASH_FORMAT_BINARY }
},
Expand Down Expand Up @@ -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 }
},
Expand Down

0 comments on commit a7fa1ae

Please sign in to comment.