Skip to content

Commit

Permalink
Merge pull request #1106 from tarek-bochkati/stlink_serial_fix
Browse files Browse the repository at this point in the history
Fixed old DFU serial number for STLINK programmers
  • Loading branch information
Nightwalker-87 committed Mar 20, 2021
2 parents 7c5ac59 + 9ed3d46 commit 4f7deea
Show file tree
Hide file tree
Showing 10 changed files with 57 additions and 92 deletions.
3 changes: 0 additions & 3 deletions doc/man/st-info.1
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ Display the chip ID of the device
.B \-\-serial
Display the serial code of the device
.TP
.B \-\-hla\-serial
Display the hex escaped serial code of the device
.TP
.B \-\-probe
Display the summarized information of the connected programmers and
devices
Expand Down
8 changes: 2 additions & 6 deletions doc/man/st-info.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ st-info - Provides information about connected STLink and STM32 devices
# DESCRIPTION

Provides information about connected STLink programmers and STM32 devices:
Serial code, OpenOCD hla-serial, flash, page size, sram, chipid, description.
Serial code, flash, page size, sram, chipid, description.

The STLink device to probe can be specified via the environment variable
STLINK_DEVICE on the format <USB_BUS>:<USB_ADDR>.
Expand All @@ -29,9 +29,6 @@ STLINK_DEVICE on the format <USB_BUS>:<USB_ADDR>.
\--serial
: Display the serial code of the device

\--hla-serial
: Display the hex escaped serial code of the device

\--flash
: Display amount of flash memory available in the device

Expand All @@ -53,8 +50,7 @@ Display information about connected programmers and devices

