Skip to content
This repository was archived by the owner on Oct 5, 2021. It is now read-only.

Commit c735612

Browse files
author
Geoffrey McRae
committed
addded: support for unprotecting the flash
For example, the USB chip on the STM32 discovery has protected flash by default, which needs to be unprotected, otherwise flashing will fail. Signed-off-by: Steve Markgraf <steve@steve-m.de>
1 parent 97b3d93 commit c735612

File tree

3 files changed

+35
-12
lines changed

3 files changed

+35
-12
lines changed

main.c

+21-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/*
22
stm32flash - Open Source ST STM32 flash program for *nix
33
Copyright (C) 2010 Geoffrey McRae <geoff@spacevs.com>
4+
..Copyright (C) 2011 Steve Markgraf <steve@steve-m.de>
45
56
This program is free software; you can redistribute it and/or
67
modify it under the terms of the GNU General Public License
@@ -46,6 +47,7 @@ char *device = NULL;
4647
serial_baud_t baudRate = SERIAL_BAUD_57600;
4748
int rd = 0;
4849
int wr = 0;
50+
int wu = 0;
4951
int npages = 0xFF;
5052
char verify = 0;
5153
int retry = 10;
@@ -164,7 +166,7 @@ int main(int argc, char* argv[]) {
164166
uint32_t left = stm->dev->fl_end - addr;
165167
len = sizeof(buffer) > left ? left : sizeof(buffer);
166168
if (!stm32_read_memory(stm, addr, buffer, len)) {
167-
fprintf(stderr, "Failed to read memory at address 0x%08x\n", addr);
169+
fprintf(stderr, "Failed to read memory at address 0x%08x, target write-protected?\n", addr);
168170
goto close;
169171
}
170172
assert(parser->write(p_st, buffer, len) == PARSER_ERR_OK);
@@ -180,8 +182,15 @@ int main(int argc, char* argv[]) {
180182
fprintf(stdout, "Done.\n");
181183
ret = 0;
182184
goto close;
183-
} else
184-
if (wr) {
185+
186+
} else if (wu) {
187+
fprintf(stdout, "Write-unprotecting flash\n");
188+
/* the device automatically performs a reset after the sending the ACK */
189+
reset_flag = 0;
190+
stm32_wunprot_memory(stm);
191+
fprintf(stdout, "Done.\n");
192+
193+
} else if (wr) {
185194
printf("\n");
186195

187196
off_t offset = 0;
@@ -287,7 +296,7 @@ int main(int argc, char* argv[]) {
287296

288297
int parse_options(int argc, char *argv[]) {
289298
int c;
290-
while((c = getopt(argc, argv, "b:r:w:e:vn:g:fch")) != -1) {
299+
while((c = getopt(argc, argv, "b:r:w:e:vn:g:fchu")) != -1) {
291300
switch(c) {
292301
case 'b':
293302
baudRate = serial_get_baud(strtoul(optarg, NULL, 0));
@@ -316,7 +325,13 @@ int parse_options(int argc, char *argv[]) {
316325
return 1;
317326
}
318327
break;
319-
328+
case 'u':
329+
wu = 1;
330+
if (rd || wr) {
331+
fprintf(stderr, "ERROR: Invalid options, can't write unprotect and read/write at the same time\n");
332+
return 1;
333+
}
334+
break;
320335
case 'v':
321336
verify = 1;
322337
break;
@@ -374,6 +389,7 @@ void show_help(char *name) {
374389
" -b rate Baud rate (default 57600)\n"
375390
" -r filename Read flash to file\n"
376391
" -w filename Write flash to file\n"
392+
" -u Disable the flash write-protection\n"
377393
" -e n Only erase n pages before writing the flash\n"
378394
" -v Verify writes\n"
379395
" -n count Retry failed writes up to count times (default 10)\n"

stm32.c

+6
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,12 @@ char stm32_write_memory(const stm32_t *stm, uint32_t address, uint8_t data[], un
251251
return stm32_read_byte(stm) == STM32_ACK;
252252
}
253253

254+
char stm32_wunprot_memory(const stm32_t *stm) {
255+
if (!stm32_send_command(stm, stm->cmd->uw)) return 0;
256+
if (!stm32_send_command(stm, 0x8C )) return 0;
257+
return 1;
258+
}
259+
254260
char stm32_erase_memory(const stm32_t *stm, uint8_t pages) {
255261
if (!stm32_send_command(stm, stm->cmd->er)) return 0;
256262
if (pages == 0xFF) {

stm32.h

+8-7
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,14 @@ struct stm32_dev {
4949
uint32_t mem_start, mem_end;
5050
};
5151

52-
stm32_t* stm32_init (const serial_t *serial, const char init);
53-
void stm32_close (stm32_t *stm);
54-
char stm32_read_memory (const stm32_t *stm, uint32_t address, uint8_t data[], unsigned int len);
55-
char stm32_write_memory(const stm32_t *stm, uint32_t address, uint8_t data[], unsigned int len);
56-
char stm32_erase_memory(const stm32_t *stm, uint8_t pages);
57-
char stm32_go (const stm32_t *stm, uint32_t address);
58-
char stm32_reset_device(const stm32_t *stm);
52+
stm32_t* stm32_init (const serial_t *serial, const char init);
53+
void stm32_close (stm32_t *stm);
54+
char stm32_read_memory (const stm32_t *stm, uint32_t address, uint8_t data[], unsigned int len);
55+
char stm32_write_memory (const stm32_t *stm, uint32_t address, uint8_t data[], unsigned int len);
56+
char stm32_wunprot_memory(const stm32_t *stm);
57+
char stm32_erase_memory (const stm32_t *stm, uint8_t pages);
58+
char stm32_go (const stm32_t *stm, uint32_t address);
59+
char stm32_reset_device (const stm32_t *stm);
5960

6061
#endif
6162

0 commit comments

Comments
 (0)