From d994565f2e95afe55a54ca51035a48b4bd8c8f92 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 31 Aug 2019 09:57:32 +0200 Subject: [PATCH 01/10] pc-stlinkv2: Fix crash with serial given not matching connected devices. --- src/platforms/pc-stlinkv2/stlinkv2.c | 70 ++++++++++++++-------------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/src/platforms/pc-stlinkv2/stlinkv2.c b/src/platforms/pc-stlinkv2/stlinkv2.c index f3de39e4..be691a62 100644 --- a/src/platforms/pc-stlinkv2/stlinkv2.c +++ b/src/platforms/pc-stlinkv2/stlinkv2.c @@ -683,7 +683,7 @@ void stlink_init(int argc, char **argv) goto error; } int i = 0; - bool multiple_devices = false; + int nr_stlinks = 0; while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; int r = libusb_get_device_descriptor(dev, &desc); @@ -699,10 +699,6 @@ void stlink_init(int argc, char **argv) DEBUG("STLINKV1 not supported\n"); continue; } - if (Stlink.handle) { - libusb_close(Stlink.handle); - multiple_devices = (serial)? false : true; - } r = libusb_open(dev, &Stlink.handle); if (r == LIBUSB_SUCCESS) { uint8_t data[32]; @@ -736,44 +732,50 @@ void stlink_init(int argc, char **argv) } if (serial && (!strncmp(Stlink.serial, serial, strlen(serial)))) DEBUG("Found "); - if (!serial || (!strncmp(Stlink.serial, serial, strlen(serial)))) { - if (desc.idProduct == PRODUCT_ID_STLINKV2) { - DEBUG("STLINKV20 serial %s\n", Stlink.serial); - Stlink.ver_hw = 20; - Stlink.ep_tx = 2; - } else if (desc.idProduct == PRODUCT_ID_STLINKV21) { - DEBUG("STLINKV21 serial %s\n", Stlink.serial); - Stlink.ver_hw = 21; - Stlink.ep_tx = 1; - } else if (desc.idProduct == PRODUCT_ID_STLINKV21_MSD) { - DEBUG("STLINKV21_MSD serial %s\n", Stlink.serial); - Stlink.ver_hw = 21; - Stlink.ep_tx = 1; - } else if (desc.idProduct == PRODUCT_ID_STLINKV3E) { - DEBUG("STLINKV3E serial %s\n", Stlink.serial); - Stlink.ver_hw = 30; - Stlink.ep_tx = 1; - } else if (desc.idProduct == PRODUCT_ID_STLINKV3) { - DEBUG("STLINKV3 serial %s\n", Stlink.serial); - Stlink.ver_hw = 30; - Stlink.ep_tx = 1; + if (desc.idProduct == PRODUCT_ID_STLINKV2) { + DEBUG("STLINKV20 serial %s\n", Stlink.serial); + Stlink.ver_hw = 20; + Stlink.ep_tx = 2; + } else if (desc.idProduct == PRODUCT_ID_STLINKV21) { + DEBUG("STLINKV21 serial %s\n", Stlink.serial); + Stlink.ver_hw = 21; + Stlink.ep_tx = 1; + } else if (desc.idProduct == PRODUCT_ID_STLINKV21_MSD) { + DEBUG("STLINKV21_MSD serial %s\n", Stlink.serial); + Stlink.ver_hw = 21; + Stlink.ep_tx = 1; + } else if (desc.idProduct == PRODUCT_ID_STLINKV3E) { + DEBUG("STLINKV3E serial %s\n", Stlink.serial); + Stlink.ver_hw = 30; + Stlink.ep_tx = 1; + } else if (desc.idProduct == PRODUCT_ID_STLINKV3) { + DEBUG("STLINKV3 serial %s\n", Stlink.serial); + Stlink.ver_hw = 30; + Stlink.ep_tx = 1; + } else { + DEBUG("Unknown STLINK variant, serial %s\n", Stlink.serial); + } + nr_stlinks++; + if (serial) { + if (!strncmp(Stlink.serial, serial, strlen(serial))) { + break; } else { - DEBUG("Unknown STLINK variant, serial %s\n", Stlink.serial); + libusb_close(Stlink.handle); + Stlink.handle = 0; } } - if (serial && (!strncmp(Stlink.serial, serial, strlen(serial)))) - break; } else { DEBUG("Open failed %s\n", libusb_strerror(r)); } } } - if (multiple_devices) { - DEBUG("Multiple Stlinks. Please specify serial number\n"); - goto error_1; - } if (!Stlink.handle) { - DEBUG("No Stlink device found!\n"); + if (nr_stlinks && serial) + DEBUG("No Stlink with given serial number %s\n", serial); + else if (nr_stlinks > 1) + DEBUG("Multiple Stlinks. Please specify serial number\n"); + else + DEBUG("No Stlink device found!\n"); goto error; } int config; From a01109543e7e2ca3f8c58c74cda420d0f1454da5 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 28 Aug 2019 16:04:00 +0200 Subject: [PATCH 02/10] pc-stlinkv2: Return failure if STLINK_DEBUG_APIV2_INIT_AP fails. --- src/platforms/pc-stlinkv2/stlinkv2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/platforms/pc-stlinkv2/stlinkv2.c b/src/platforms/pc-stlinkv2/stlinkv2.c index be691a62..9c13bc00 100644 --- a/src/platforms/pc-stlinkv2/stlinkv2.c +++ b/src/platforms/pc-stlinkv2/stlinkv2.c @@ -1079,8 +1079,7 @@ bool adiv5_ap_setup(int ap) uint8_t data[2]; send_recv_retry(cmd, 16, data, 2); DEBUG_STLINK("Open AP %d\n", ap); - stlink_usb_error_check(data, true); - return true; + return (stlink_usb_error_check(data, true))? false: true; } void adiv5_ap_cleanup(int ap) From aef055bb6f3ca74af15774cad976b2d3b463b1f3 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 28 Aug 2019 15:43:47 +0200 Subject: [PATCH 03/10] adiv5: If setup AP0 fails, fail immediate. --- src/target/adiv5.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/target/adiv5.c b/src/target/adiv5.c index 0e507c16..66c45a9d 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -491,7 +491,10 @@ void adiv5_dp_init(ADIv5_DP_t *dp) ap = adiv5_new_ap(dp, i); if (ap == NULL) { adiv5_ap_cleanup(i); - continue; + if (i == 0) + return; + else + continue; } extern void kinetis_mdm_probe(ADIv5_AP_t *); kinetis_mdm_probe(ap); From 0d61106f9005a821b351b9c5f4bba12395851692 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 28 Aug 2019 17:31:25 +0200 Subject: [PATCH 04/10] pc-stlinkv2: Remove redundant read of CoreID. --- src/platforms/pc-stlinkv2/stlinkv2.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/platforms/pc-stlinkv2/stlinkv2.c b/src/platforms/pc-stlinkv2/stlinkv2.c index 9c13bc00..98e04f64 100644 --- a/src/platforms/pc-stlinkv2/stlinkv2.c +++ b/src/platforms/pc-stlinkv2/stlinkv2.c @@ -900,14 +900,8 @@ int stlink_enter_debug_swd(void) STLINK_DEBUG_ENTER_SWD_NO_RESET}; uint8_t data[2]; DEBUG("Enter SWD\n"); - if (send_recv_retry(cmd, 16, data, 2) != STLINK_ERROR_OK) - return -1; - uint8_t cmd1[16] = {STLINK_DEBUG_COMMAND, - STLINK_DEBUG_READCOREID}; - uint8_t data1[4]; - send_recv(cmd1, 16, data1, 4); - stlink_usb_error_check(data, false); - return 0; + send_recv(cmd, 16, data, 2); + return stlink_usb_error_check(data, true); } int stlink_enter_debug_jtag(void) From d1ee827b4df710a0f693f6df7808cb5d75b2530c Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 28 Aug 2019 20:45:39 +0200 Subject: [PATCH 05/10] pc-stlinkv2: STLINK_SWD_DP_ERROR seem unrecoverable. Throw exception. --- src/platforms/pc-stlinkv2/stlinkv2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/platforms/pc-stlinkv2/stlinkv2.c b/src/platforms/pc-stlinkv2/stlinkv2.c index 98e04f64..f7aeb4cc 100644 --- a/src/platforms/pc-stlinkv2/stlinkv2.c +++ b/src/platforms/pc-stlinkv2/stlinkv2.c @@ -440,6 +440,7 @@ static int stlink_usb_error_check(uint8_t *data, bool verbose) case STLINK_SWD_DP_ERROR: if (verbose) DEBUG("STLINK_SWD_DP_ERROR\n"); + raise_exception(EXCEPTION_ERROR, "STLINK_SWD_DP_ERROR"); return STLINK_ERROR_FAIL; case STLINK_SWD_DP_PARITY_ERROR: if (verbose) @@ -487,7 +488,7 @@ static int send_recv_retry(uint8_t *txbuf, size_t txsize, gettimeofday(&now, NULL); timersub(&now, &start, &diff); if ((diff.tv_sec >= 1) || (res != STLINK_ERROR_WAIT)) { - DEBUG_STLINK("Failed: "); + DEBUG("write_retry failed"); return res; } } @@ -510,7 +511,7 @@ static int read_retry(uint8_t *txbuf, size_t txsize, gettimeofday(&now, NULL); timersub(&now, &start, &diff); if ((diff.tv_sec >= 1) || (res != STLINK_ERROR_WAIT)) { - DEBUG_STLINK("Failed: "); + DEBUG("read_retry failed"); return res; } } @@ -534,7 +535,6 @@ static int write_retry(uint8_t *cmdbuf, size_t cmdsize, gettimeofday(&now, NULL); timersub(&now, &start, &diff); if ((diff.tv_sec >= 1) || (res != STLINK_ERROR_WAIT)) { - DEBUG_STLINK("failed"); return res; } } From d39dc343827a2c4f2c64f7b76ddf42806812fae4 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 28 Aug 2019 20:28:25 +0200 Subject: [PATCH 06/10] pc-stlinkv2: Fix reg_read|write - Fix wrong placed brace in cortexm_regs_write() - Start writing with r0 - With register read, save only registers listed --- src/target/cortexm.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/target/cortexm.c b/src/target/cortexm.c index 882022d1..a67b5994 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -451,17 +451,18 @@ static void cortexm_regs_read(target *t, void *data) { uint32_t *regs = data; ADIv5_AP_t *ap = cortexm_ap(t); + unsigned i; #if defined(STLINKV2) + uint32_t base_regs[21]; extern void stlink_regs_read(ADIv5_AP_t *ap, void *data); extern uint32_t stlink_reg_read(ADIv5_AP_t *ap, int idx); - stlink_regs_read(ap, data); - regs += sizeof(regnum_cortex_m); + stlink_regs_read(ap, base_regs); + for(i = 0; i < sizeof(regnum_cortex_m) / 4; i++) + *regs++ = base_regs[regnum_cortex_m[i]]; if (t->target_options & TOPT_FLAVOUR_V7MF) for(size_t t = 0; t < sizeof(regnum_cortex_mf) / 4; t++) *regs++ = stlink_reg_read(ap, regnum_cortex_mf[t]); #else - unsigned i; - /* FIXME: Describe what's really going on here */ adiv5_ap_write(ap, ADIV5_AP_CSW, ap->csw | ADIV5_AP_CSW_SIZE_WORD); @@ -494,14 +495,14 @@ static void cortexm_regs_write(target *t, const void *data) ADIv5_AP_t *ap = cortexm_ap(t); #if defined(STLINKV2) extern void stlink_reg_write(ADIv5_AP_t *ap, int num, uint32_t val); - for(size_t z = 1; z < sizeof(regnum_cortex_m) / 4; z++) { + for(size_t z = 0; z < sizeof(regnum_cortex_m) / 4; z++) { stlink_reg_write(ap, regnum_cortex_m[z], *regs); regs++; + } if (t->target_options & TOPT_FLAVOUR_V7MF) for(size_t z = 0; z < sizeof(regnum_cortex_mf) / 4; z++) { stlink_reg_write(ap, regnum_cortex_mf[z], *regs); regs++; - } } #else unsigned i; From 80a9fd51ca0c904ed689aaf2fe1467dc8f474613 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 29 Aug 2019 13:35:20 +0200 Subject: [PATCH 07/10] Clarify STM32F103x8 Flashsize handling. Should finally fix #471. --- src/platforms/stlink/Flashsize_F103 | 51 ++++++++++++++--------------- upgrade/Makefile | 2 +- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/platforms/stlink/Flashsize_F103 b/src/platforms/stlink/Flashsize_F103 index c6b55a24..24047b5a 100644 --- a/src/platforms/stlink/Flashsize_F103 +++ b/src/platforms/stlink/Flashsize_F103 @@ -20,34 +20,31 @@ This flash may have been tested bad, or not have been tested at all, or, in the best case, was tested good but market requirements made STM sell it as F103C8. -Ignoring the chip marking and using an F103C8 blindly as a F103Cb is done -already with few problems on many china boards (e.g. blue pill). Probably -this second approach will work for many of the older STLinks. - -dfu-util cares for the size and refuses to programm above the announced size: - > dfu-util -S E4D078EA -s 0x08002000:leave -D blackmagic.bin - dfu-util 0.9 - ... - dfu-util: Last page at 0x0801093f is not writeable +Ignoring the chip marking and using an F103C8 blindly as a F103CB is done +already with no known problems on many STM board and china boards (e.g. blue +pill) with genuine STM32. China stlinks clones with a GD32F103x8 will +probably not work. Best is to get new genuine ST hardware. The +STLINK-Vmini is < 10 $ without VAT or to resolder a genuine +STM32F103CB chip. Think also about using the pc-hosted pc-stlinkv2 +platform on stlinks with revent firmware. Flash above the announced size with recent bootloader/BMP: ========================================================== -script/stm32_mem.py does not care for the announced size: + +Use either the provided python tool, as script/stm32_mem.py +does not care for the announced size and verifies: + > ../scripts/stm32_mem.py blackmagic.bin - ... - USB Device Firmware Upgrade - Host Utility -- version 1.2 - ... - Programming memory at 0x08010800 - All operations complete! - -Get length of binary - > ls -l blackmagic.bin - -rwxr-xr-x 1 bon users 59712 21. Sep 22:47 blackmagic.bin -Actual file size may differ! - -Upload binary from flash with the exact size - > dfu-util -s 0x08002000:leave:force:59712 -U blackmagic.bin.1 - -Compare - > diff blackmagic.bin* -No differences should get reported! + +or compile and use the upgrade executable. + +> cd upgrade +> make (PROBE_HOST=...) +> ./blackmagic_upgrade + +To long to read +=============== +Use the BMP provided upgrade tools: +- scripts/stm32_mem.py +- Compiled upgrade tool in upgrade +Only if mismatch is reported, think further. diff --git a/upgrade/Makefile b/upgrade/Makefile index 17d898ed..9f7285d1 100644 --- a/upgrade/Makefile +++ b/upgrade/Makefile @@ -36,7 +36,7 @@ endif bindata.o: $(PROBE_HOST).d -$(PROBE_HOST).d: ../src/blackmagic.bin +$(PROBE_HOST).d: $(wildcard ../src/blackmagic.bin) -rm *.d make -C ../src $0 clean make -C ../src $0 From 86d0be97081b4e394fdd82d665a3b5c4ad3eba00 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 31 Aug 2019 17:08:14 +0200 Subject: [PATCH 08/10] pc-hosted: Display morse message on controlling terminal. --- src/morse.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/morse.c b/src/morse.c index 6b17c16b..55db0ba0 100644 --- a/src/morse.c +++ b/src/morse.c @@ -59,8 +59,14 @@ static char morse_repeat; void morse(const char *msg, char repeat) { - morse_msg = morse_ptr = msg; +#if defined(PC_HOSTED) + if (msg) + DEBUG("%s\n", msg); + (void) repeat; +#else +morse_msg = morse_ptr = msg; morse_repeat = repeat; +#endif } bool morse_update(void) From 6f1cae9203004e3bd91357e56b7ffddce2ce0884 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 31 Aug 2019 12:32:23 +0200 Subject: [PATCH 09/10] pc-stlinkv2: Wait for device attach. --- src/platforms/pc-stlinkv2/stlinkv2.c | 67 +++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 7 deletions(-) diff --git a/src/platforms/pc-stlinkv2/stlinkv2.c b/src/platforms/pc-stlinkv2/stlinkv2.c index f7aeb4cc..441a5f2a 100644 --- a/src/platforms/pc-stlinkv2/stlinkv2.c +++ b/src/platforms/pc-stlinkv2/stlinkv2.c @@ -245,6 +245,19 @@ struct trans_ctx { }; int debug_level = 0; +bool has_attached = false; + +static int LIBUSB_CALL hotplug_callback_attach( + libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, + void *user_data) +{ + (void)ctx; + (void)dev; + (void)event; + (void)user_data; + has_attached = true; + return 0; +} static void LIBUSB_CALL on_trans_done(struct libusb_transfer * trans) { @@ -645,6 +658,7 @@ void stlink_help(char **argv) DEBUG("\t-v[1|2]\t\t: Increasing verbosity\n"); DEBUG("\t-s \"string\"\t: Use Stlink with (partial) " "serial number \"string\"\n"); + DEBUG("\t-n\t\t: Exit immediate if no device found\n"); DEBUG("\t-h\t\t: This help.\n"); exit(0); } @@ -659,8 +673,12 @@ void stlink_init(int argc, char **argv) libusb_init(&Stlink.libusb_ctx); char *serial = NULL; int c; - while((c = getopt(argc, argv, "s:v:h")) != -1) { + bool wait_for_attach = true; + while((c = getopt(argc, argv, "ns:v:h")) != -1) { switch(c) { + case 'n': + wait_for_attach = false; + break; case 's': serial = optarg; break; @@ -676,9 +694,17 @@ void stlink_init(int argc, char **argv) r = libusb_init(NULL); if (r < 0) DEBUG("Failed: %s", libusb_strerror(r)); - ssize_t cnt = libusb_get_device_list(NULL, &devs); + bool hotplug = true; + if (!libusb_has_capability (LIBUSB_CAP_HAS_HOTPLUG)) { + printf("Hotplug capabilites are not supported on this platform\n"); + hotplug = false; + } + ssize_t cnt; + rescan: + has_attached = 0; + memset(&Stlink, 0, sizeof(Stlink)); + cnt = libusb_get_device_list(NULL, &devs); if (cnt < 0) { - libusb_exit(NULL); DEBUG("Failed: %s", libusb_strerror(r)); goto error; } @@ -769,13 +795,40 @@ void stlink_init(int argc, char **argv) } } } + libusb_free_device_list(devs, 1); if (!Stlink.handle) { - if (nr_stlinks && serial) + if (nr_stlinks && serial) { DEBUG("No Stlink with given serial number %s\n", serial); - else if (nr_stlinks > 1) + } else if (nr_stlinks > 1) { DEBUG("Multiple Stlinks. Please specify serial number\n"); - else + goto error; + } else { DEBUG("No Stlink device found!\n"); + } + if (hotplug && wait_for_attach) { + libusb_hotplug_callback_handle hp; + int rc = libusb_hotplug_register_callback + (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, 0, + VENDOR_ID_STLINK, LIBUSB_HOTPLUG_MATCH_ANY, + LIBUSB_HOTPLUG_MATCH_ANY, + hotplug_callback_attach, NULL, &hp); + if (LIBUSB_SUCCESS != rc) { + DEBUG("Error registering attach callback\n"); + goto error; + } + DEBUG("Waiting for %sST device%s%s to attach\n", + (serial)? "" : "some ", + (serial)? " with serial ": "", + (serial)? serial: ""); + DEBUG("Terminate with ^C\n"); + while (has_attached == 0) { + rc = libusb_handle_events (NULL); + if (rc < 0) + printf("libusb_handle_events() failed: %s\n", + libusb_error_name(rc)); + } + goto rescan; + } goto error; } int config; @@ -829,7 +882,7 @@ void stlink_init(int argc, char **argv) error_1: libusb_close(Stlink.handle); error: - libusb_free_device_list(devs, 1); + libusb_exit(Stlink.libusb_ctx); exit(-1); } From 1d868bfffbfd38fe4d5e3f75213bfb23e6ea3321 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 31 Aug 2019 15:27:16 +0200 Subject: [PATCH 10/10] pc-stlinkv2: Detect stlink detach. As libusb has no real async callback, we need to call libusb_handle_events() in different places. While waiting for the gdb connection, we set the socket to non-blocking and check additional for usb events in that loop. That way, detach is also detected while waiting for connection. With debugger attached, SET_IDLE_STATE ist missused for checking for usb events. --- src/platforms/pc-stlinkv2/platform.h | 3 +- src/platforms/pc-stlinkv2/stlinkv2.c | 44 ++++++++++++++++++++++++++-- src/platforms/pc/gdb_if.c | 29 +++++++++++++++++- 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/src/platforms/pc-stlinkv2/platform.h b/src/platforms/pc-stlinkv2/platform.h index a100a063..7db112d4 100644 --- a/src/platforms/pc-stlinkv2/platform.h +++ b/src/platforms/pc-stlinkv2/platform.h @@ -37,7 +37,8 @@ #define PLATFORM_IDENT "StlinkV2/3" #define SET_RUN_STATE(state) -#define SET_IDLE_STATE(state) +void stlink_check_detach(int state); +#define SET_IDLE_STATE(state) stlink_check_detach(state) //#define SET_ERROR_STATE(state) void platform_buffer_flush(void); diff --git a/src/platforms/pc-stlinkv2/stlinkv2.c b/src/platforms/pc-stlinkv2/stlinkv2.c index 441a5f2a..86c7a1ec 100644 --- a/src/platforms/pc-stlinkv2/stlinkv2.c +++ b/src/platforms/pc-stlinkv2/stlinkv2.c @@ -228,7 +228,7 @@ stlink Stlink; static void exit_function(void) { libusb_exit(NULL); - DEBUG_STLINK("Cleanup\n"); + DEBUG("\nCleanup\n"); } /* SIGTERM handler. */ @@ -256,7 +256,34 @@ static int LIBUSB_CALL hotplug_callback_attach( (void)event; (void)user_data; has_attached = true; - return 0; + return 1; /* deregister Callback*/ +} + +int device_detached = 0; +static int LIBUSB_CALL hotplug_callback_detach( + libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, + void *user_data) +{ + (void)ctx; + (void)dev; + (void)event; + (void)user_data; + device_detached = 1; + return 1; /* deregister Callback*/ +} + +void stlink_check_detach(int state) +{ + if (state == 1) { + /* Check for hotplug events */ + struct timeval tv = {0,0}; + libusb_handle_events_timeout_completed( + Stlink.libusb_ctx, &tv, &device_detached); + if (device_detached) { + DEBUG("Dongle was detached\n"); + exit(0); + } + } } static void LIBUSB_CALL on_trans_done(struct libusb_transfer * trans) @@ -332,6 +359,7 @@ static int send_recv(uint8_t *txbuf, size_t txsize, uint8_t *rxbuf, size_t rxsize) { int res = 0; + stlink_check_detach(1); if( txsize) { int txlen = txsize; libusb_fill_bulk_transfer(Stlink.req_trans, Stlink.handle, @@ -725,6 +753,8 @@ void stlink_init(int argc, char **argv) DEBUG("STLINKV1 not supported\n"); continue; } + Stlink.vid = desc.idVendor; + Stlink.pid = desc.idProduct; r = libusb_open(dev, &Stlink.handle); if (r == LIBUSB_SUCCESS) { uint8_t data[32]; @@ -852,6 +882,16 @@ void stlink_init(int argc, char **argv) DEBUG("libusb_claim_interface failed %s\n", libusb_strerror(r)); goto error_1; } + if (hotplug) { /* Allow gracefully exit when stlink is unplugged*/ + libusb_hotplug_callback_handle hp; + int rc = libusb_hotplug_register_callback + (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, Stlink.vid, Stlink.pid, + LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback_detach, NULL, &hp); + if (LIBUSB_SUCCESS != rc) { + DEBUG("Error registering detach callback\n"); + goto error; + } + } Stlink.req_trans = libusb_alloc_transfer(0); Stlink.rep_trans = libusb_alloc_transfer(0); stlink_version(); diff --git a/src/platforms/pc/gdb_if.c b/src/platforms/pc/gdb_if.c index 5da42da4..b5583b6f 100644 --- a/src/platforms/pc/gdb_if.c +++ b/src/platforms/pc/gdb_if.c @@ -32,6 +32,7 @@ # include # include # include +# include #endif #include @@ -100,7 +101,33 @@ unsigned char gdb_if_getchar(void) while(i <= 0) { if(gdb_if_conn <= 0) { - gdb_if_conn = accept(gdb_if_serv, NULL, NULL); +#if defined(_WIN32) || defined(__CYGWIN__) + unsigned long opt = 1; + ioctlsocket(gdb_if_serv, FIONBIO, &opt); +#else + int flags = fcntl(gdb_if_serv, F_GETFL); + fcntl(gdb_if_serv, F_SETFL, flags | O_NONBLOCK); +#endif + while(1) { + gdb_if_conn = accept(gdb_if_serv, NULL, NULL); + if (gdb_if_conn == -1) { + if (errno == EWOULDBLOCK) { + SET_IDLE_STATE(1); + platform_delay(100); + } else { + DEBUG("error when accepting connection"); + exit(1); + } + } else { +#if defined(_WIN32) || defined(__CYGWIN__) + unsigned long opt = 0; + ioctlsocket(gdb_if_serv, FIONBIO, &opt); +#else + fcntl(gdb_if_serv, F_SETFL, flags); +#endif + break; + } + } DEBUG("Got connection\n"); } i = recv(gdb_if_conn, (void*)&ret, 1, 0);