kopia lustrzana https://github.com/stlink-org/stlink
Merge branch 'develop' into stlink-v3_pre
commit
d827ce1e8e
|
@ -19,6 +19,17 @@ The size may be followed by an optional "k" or "m" to multiply the given value b
|
|||
When flashing a file, a checksum is calculated for the binary file, both in md5 and the sum algorithm.
|
||||
The latter is also used by the official ST-Link utility tool from STMicroelectronics as described in the document: [`UM0892 - User manual - STM32 ST-LINK utility software description`](https://www.st.com/resource/en/user_manual/cd00262073-stm32-stlink-utility-software-description-stmicroelectronics.pdf).
|
||||
|
||||
#### --freq=n[k][m]
|
||||
|
||||
(since v1.6.1)
|
||||
|
||||
You can specify the frequency of SWD/JTAG interface, to override the default 1800KHz configuration. This option accpets decimal only (5K or 1.8M). `Hz` is left out in this option. Valid frequencies are `5K, 15K, 25K, 50K, 100K, 125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)`
|
||||
|
||||
#### --opt
|
||||
|
||||
(since v1.6.1, optional; enabled by default from v1.0.0 to v1.6.0)
|
||||
|
||||
You can enable the optimization to skip flashing empty (0x00 or 0xff) bytes at the end of binary file. May cause some garbage data left after a flash.
|
||||
|
||||
## Solutions to common problems
|
||||
### a) STLINK/v1 driver: Issue with Kernel Extension (kext) (macOS 10.11 and later only)
|
||||
|
|
|
@ -102,7 +102,6 @@ enum target_state {
|
|||
#define S_RETIRE_ST (1 << 24)
|
||||
#define S_RESET_ST (1 << 25)
|
||||
|
||||
|
||||
/* Map the relevant features, quirks and workaround for specific firmware version of stlink */
|
||||
#define STLINK_F_HAS_TRACE (1<<0)
|
||||
#define STLINK_F_HAS_SWD_SET_FREQ (1<<1)
|
||||
|
@ -115,7 +114,6 @@ enum target_state {
|
|||
#define STLINK_F_HAS_DPBANKSEL (1<<8)
|
||||
#define STLINK_F_HAS_RW8_512BYTES (1<<9)
|
||||
|
||||
|
||||
#define C_BUF_LEN 32
|
||||
|
||||
enum stlink_flash_type {
|
||||
|
@ -185,7 +183,7 @@ enum transport_type {
|
|||
};
|
||||
|
||||
typedef struct _stlink stlink_t;
|
||||
|
||||
|
||||
#include <backend.h>
|
||||
|
||||
struct _stlink {
|
||||
|
@ -207,6 +205,7 @@ struct _stlink {
|
|||
|
||||
char serial[STLINK_SERIAL_MAX_SIZE];
|
||||
int serial_size;
|
||||
int freq; // set by stlink_open_usb(), values: STLINK_SWDCLK_xxx_DIVISOR
|
||||
|
||||
enum stlink_flash_type flash_type;
|
||||
// stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx
|
||||
|
|
|
@ -25,10 +25,11 @@ struct flash_opts
|
|||
enum flash_area area;
|
||||
uint32_t val;
|
||||
size_t flash_size; /* --flash=n[k][m] */
|
||||
int opt;
|
||||
int opt; /* enable empty tail data drop optimization */
|
||||
int freq; /* --freq=n[k][m] frequency of JTAG/SWD */
|
||||
};
|
||||
|
||||
#define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 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}
|
||||
|
||||
int flash_get_opts(struct flash_opts* o, int ac, char** av);
|
||||
|
||||
|
|
|
@ -87,9 +87,9 @@ static void cleanup(int signum) {
|
|||
static stlink_t* do_connect(st_state_t *st) {
|
||||
stlink_t *sl = NULL;
|
||||
if (serial_specified) {
|
||||
sl = stlink_open_usb(st->logging_level, st->reset, serialnumber);
|
||||
sl = stlink_open_usb(st->logging_level, st->reset, serialnumber, 0);
|
||||
} else {
|
||||
sl = stlink_open_usb(st->logging_level, st->reset, NULL);
|
||||
sl = stlink_open_usb(st->logging_level, st->reset, NULL, 0);
|
||||
}
|
||||
return sl;
|
||||
}
|
||||
|
|
|
@ -490,7 +490,7 @@ static void connect_button_cb (GtkWidget *widget, gpointer data) {
|
|||
/* try version 1 then version 2 */
|
||||
gui->sl = stlink_v1_open(0, 1);
|
||||
if (gui->sl == NULL)
|
||||
gui->sl = stlink_open_usb(0, 1, NULL);
|
||||
gui->sl = stlink_open_usb(0, 1, NULL, 0);
|
||||
if (gui->sl == NULL) {
|
||||
stlink_gui_set_info_error_message (gui, "Failed to connect to STLink.");
|
||||
return;
|
||||
|
|
|
@ -28,9 +28,9 @@ static void cleanup(int signum) {
|
|||
|
||||
static void usage(void)
|
||||
{
|
||||
puts("command line: ./st-flash [--debug] [--reset] [--opt] [--serial <serial>] [--format <format>] [--flash=<fsize>] {read|write} <path> [addr] [size]");
|
||||
puts("command line: ./st-flash [--debug] [--serial <serial>] erase");
|
||||
puts("command line: ./st-flash [--debug] [--serial <serial>] reset");
|
||||
puts("command line: ./st-flash [--debug] [--reset] [--opt] [--serial <serial>] [--format <format>] [--flash=<fsize>] [--freq=<Hz>] {read|write} <path> [addr] [size]");
|
||||
puts("command line: ./st-flash [--debug] [--freq=<Hz>] [--serial <serial>] erase");
|
||||
puts("command line: ./st-flash [--debug] [--freq=<Hz>] [--serial <serial>] reset");
|
||||
puts(" <addr>, <serial> and <size>: Use hex format.");
|
||||
puts(" <fsize>: Use decimal, octal or hex (prefix 0xXXX) format, optionally followed by k=KB, or m=MB (eg. --flash=128k)");
|
||||
puts(" <format>: Can be 'binary' (default) or 'ihex', although <addr> must be specified for binary format only.");
|
||||
|
@ -56,7 +56,7 @@ int main(int ac, char** av)
|
|||
|
||||
printf("st-flash %s\n", STLINK_VERSION);
|
||||
|
||||
sl = stlink_open_usb(o.log_level, 1, (char *)o.serial);
|
||||
sl = stlink_open_usb(o.log_level, 1, (char *)o.serial, o.freq);
|
||||
|
||||
if (sl == NULL) {
|
||||
return -1;
|
||||
|
|
|
@ -149,6 +149,56 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) {
|
|||
return -1;
|
||||
|
||||
}
|
||||
else if (strcmp(av[0], "--freq") == 0 || starts_with(av[0], "--freq=")) {
|
||||
const char* freq;
|
||||
if (strcmp(av[0], "--freq") == 0) {
|
||||
ac--;
|
||||
av++;
|
||||
if (ac < 1) return -1;
|
||||
freq = av[0];
|
||||
}
|
||||
else {
|
||||
freq = av[0] + strlen("--freq=");
|
||||
}
|
||||
if (strcmp(freq, "5K") == 0 || strcmp(freq, "5k") == 0) {
|
||||
o->freq = 5;
|
||||
}
|
||||
else if (strcmp(freq, "15K") == 0 || strcmp(freq, "15k") == 0) {
|
||||
o->freq = 15;
|
||||
}
|
||||
else if (strcmp(freq, "25K") == 0 || strcmp(freq, "25k") == 0) {
|
||||
o->freq = 25;
|
||||
}
|
||||
else if (strcmp(freq, "50K") == 0 || strcmp(freq, "50k") == 0) {
|
||||
o->freq = 50;
|
||||
}
|
||||
else if (strcmp(freq, "100K") == 0 || strcmp(freq, "100k") == 0) {
|
||||
o->freq = 100;
|
||||
}
|
||||
else if (strcmp(freq, "125K") == 0 || strcmp(freq, "125k") == 0) {
|
||||
o->freq = 125;
|
||||
}
|
||||
else if (strcmp(freq, "240K") == 0 || strcmp(freq, "240k") == 0) {
|
||||
o->freq = 240;
|
||||
}
|
||||
else if (strcmp(freq, "480K") == 0 || strcmp(freq, "480k") == 0) {
|
||||
o->freq = 480;
|
||||
}
|
||||
else if (strcmp(freq, "950K") == 0 || strcmp(freq, "950k") == 0) {
|
||||
o->freq = 950;
|
||||
}
|
||||
else if (strcmp(freq, "1200K") == 0 || strcmp(freq, "1200k") == 0 || strcmp(freq, "1.2M") == 0 || strcmp(freq, "1.2m") == 0) {
|
||||
o->freq = 1200;
|
||||
}
|
||||
else if (strcmp(freq, "1800K") == 0 || strcmp(freq, "1800k") == 0 || strcmp(freq, "1.8M") == 0 || strcmp(freq, "1.8m") == 0) {
|
||||
o->freq = 1800;
|
||||
}
|
||||
else if (strcmp(freq, "4000K") == 0 || strcmp(freq, "4000k") == 0 || strcmp(freq, "4M") == 0 || strcmp(freq, "4m") == 0) {
|
||||
o->freq = 4000;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else if (strcmp(av[0], "--format") == 0 || starts_with(av[0], "--format=")) {
|
||||
const char * format;
|
||||
if (strcmp(av[0], "--format") == 0) {
|
||||
|
|
|
@ -81,7 +81,7 @@ static stlink_t *stlink_open_first(void)
|
|||
stlink_t* sl = NULL;
|
||||
sl = stlink_v1_open(0, 1);
|
||||
if (sl == NULL)
|
||||
sl = stlink_open_usb(0, 1, NULL);
|
||||
sl = stlink_open_usb(0, 1, NULL, 0);
|
||||
|
||||
return sl;
|
||||
}
|
||||
|
|
47
src/usb.c
47
src/usb.c
|
@ -949,7 +949,7 @@ static stlink_backend_t _stlink_usb_backend = {
|
|||
_stlink_usb_set_swdclk
|
||||
};
|
||||
|
||||
stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE])
|
||||
stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq)
|
||||
{
|
||||
stlink_t* sl = NULL;
|
||||
struct stlink_libusb* slu = NULL;
|
||||
|
@ -1130,10 +1130,51 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST
|
|||
stlink_exit_dfu_mode(sl);
|
||||
}
|
||||
|
||||
|
||||
sl->freq = freq;
|
||||
// set the speed before entering the mode
|
||||
// as the chip discovery phase should be done at this speed too
|
||||
// Set the stlink clock speed (default is 1800kHz)
|
||||
stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR);
|
||||
DLOG("JTAG/SWD freq set to %d\n", freq);
|
||||
switch (freq) {
|
||||
case 5:
|
||||
stlink_set_swdclk(sl, STLINK_SWDCLK_5KHZ_DIVISOR);
|
||||
break;
|
||||
case 15:
|
||||
stlink_set_swdclk(sl, STLINK_SWDCLK_15KHZ_DIVISOR);
|
||||
break;
|
||||
case 25:
|
||||
stlink_set_swdclk(sl, STLINK_SWDCLK_25KHZ_DIVISOR);
|
||||
break;
|
||||
case 50:
|
||||
stlink_set_swdclk(sl, STLINK_SWDCLK_50KHZ_DIVISOR);
|
||||
break;
|
||||
case 100:
|
||||
stlink_set_swdclk(sl, STLINK_SWDCLK_100KHZ_DIVISOR);
|
||||
break;
|
||||
case 125:
|
||||
stlink_set_swdclk(sl, STLINK_SWDCLK_125KHZ_DIVISOR);
|
||||
break;
|
||||
case 240:
|
||||
stlink_set_swdclk(sl, STLINK_SWDCLK_240KHZ_DIVISOR);
|
||||
break;
|
||||
case 480:
|
||||
stlink_set_swdclk(sl, STLINK_SWDCLK_480KHZ_DIVISOR);
|
||||
break;
|
||||
case 950:
|
||||
stlink_set_swdclk(sl, STLINK_SWDCLK_950KHZ_DIVISOR);
|
||||
break;
|
||||
case 1200:
|
||||
stlink_set_swdclk(sl, STLINK_SWDCLK_1P2MHZ_DIVISOR);
|
||||
break;
|
||||
case 0: case 1800:
|
||||
stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR);
|
||||
break;
|
||||
case 4000:
|
||||
stlink_set_swdclk(sl, STLINK_SWDCLK_4MHZ_DIVISOR);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) {
|
||||
stlink_enter_swd_mode(sl);
|
||||
|
@ -1234,7 +1275,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) {
|
|||
continue;
|
||||
}
|
||||
|
||||
stlink_t *sl = stlink_open_usb(0, 1, serial);
|
||||
stlink_t *sl = stlink_open_usb(0, 1, serial, 0);
|
||||
if (!sl) {
|
||||
ELOG("Failed to open USB device %#06x:%#06x\n", desc.idVendor, desc.idProduct);
|
||||
continue;
|
||||
|
|
|
@ -68,7 +68,7 @@ extern "C" {
|
|||
* @retval NULL Error while opening the stlink
|
||||
* @retval !NULL Stlink found and ready to use
|
||||
*/
|
||||
stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE]);
|
||||
stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq);
|
||||
size_t stlink_probe_usb(stlink_t **stdevs[]);
|
||||
void stlink_probe_usb_free(stlink_t **stdevs[], size_t size);
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@ static bool execute_test(const struct Test * test) {
|
|||
ret &= (opts.size == test->opts.size);
|
||||
ret &= (opts.reset == test->opts.reset);
|
||||
ret &= (opts.log_level == test->opts.log_level);
|
||||
ret &= (opts.freq == test->opts.freq);
|
||||
ret &= (opts.format == test->opts.format);
|
||||
}
|
||||
|
||||
|
@ -83,6 +84,7 @@ static struct Test tests[] = {
|
|||
.size = 0x1000,
|
||||
.reset = 1,
|
||||
.log_level = DEBUG_LOG_LEVEL,
|
||||
.freq = 0,
|
||||
.format = FLASH_FORMAT_BINARY }
|
||||
},
|
||||
{ "--debug --reset write test.bin 0x80000000", 0,
|
||||
|
@ -93,6 +95,51 @@ static struct Test tests[] = {
|
|||
.size = 0,
|
||||
.reset = 1,
|
||||
.log_level = DEBUG_LOG_LEVEL,
|
||||
.freq = 0,
|
||||
.format = FLASH_FORMAT_BINARY }
|
||||
},
|
||||
{ "--debug --freq 5k --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,
|
||||
.freq = 5,
|
||||
.format = FLASH_FORMAT_BINARY }
|
||||
},
|
||||
{ "--debug --freq 15K --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,
|
||||
.freq = 15,
|
||||
.format = FLASH_FORMAT_BINARY }
|
||||
},
|
||||
{ "--debug --freq=5k --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,
|
||||
.freq = 5,
|
||||
.format = FLASH_FORMAT_BINARY }
|
||||
},
|
||||
{ "--debug --freq=6k --reset write test.bin 0x80000000", -1,
|
||||
{ .cmd = FLASH_CMD_WRITE,
|
||||
.serial = { 0 },
|
||||
.filename = "test.bin",
|
||||
.addr = 0x80000000,
|
||||
.size = 0,
|
||||
.reset = 1,
|
||||
.log_level = DEBUG_LOG_LEVEL,
|
||||
.freq = 6,
|
||||
.format = FLASH_FORMAT_BINARY }
|
||||
},
|
||||
{ "--debug --reset read test.bin 0x80000000 1000", 0,
|
||||
|
@ -103,6 +150,7 @@ static struct Test tests[] = {
|
|||
.size = 1000,
|
||||
.reset = 1,
|
||||
.log_level = DEBUG_LOG_LEVEL,
|
||||
.freq = 0,
|
||||
.format = FLASH_FORMAT_BINARY }
|
||||
},
|
||||
{ "--debug --reset read test.bin 0x80000000 1k", 0,
|
||||
|
@ -113,6 +161,7 @@ static struct Test tests[] = {
|
|||
.size = 1024,
|
||||
.reset = 1,
|
||||
.log_level = DEBUG_LOG_LEVEL,
|
||||
.freq = 0,
|
||||
.format = FLASH_FORMAT_BINARY }
|
||||
},
|
||||
{ "--debug --reset read test.bin 0x80000000 1M", 0,
|
||||
|
@ -123,6 +172,7 @@ static struct Test tests[] = {
|
|||
.size = 1048576,
|
||||
.reset = 1,
|
||||
.log_level = DEBUG_LOG_LEVEL,
|
||||
.freq = 0,
|
||||
.format = FLASH_FORMAT_BINARY }
|
||||
},
|
||||
{ "--debug --reset write test.bin 0x80000000", 0,
|
||||
|
@ -133,6 +183,7 @@ static struct Test tests[] = {
|
|||
.size = 0,
|
||||
.reset = 1,
|
||||
.log_level = DEBUG_LOG_LEVEL,
|
||||
.freq = 0,
|
||||
.format = FLASH_FORMAT_BINARY }
|
||||
},
|
||||
{ "erase", 0,
|
||||
|
@ -143,6 +194,7 @@ static struct Test tests[] = {
|
|||
.size = 0,
|
||||
.reset = 0,
|
||||
.log_level = STND_LOG_LEVEL,
|
||||
.freq = 0,
|
||||
.format = FLASH_FORMAT_BINARY }
|
||||
},
|
||||
{ "--debug --reset --format=ihex write test.hex", 0,
|
||||
|
@ -153,6 +205,7 @@ static struct Test tests[] = {
|
|||
.size = 0,
|
||||
.reset = 1,
|
||||
.log_level = DEBUG_LOG_LEVEL,
|
||||
.freq = 0,
|
||||
.format = FLASH_FORMAT_IHEX }
|
||||
},
|
||||
{ "--debug --reset --format=binary write test.hex", -1, FLASH_OPTS_INITIALIZER },
|
||||
|
@ -167,6 +220,7 @@ static struct Test tests[] = {
|
|||
.size = 0,
|
||||
.reset = 0,
|
||||
.log_level = STND_LOG_LEVEL,
|
||||
.freq = 0,
|
||||
.format = FLASH_FORMAT_BINARY }
|
||||
},
|
||||
{ "--serial=A1020304 erase", 0,
|
||||
|
@ -177,6 +231,7 @@ static struct Test tests[] = {
|
|||
.size = 0,
|
||||
.reset = 0,
|
||||
.log_level = STND_LOG_LEVEL,
|
||||
.freq = 0,
|
||||
.format = FLASH_FORMAT_BINARY }
|
||||
},
|
||||
};
|
||||
|
|
|
@ -9,7 +9,7 @@ int main(int ac, char** av) {
|
|||
stlink_t* sl;
|
||||
struct stlink_reg regs;
|
||||
|
||||
sl = stlink_open_usb(10, 1, NULL);
|
||||
sl = stlink_open_usb(10, 1, NULL, 0);
|
||||
if (sl != NULL) {
|
||||
printf("-- version\n");
|
||||
stlink_version(sl);
|
||||
|
|
Ładowanie…
Reference in New Issue