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