$ st-info --probe
Found 1 stlink programmers
serial: 303033413030323233343338353130323334333133393339
hla-serial: "\x30\x30\x33\x41\x30\x30\x32\x32\x33\x34\x33\x38\x35\x31\x30\x32\x33\x34\x33\x31\x33\x39\x33\x39"
serial: 57FF72067265575742132067
flash: 131072 (pagesize: 128)
sram: 20480
chipid: 0x0447
Expand Down
6 changes: 3 additions & 3 deletions inc/stlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ enum target_state {
#define STLINK_SWDCLK_15KHZ_DIVISOR 265
#define STLINK_SWDCLK_5KHZ_DIVISOR 798

#define STLINK_SERIAL_MAX_SIZE 64
#define STLINK_SERIAL_LENGTH 24
#define STLINK_SERIAL_BUFFER_SIZE (STLINK_SERIAL_LENGTH + 1)

#define STLINK_V3_MAX_FREQ_NB 10

Expand Down Expand Up @@ -191,8 +192,7 @@ struct _stlink {
uint32_t chip_id; // set by stlink_load_device_params(), used to identify flash and sram
enum target_state core_stat; // set by stlink_status()

char serial[STLINK_SERIAL_MAX_SIZE];
int serial_size;
char serial[STLINK_SERIAL_BUFFER_SIZE];
int freq; // set by stlink_open_usb(), values: STLINK_SWDCLK_xxx_DIVISOR

enum stlink_flash_type flash_type;
Expand Down
2 changes: 1 addition & 1 deletion src/st-flash/flash.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ enum flash_format {FLASH_FORMAT_BINARY = 0, FLASH_FORMAT_IHEX = 1};
enum flash_area {FLASH_MAIN_MEMORY = 0, FLASH_SYSTEM_MEMORY = 1, FLASH_OTP = 2, FLASH_OPTION_BYTES = 3, FLASH_OPTION_BYTES_BOOT_ADD = 4, FLASH_OPTCR = 5, FLASH_OPTCR1 = 6};
struct flash_opts {
enum flash_cmd cmd;
uint8_t serial[STLINK_SERIAL_MAX_SIZE];
uint8_t serial[STLINK_SERIAL_BUFFER_SIZE];
const char* filename;
stm32_addr_t addr;
size_t size;
Expand Down
12 changes: 1 addition & 11 deletions src/st-flash/flash_opts.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,18 +106,8 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) {
serial = av[0] + strlen("--serial=");
}

/** @todo This is not really portable, as strlen really returns size_t we need to obey
and not cast it to a signed type. */
int j = (int)strlen(serial);
int length = j / 2; // the length of the destination-array
memcpy(o->serial, serial, STLINK_SERIAL_BUFFER_SIZE);

if (j % 2 != 0) { return(-1); }

for (size_t k = 0; j >= 0 && k < sizeof(o->serial); ++k, j -= 2) {
char buffer[3] = {0};
memcpy(buffer, serial + j, 2);
o->serial[length - k] = (uint8_t)strtol(buffer, NULL, 16);
}
} else if (strcmp(av[0], "--area") == 0 || starts_with(av[0], "--area=")) {
const char * area;

Expand Down
28 changes: 2 additions & 26 deletions src/st-info/info.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,13 @@ static void usage(void) {
puts("st-info --version");
puts("st-info --probe");
puts("st-info --serial");
puts("st-info --hla-serial");
puts("st-info --flash [--connect-under-reset]");
puts("st-info --pagesize [--connect-under-reset]");
puts("st-info --sram [--connect-under-reset]");
puts("st-info --chipid [--connect-under-reset]");
puts("st-info --descr [--connect-under-reset]");
}

/* Print normal or OpenOCD hla_serial with newline */
static void stlink_print_serial(stlink_t *sl, bool openocd) {
const char *fmt;

if (openocd) {
printf("\"");
fmt = "\\x%02x";
} else {
fmt = "%02x";
}

for (int n = 0; n < sl->serial_size; n++) { printf(fmt, sl->serial[n]); }

if (openocd) { printf("\""); }

printf("\n");
}

static void stlink_print_version(stlink_t *sl) {
// Implementation of version printing is minimalistic
// but contains all available information from sl->version
Expand All @@ -53,10 +34,7 @@ static void stlink_print_info(stlink_t *sl) {

printf(" version: ");
stlink_print_version(sl);
printf(" serial: ");
stlink_print_serial(sl, false);
printf(" hla-serial: ");
stlink_print_serial(sl, true);
printf(" serial: %s\n", sl->serial);
printf(" flash: %u (pagesize: %u)\n",
(uint32_t)sl->flash_size, (uint32_t)sl->flash_pgsz);
printf(" sram: %u\n", (uint32_t)sl->sram_size);
Expand Down Expand Up @@ -131,9 +109,7 @@ static int print_data(int ac, char **av) {
if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); }

if (strcmp(av[1], "--serial") == 0) {
stlink_print_serial(sl, false);
} else if (strcmp(av[1], "--hla-serial") == 0) {
stlink_print_serial(sl, true);
printf("%s\n", sl->serial);
} else if (strcmp(av[1], "--flash") == 0) {
printf("0x%x\n", (uint32_t)sl->flash_size);
} else if (strcmp(av[1], "--pagesize") == 0) {
Expand Down
19 changes: 1 addition & 18 deletions src/st-trace/trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,25 +191,8 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) {
return true;
}

static void convert_serial_number_text_to_binary(const char* text, char binary_out[STLINK_SERIAL_MAX_SIZE]) {
size_t length = 0;
for (uint32_t n = 0; n < strlen(text) && length < STLINK_SERIAL_MAX_SIZE; n += 2) {
char buffer[3] = { 0 };
memcpy(buffer, text + n, 2);
binary_out[length++] = (uint8_t)strtol(buffer, NULL, 16);
}
}

static stlink_t* stlink_connect(const st_settings_t* settings) {
if (settings->serial_number) {
// Open this specific stlink.
char binary_serial_number[STLINK_SERIAL_MAX_SIZE] = { 0 };
convert_serial_number_text_to_binary(settings->serial_number, binary_serial_number);
return stlink_open_usb(settings->logging_level, false, binary_serial_number, 0);
} else {
// Otherwise, open any stlink.
return stlink_open_usb(settings->logging_level, false, NULL, 0);
}
return stlink_open_usb(settings->logging_level, false, settings->serial_number, 0);
}

static bool enable_trace(stlink_t* stlink, const st_settings_t* settings, uint32_t trace_frequency) {
Expand Down
17 changes: 2 additions & 15 deletions src/st-util/gdb-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
static stlink_t *connected_stlink = NULL;
static bool semihosting = false;
static bool serial_specified = false;
static char serialnumber[STLINK_SERIAL_MAX_SIZE] = {0};
static char serialnumber[STLINK_SERIAL_BUFFER_SIZE] = {0};

#if defined(_WIN32)
#define close_socket win32_close_socket
Expand Down Expand Up @@ -192,20 +192,7 @@ int parse_options(int argc, char** argv, st_state_t *st) {
break;
case SERIAL_OPTION:
printf("use serial %s\n", optarg);
/* TODO: This is not really portable, as strlen really returns size_t,
* we need to obey and not cast it to a signed type.
*/
int j = (int)strlen(optarg);
int length = j / 2; // the length of the destination-array

if (j % 2 != 0) { return(-1); }

for (size_t k = 0; j >= 0 && k < sizeof(serialnumber); ++k, j -= 2) {
char buffer[3] = {0};
memcpy(buffer, optarg + j, 2);
serialnumber[length - k] = (uint8_t)strtol(buffer, NULL, 16);
}

memcpy(serialnumber, optarg, STLINK_SERIAL_BUFFER_SIZE);
serial_specified = true;
break;
}
Expand Down
52 changes: 44 additions & 8 deletions src/stlink-lib/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1159,7 +1159,44 @@ static stlink_backend_t _stlink_usb_backend = {
_stlink_usb_read_trace
};

stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq) {
/* return the length of serial or (0) in case of errors */
size_t stlink_serial(struct libusb_device_handle *handle, struct libusb_device_descriptor *desc, char *serial) {
unsigned char desc_serial[(STLINK_SERIAL_LENGTH) * 2];

/* truncate the string in the serial buffer */
serial[0] = '\0';

/* get the LANGID from String Descriptor Zero */
int ret = libusb_get_string_descriptor(handle, 0, 0, desc_serial, sizeof(desc_serial));
if (ret < 4) return 0;

uint32_t langid = desc_serial[2] | (desc_serial[3] << 8);

/* get the serial */
ret = libusb_get_string_descriptor(handle, desc->iSerialNumber, langid, desc_serial,
sizeof(desc_serial));
if (ret < 0) return 0; // could not read serial

unsigned char len = desc_serial[0];

if (len == ((STLINK_SERIAL_LENGTH + 1) * 2)) { /* len == 50 */
/* good ST-Link adapter */
ret = libusb_get_string_descriptor_ascii(
handle, desc->iSerialNumber, (unsigned char *)serial, STLINK_SERIAL_BUFFER_SIZE);
if (ret < 0) return 0;
} else if (len == ((STLINK_SERIAL_LENGTH / 2 + 1) * 2)) { /* len == 26 */
/* fix-up the buggy serial */
for (unsigned int i = 0; i < STLINK_SERIAL_LENGTH; i += 2)
sprintf(serial + i, "%02X", desc_serial[i + 2]);
serial[STLINK_SERIAL_LENGTH] = '\0';
} else {
return 0;
}

return strlen(serial);
}

stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_BUFFER_SIZE], int freq) {
stlink_t* sl = NULL;
struct stlink_libusb* slu = NULL;
int ret = -1;
Expand Down Expand Up @@ -1236,15 +1273,14 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL

if (ret) { continue; } // could not open device

sl->serial_size = libusb_get_string_descriptor_ascii(
handle, desc.iSerialNumber, (unsigned char *)sl->serial, sizeof(sl->serial));
size_t serial_len = stlink_serial(handle, &desc, sl->serial);

libusb_close(handle);

if (sl->serial_size < 0) { continue; } // could not read serial
if (serial_len != STLINK_SERIAL_LENGTH) { continue; } // could not read the serial

// if no serial provided, or if serial match device, fixup version and protocol
if (((serial == NULL) || (*serial == 0)) || (memcmp(serial, &sl->serial, sl->serial_size) == 0)) {
if (((serial == NULL) || (*serial == 0)) || (memcmp(serial, &sl->serial, STLINK_SERIAL_LENGTH) == 0)) {
if (STLINK_V1_USB_PID(desc.idProduct)) {
slu->protocoll = 1;
sl->version.stlink_v = 1;
Expand Down Expand Up @@ -1433,7 +1469,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) {
if (!STLINK_SUPPORTED_USB_PID(desc.idProduct)) { continue; }

struct libusb_device_handle* handle;
char serial[STLINK_SERIAL_MAX_SIZE] = {0, };
char serial[STLINK_SERIAL_BUFFER_SIZE] = {0, };

ret = libusb_open(dev, &handle);

Expand All @@ -1447,11 +1483,11 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) {
break;
}

ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)&serial, sizeof(serial));
size_t serial_len = stlink_serial(handle, &desc, serial);

libusb_close(handle);

if (ret < 0) { continue; }
if (serial_len != STLINK_SERIAL_LENGTH) { continue; }

stlink_t *sl = stlink_open_usb(0, 1, serial, 0);

Expand Down
2 changes: 1 addition & 1 deletion src/stlink-lib/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ struct stlink_libusb {
* @retval NULL Error while opening the stlink
* @retval !NULL Stlink found and ready to use
*/
stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq);
stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_BUFFER_SIZE], int freq);
size_t stlink_probe_usb(stlink_t **stdevs[]);
void stlink_probe_usb_free(stlink_t **stdevs[], size_t size);

Expand Down

0 comments on commit 4f7deea

Please sign in to comment.