Skip to content

Commit

Permalink
Merge pull request #953 from chenguokai/issue893
Browse files Browse the repository at this point in the history
[feature] Adjust the JTAG/SWD frequency via cmdline option
  • Loading branch information
Nightwalker-87 authored May 8, 2020
2 parents 9b207de + 6c6f27b commit 5284694
Show file tree
Hide file tree
Showing 12 changed files with 176 additions and 16 deletions.
11 changes: 11 additions & 0 deletions doc/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 3 additions & 1 deletion include/stlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,16 @@ typedef struct flash_loader {

// transport layer verboseness: 0 for no debug info, 10 for lots
int verbose;
int opt;
int opt; // set by main() in tools/flash.c, empty tail bytes drop optimization
uint32_t core_id; // set by stlink_core_id(), result from STLINK_DEBUGREADCOREID
uint32_t chip_id; // set by stlink_load_device_params(), used to identify flash and sram
int core_stat; // set by stlink_status(), values STLINK_CORE_xxxxx

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
bool has_dual_bank;

Expand Down
5 changes: 3 additions & 2 deletions include/stlink/tools/flash.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
4 changes: 2 additions & 2 deletions src/st-util/gdb-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion src/stlink-gui/gui.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 4 additions & 4 deletions src/tools/flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.");
Expand All @@ -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;
Expand Down
50 changes: 50 additions & 0 deletions src/tools/flash_opts.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion src/tools/info.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
47 changes: 44 additions & 3 deletions src/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -873,7 +873,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;
Expand Down Expand Up @@ -1041,10 +1041,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);
Expand Down Expand Up @@ -1147,7 +1188,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;
Expand Down
2 changes: 1 addition & 1 deletion src/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
55 changes: 55 additions & 0 deletions tests/flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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 },
Expand All @@ -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,
Expand All @@ -177,6 +231,7 @@ static struct Test tests[] = {
.size = 0,
.reset = 0,
.log_level = STND_LOG_LEVEL,
.freq = 0,
.format = FLASH_FORMAT_BINARY }
},
};
Expand Down
2 changes: 1 addition & 1 deletion tests/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 5284694

Please sign in to comment.