Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] --mass-erase for st-flash write commands #1397

Merged
merged 2 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 25 additions & 11 deletions src/st-flash/flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,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 @@ -120,6 +121,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 @@ -131,9 +140,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 @@ -188,7 +197,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 @@ -203,16 +212,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 @@ -102,6 +102,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 @@ -596,8 +596,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
18 changes: 12 additions & 6 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 @@ -1374,7 +1377,7 @@ int32_t stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) {
} 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, 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
Loading