st-probe: Initial working stlink_probe_* API and CLI tool
authorJerry Jacobs <jerry.jacobs@dualinventive.com>
Wed, 6 Apr 2016 12:35:57 +0000 (14:35 +0200)
committerJerry Jacobs <jerry.jacobs@dualinventive.com>
Wed, 6 Apr 2016 12:58:51 +0000 (14:58 +0200)
AUTHORS
CMakeLists.txt
Makefile.am
src/st-probe.c [new file with mode: 0644]
src/stlink-common.h
src/stlink-usb.c
src/stlink-usb.h

diff --git a/AUTHORS b/AUTHORS
index 5c52c64f37302996741464b1769429188ca031d2..aae9e296357e9681c3e17d9fe723bd8df7e2015d 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -16,3 +16,4 @@ marpe@mimuw.edu.pl
 marco.cassinerio@gmail.com
 jserv@0xlab.org
 michael@pratt.im
+jerry.jacobs@xor-gate.org
index 6f5be17ffc183334434a7306177736831766e578..247e515a9e9209996b645c3ff1c0f81a68a50368 100644 (file)
@@ -41,7 +41,10 @@ target_link_libraries(st-util stlink)
 add_executable(st-info src/st-info.c)
 target_link_libraries(st-info stlink)
 
-install(TARGETS  stlink st-flash st-util st-info
+add_executable(st-probe src/st-probe.c)
+target_link_libraries(st-probe stlink)
+
+install(TARGETS  stlink st-flash st-util st-info st-probe
         RUNTIME DESTINATION bin
         ARCHIVE DESTINATION lib)
 
index 2ddbf475dc89ea77bab6147ee6577fb037a7165b..9a0b387e21085eb2227f86383aa6fa7c3f40bb8a 100644 (file)
@@ -5,9 +5,9 @@ SUBDIRS = . $(MAYBE_GUI)
 AUTOMAKE_OPTIONS = subdir-objects
 
 if MINGW
-bin_PROGRAMS = st-flash st-util st-info
+bin_PROGRAMS = st-flash st-util st-info st-probe
 else
-bin_PROGRAMS = st-flash st-util st-term st-info
+bin_PROGRAMS = st-flash st-util st-term st-info st-probe
 endif
 
 noinst_LIBRARIES      = libstlink.a
@@ -15,6 +15,7 @@ noinst_LIBRARIES      = libstlink.a
 st_flash_SOURCES = flash/main.c
 st_term_SOURCES = src/st-term.c
 st_info_SOURCES = src/st-info.c
+st_probe_SOURCES = src/st-probe.c
 st_util_SOURCES = gdbserver/gdb-remote.c gdbserver/gdb-remote.h gdbserver/gdb-server.c mingw/mingw.c mingw/mingw.h
 
 CFILES = \
@@ -52,6 +53,7 @@ st_term_CPPFLAGS        = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(t
 st_info_LDADD   =       libstlink.a
 st_info_CPPFLAGS        = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw
 
+st_probe_LDADD   =       libstlink.a
+st_probe_CPPFLAGS       = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw
 
 EXTRA_DIST = autogen.sh
-
diff --git a/src/st-probe.c b/src/st-probe.c
new file mode 100644 (file)
index 0000000..f5cf3d8
--- /dev/null
@@ -0,0 +1,45 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include "stlink-common.h"
+
+void stlink_print_info(stlink_t *sl)
+{
+       const chip_params_t *params = NULL;
+
+       for (size_t n = 0; n < sizeof(sl->serial); n++)
+               printf("%02x", sl->serial[n]);
+       printf("\n");
+
+       printf("\t flash: %zu (pagesize: %zu)\n", sl->flash_size, sl->flash_pgsz);
+       printf("\t  sram: %zu\n",       sl->sram_size);
+       printf("\tchipid: 0x%.4x\n",    sl->chip_id);
+
+       for (size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) {
+               if(devices[i].chip_id == sl->chip_id) {
+                       params = &devices[i];
+                       break;
+               }
+       }
+
+       if (params)
+               printf("\t descr: %s\n", params->description);
+}
+
+int main(void)
+{
+       stlink_t **stdevs;
+       size_t size;
+
+       size = stlink_probe_usb(&stdevs);
+
+       printf("Found %zu stlink programmers\n", size);
+
+       for (size_t n = 0; n < size; n++)
+               stlink_print_info(stdevs[n]);
+
+       stlink_probe_usb_free(&stdevs, size);
+
+       return EXIT_SUCCESS;
+}
index 448d01a56b5bfac2a23e047bc2aee4c9c9f30d1c..2b2d09b1a32417949a91ab765b99ad7cffdb0eb1 100644 (file)
@@ -641,6 +641,8 @@ extern "C" {
         uint32_t chip_id;
         int core_stat;
 
+        char serial[13];
+
 #define STM32_FLASH_PGSZ 1024
 #define STM32L_FLASH_PGSZ 256
 
index b0ee00bed4da904fa4111d9947b998ad21c0e88a..ab555785c27ac4b1cf68afacfae9fabe3e6073b3 100644 (file)
@@ -363,7 +363,7 @@ int _stlink_usb_reset(stlink_t * sl) {
         return size;
     }
 
-       return 0;
+    return 0;
 }
 
 
@@ -718,12 +718,10 @@ stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial) {
     int error = -1;
     int config;
 
-    sl = malloc(sizeof (stlink_t));
-    slu = malloc(sizeof (struct stlink_libusb));
+    sl = calloc(1, sizeof (stlink_t));
+    slu = calloc(1, sizeof (struct stlink_libusb));
     if (sl == NULL) goto on_malloc_error;
     if (slu == NULL) goto on_malloc_error;
-    memset(sl, 0, sizeof (stlink_t));
-    memset(slu, 0, sizeof (struct stlink_libusb));
 
     ugly_init(verbose);
     sl->backend = &_stlink_usb_backend;
@@ -760,12 +758,11 @@ stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial) {
             if ((libusb_get_bus_number(list[cnt])!=devBus) || (libusb_get_device_address(list[cnt])!=devAddr)) continue;
         if ( (desc.idProduct == USB_STLINK_32L_PID) || (desc.idProduct == USB_STLINK_NUCLEO_PID) ){
             if ((p_usb_iserial != NULL)){
-                unsigned char buffer[13];
                 struct libusb_device_handle* handle;
                 libusb_open(list[cnt], &handle);
-                libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, buffer, 13);
+                libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)sl->serial, sizeof(sl->serial));
                 libusb_close(handle);
-                if (memcmp(p_usb_iserial,&buffer,12) == 0){
+                if (memcmp(p_usb_iserial,&sl->serial, sizeof(sl->serial) - 1) == 0){
                     break;
                 }else{
                     continue;
@@ -787,7 +784,7 @@ stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial) {
         int error = libusb_open(list[cnt], &slu->usb_handle);
         if( error !=0 ) {
             WLOG("Error %d (%s) opening ST-Link/V2 device %03d:%03d\n", 
-               error, strerror (errno), libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt]));
+        error, strerror (errno), libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt]));
             goto on_error;
         }
     }
