1 /* Simple wrapper around the stlink_flash_write function */
2 
3 // TODO - this should be done as just a simple flag to the st-util command line...
4 
5 #include <signal.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/types.h>
10 
11 #include <stlink.h>
12 #include "flash.h"
13 
14 static stlink_t *connected_stlink = NULL;
15 
cleanup(int signum)16 static void cleanup(int signum) {
17     (void)signum;
18 
19     if (connected_stlink) { // switch back to mass storage mode before closing
20         stlink_run(connected_stlink, RUN_NORMAL);
21         stlink_exit_debug_mode(connected_stlink);
22         stlink_close(connected_stlink);
23     }
24 
25     exit(1);
26 }
27 
usage(void)28 static void usage(void) {
29     puts("command line:   ./st-flash [--debug] [--reset] [--connect-under-reset] [--hot-plug] [--opt] [--serial <serial>] [--format <format>] [--flash=<fsize>] [--freq=<KHz>] [--area=<area>] {read|write} [path] [addr] [size]");
30     puts("command line:   ./st-flash [--debug] [--connect-under-reset] [--hot-plug] [--freq=<KHz>] [--serial <serial>] erase");
31     puts("command line:   ./st-flash [--debug] [--freq=<KHz>] [--serial <serial>] reset");
32     puts("   <addr>, <serial> and <size>: Use hex format.");
33     puts("   <fsize>: Use decimal, octal or hex (prefix 0xXXX) format, optionally followed by k=KB, or m=MB (eg. --flash=128k)");
34     puts("   <format>: Can be 'binary' (default) or 'ihex', although <addr> must be specified for binary format only.");
35     puts("   <area>: Can be 'main' (default), 'system', 'otp', 'optcr', 'optcr1', 'option' or 'option_boot_add'");
36     puts("print tool version info:   ./st-flash [--version]");
37     puts("example read option byte: ./st-flash --area=option read [path] [size]");
38     puts("example write option byte: ./st-flash --area=option write 0xXXXXXXXX");
39     puts("On selected targets:");
40     puts("example read boot_add option byte:  ./st-flash --area=option_boot_add read");
41     puts("example write boot_add option byte: ./st-flash --area=option_boot_add write 0xXXXXXXXX");
42     puts("example read option control register byte:  ./st-flash --area=optcr read");
43     puts("example write option control register1 byte:  ./st-flash --area=optcr write 0xXXXXXXXX");
44     puts("example read option control register1 byte:  ./st-flash --area=optcr1 read");
45     puts("example write option control register1 byte:  ./st-flash --area=optcr1 write 0xXXXXXXXX");
46 }
47 
main(int ac,char ** av)48 int main(int ac, char** av) {
49     stlink_t* sl = NULL;
50     struct flash_opts o;
51     int err = -1;
52     uint8_t * mem = NULL;
53 
54     o.size = 0;
55     o.connect = CONNECT_NORMAL;
56 
57     if (flash_get_opts(&o, ac - 1, av + 1) == -1) {
58         printf("invalid command line\n");
59         usage();
60         return(-1);
61     }
62 
63     printf("st-flash %s\n", STLINK_VERSION);
64 
65     sl = stlink_open_usb(o.log_level, o.connect, (char *)o.serial, o.freq);
66 
67     if (sl == NULL) { return(-1); }
68 
69     if (sl->flash_type == STLINK_FLASH_TYPE_UNKNOWN) {
70         printf("Failed to connect to target\n");
71         return(-1);
72     }
73 
74     if ( o.flash_size != 0u && o.flash_size != sl->flash_size ) {
75         sl->flash_size = o.flash_size;
76         printf("Forcing flash size: --flash=0x%08X\n", (unsigned int)sl->flash_size);
77     }
78 
79     sl->verbose = o.log_level;
80     sl->opt = o.opt;
81 
82     connected_stlink = sl;
83     signal(SIGINT, &cleanup);
84     signal(SIGTERM, &cleanup);
85     signal(SIGSEGV, &cleanup);
86 
87     if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) {
88         if (stlink_exit_dfu_mode(sl)) {
89             printf("Failed to exit DFU mode\n");
90             goto on_error;
91         }
92     }
93 
94     if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) {
95         if (stlink_enter_swd_mode(sl)) {
96             printf("Failed to enter SWD mode\n");
97             goto on_error;
98         }
99     }
100 
101     // core must be halted to use RAM based flashloaders
102     if (stlink_force_debug(sl)) {
103         printf("Failed to halt the core\n");
104         goto on_error;
105     }
106 
107     if (stlink_status(sl)) {
108         printf("Failed to get Core's status\n");
109         goto on_error;
110     }
111 
112     if (o.cmd == FLASH_CMD_WRITE) {                                             // write
113         size_t size = 0;
114         if (o.format == FLASH_FORMAT_IHEX) {
115             err = stlink_parse_ihex(o.filename, stlink_get_erased_pattern(sl), &mem, &size, &o.addr);
116 
117             if (err == -1) {
118                 printf("Cannot parse %s as Intel-HEX file\n", o.filename);
119                 goto on_error;
120             }
121         }
122         if ((o.addr >= sl->flash_base) &&
123             (o.addr < sl->flash_base + sl->flash_size)) {
124             if (o.format == FLASH_FORMAT_IHEX) {
125                 err = stlink_mwrite_flash(sl, mem, (uint32_t)size, o.addr);
126             } else {
127                 err = stlink_fwrite_flash(sl, o.filename, o.addr);
128             }
129 
130             if (err == -1) {
131                 printf("stlink_fwrite_flash() == -1\n");
132                 goto on_error;
133             }
134         } else if ((o.addr >= sl->sram_base) &&
135                    (o.addr < sl->sram_base + sl->sram_size)) {
136             if (o.format == FLASH_FORMAT_IHEX) {
137                 err = stlink_mwrite_sram(sl, mem, (uint32_t)size, o.addr);
138             } else {
139                 err = stlink_fwrite_sram(sl, o.filename, o.addr);
140             }
141 
142             if (err == -1) {
143                 printf("stlink_fwrite_sram() == -1\n");
144                 goto on_error;
145             }
146         } else if ((o.addr >= sl->option_base) &&
147                    (o.addr < sl->option_base + sl->option_size)) {
148             err = stlink_fwrite_option_bytes(sl, o.filename, o.addr);
149 
150             if (err == -1) {
151                 printf("stlink_fwrite_option_bytes() == -1\n");
152                 goto on_error;
153             }
154         } else if (o.area == FLASH_OPTION_BYTES) {
155             if (o.val == 0) {
156                 printf("attempting to set option byte to 0, abort.\n");
157                 goto on_error;
158             }
159 
160             err = stlink_write_option_bytes32(sl, o.val);
161 
162             if (err == -1) {
163                 printf("stlink_write_option_bytes32() == -1\n");
164                 goto on_error;
165             }
166         } else if (o.area == FLASH_OPTCR) {
167             DLOG("@@@@ Write %d (%0#10x) to option control register\n", o.val, o.val);
168 
169             err = stlink_write_option_control_register32(sl, o.val);
170         } else if (o.area == FLASH_OPTCR1) {
171             DLOG("@@@@ Write %d (%0#10x) to option control register 1\n", o.val, o.val);
172 
173             err = stlink_write_option_control_register1_32(sl, o.val);
174         } else if (o.area == FLASH_OPTION_BYTES_BOOT_ADD) {
175             DLOG("@@@@ Write %d (%0#10x) to option bytes boot address\n", o.val, o.val);
176 
177             err = stlink_write_option_bytes_boot_add32(sl, o.val);
178         } else {
179             err = -1;
180             printf("Unknown memory region\n");
181             goto on_error;
182         }
183     } else if (o.cmd == FLASH_CMD_ERASE) {
184         err = stlink_erase_flash_mass(sl);
185 
186         if (err == -1) {
187             printf("stlink_erase_flash_mass() == -1\n");
188             goto on_error;
189         }
190     } else if (o.cmd == CMD_RESET) {
191         if (stlink_reset(sl, RESET_AUTO)) {
192             printf("Failed to reset device\n");
193             goto on_error;
194         }
195     } else {                                                                    // read
196         if ((o.area == FLASH_MAIN_MEMORY) || (o.area == FLASH_SYSTEM_MEMORY)) {
197             if ((o.size == 0) && (o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) {
198                 o.size = sl->flash_size;
199             }
200             else if ((o.size == 0) && (o.addr >= sl->sram_base) && (o.addr < sl->sram_base + sl->sram_size)) {
201                 o.size = sl->sram_size;
202             }
203             err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, o.addr, o.size);
204 
205             if (err == -1) {
206                 printf("could not read main memory (%d)\n", err);
207                 goto on_error;
208             }
209         } else if (o.area == FLASH_OPTION_BYTES) {
210             uint8_t remaining_option_length = sl->option_size / 4;
211             DLOG("@@@@ Read %d (%#x) option bytes from %#10x\n", remaining_option_length, remaining_option_length, sl->option_base);
212 
213             if (NULL != o.filename) {
214                 if (0 == o.size) {
215                     o.size = sl->option_size;
216                 }
217                 err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, sl->option_base, o.size);
218             } else {
219                 uint32_t option_byte = 0;
220                 err = stlink_read_option_bytes32(sl, &option_byte);
221                 if (err == -1) {
222                     printf("could not read option bytes (%d)\n", err);
223                     goto on_error;
224                 } else {
225                     printf("%08x\n", option_byte);
226                 }
227             }
228         } else if (o.area == FLASH_OPTION_BYTES_BOOT_ADD) {
229             uint32_t option_byte = 0;
230             err = stlink_read_option_bytes_boot_add32(sl, &option_byte);
231             if (err == -1) {
232                 printf("could not read option bytes boot address (%d)\n", err);
233                 goto on_error;
234             } else {
235                 printf("%08x\n",option_byte);
236             }
237         } else if (o.area == FLASH_OPTCR) {
238             uint32_t option_byte = 0;
239             err = stlink_read_option_control_register32(sl, &option_byte);
240             if (err == -1) {
241                 printf("could not read option control register (%d)\n", err);
242                 goto on_error;
243             } else {
244                 printf("%08x\n",option_byte);
245             }
246         } else if (o.area == FLASH_OPTCR1) {
247             uint32_t option_byte = 0;
248             err = stlink_read_option_control_register1_32(sl, &option_byte);
249             if (err == -1) {
250                 printf("could not read option control register (%d)\n", err);
251                 goto on_error;
252             } else {
253                 printf("%08x\n",option_byte);
254             }
255         }
256     }
257 
258     if (o.reset) {
259         stlink_reset(sl, RESET_AUTO);
260     }
261 
262     err = 0; // success
263 
264 on_error:
265     stlink_exit_debug_mode(sl);
266     stlink_close(sl);
267     free(mem);
268 
269     return(err);
270 }
271