Merge pull request #391 from xor-gate/st-probe

st-probe: Initial working stlink_probe_* API and CLI tool
pull/392/head
texane 2016-04-06 17:43:55 +02:00
commit 9c5c2a0803
7 zmienionych plików z 164 dodań i 14 usunięć

Wyświetl plik

@ -16,3 +16,4 @@ marpe@mimuw.edu.pl
marco.cassinerio@gmail.com
jserv@0xlab.org
michael@pratt.im
jerry.jacobs@xor-gate.org

Wyświetl plik

@ -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)

Wyświetl plik

@ -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

45
src/st-probe.c 100644
Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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
}