@@ -873,3 +870,102 @@ on_malloc_error:
     return NULL;
 }
 
+static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) {
+    stlink_t **_sldevs;
+    libusb_device *dev;
+    int i = 0;
+    size_t slcnt = 0;
+    size_t slcur = 0;
+
+    /* Count stlink */
+    while ((dev = devs[i++]) != NULL) {
+        struct libusb_device_descriptor desc;
+        int r = libusb_get_device_descriptor(dev, &desc);
+        if (r < 0) {
+            fprintf(stderr, "failed to get device descriptor");
+            break;
+        }
+
+        if (desc.idProduct != USB_STLINK_32L_PID &&
+            desc.idProduct != USB_STLINK_NUCLEO_PID)
+            continue;
+
+        slcnt++;
+    }
+
+    /* Allocate list of pointers */
+    _sldevs = calloc(slcnt, sizeof(stlink_t *));
+    if (!_sldevs) {
+        *sldevs = NULL;
+        return 0;
+    }
+
+    /* Open stlinks and attach to list */
+    i = 0;
+    while ((dev = devs[i++]) != NULL) {
+        struct libusb_device_descriptor desc;
+        int r = libusb_get_device_descriptor(dev, &desc);
+        if (r < 0) {
+            fprintf(stderr, "failed to get device descriptor");
+            break;
+        }
+
+        if (desc.idProduct != USB_STLINK_32L_PID &&
+            desc.idProduct != USB_STLINK_NUCLEO_PID)
+            continue;
+
+        struct libusb_device_handle* handle;
+        char serial[13];
+        memset(serial, 0, sizeof(serial));
+
+        libusb_open(dev, &handle);
+        libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)&serial, sizeof(serial));
+        libusb_close(handle);
+
+        stlink_t *sl = NULL;
+        sl = stlink_open_usb(0, 1, serial);
+        if (!sl)
+            continue;
+
+        _sldevs[slcur] = sl;
+        slcur++;
+    }
+
+    *sldevs = _sldevs;
+    return slcnt;
+}
+
+size_t stlink_probe_usb(stlink_t **stdevs[]) {
+    libusb_device **devs;
+    stlink_t **sldevs;
+
+    size_t slcnt = 0;
+    int r;
+    ssize_t cnt;
+
+    r = libusb_init(NULL);
+    if (r < 0)
+        return 0;
+
+    cnt = libusb_get_device_list(NULL, &devs);
+    if (cnt < 0)
+        return 0;
+
+    slcnt = stlink_probe_usb_devs(devs, &sldevs);
+    libusb_free_device_list(devs, 1);
+
+    libusb_exit(NULL);
+
+    *stdevs = sldevs;
+    return slcnt;
+}
+
+void stlink_probe_usb_free(stlink_t ***stdevs, size_t size) {
+    if (stdevs == NULL || *stdevs == NULL || size == 0)
+        return;
+
+    for (size_t n = 0; n < size; n++)
+        stlink_close((*stdevs)[n]);
+    free(*stdevs);
+    *stdevs = NULL;
+}
index 938c07bcbf985a78e747fc98fb3c0c299368fcda..801cafad3232b9f333b9fec5ac2e453584d74183 100644 (file)
@@ -29,7 +29,8 @@ extern "C" {
     };
 
     stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial);
-
+    size_t stlink_probe_usb(stlink_t **stdevs[]);
+    void stlink_probe_usb_free(stlink_t **stdevs[], size_t size);
 
 #ifdef __cplusplus
 }