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.
This commit is contained in:
parent
6f1cae9203
commit
1d868bfffb
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
# include <netinet/in.h>
|
||||
# include <netinet/tcp.h>
|
||||
# include <sys/select.h>
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -100,7 +101,33 @@ unsigned char gdb_if_getchar(void)
|
|||
|
||||
while(i <= 0) {
|
||||
if(gdb_if_conn <= 0) {
|
||||
#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);
|
||||
|
|
Loading…
Reference in New Issue