Skip to content

Commit

Permalink
fix for stlink old DFU serial number
Browse files Browse the repository at this point in the history
omit the hla serial aka 'openocd serial'
Only one valid serial is used which matches the serial as displayed
in STM32CubeProgrammer and official ST tools.

Signed-off-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com>
  • Loading branch information
tarek-bochkati committed Mar 18, 2021
1 parent 9956bde commit 98e16d6
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 (-1) in case of errors */
int 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 -1;

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 -1; // 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 -1;
} 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 -1;
}

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));
int 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));
int 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 98e16d6

Please sign in to comment.