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 PLATFORM_IDENT "StlinkV2/3"
|
||||||
#define SET_RUN_STATE(state)
|
#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)
|
//#define SET_ERROR_STATE(state)
|
||||||
|
|
||||||
void platform_buffer_flush(void);
|
void platform_buffer_flush(void);
|
||||||
|
@ -228,7 +228,7 @@ stlink Stlink;
|
|||||||
static void exit_function(void)
|
static void exit_function(void)
|
||||||
{
|
{
|
||||||
libusb_exit(NULL);
|
libusb_exit(NULL);
|
||||||
DEBUG_STLINK("Cleanup\n");
|
DEBUG("\nCleanup\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SIGTERM handler. */
|
/* SIGTERM handler. */
|
||||||
@ -256,7 +256,34 @@ static int LIBUSB_CALL hotplug_callback_attach(
|
|||||||
(void)event;
|
(void)event;
|
||||||
(void)user_data;
|
(void)user_data;
|
||||||
has_attached = true;
|
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)
|
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)
|
uint8_t *rxbuf, size_t rxsize)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
stlink_check_detach(1);
|
||||||
if( txsize) {
|
if( txsize) {
|
||||||
int txlen = txsize;
|
int txlen = txsize;
|
||||||
libusb_fill_bulk_transfer(Stlink.req_trans, Stlink.handle,
|
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");
|
DEBUG("STLINKV1 not supported\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
Stlink.vid = desc.idVendor;
|
||||||
|
Stlink.pid = desc.idProduct;
|
||||||
r = libusb_open(dev, &Stlink.handle);
|
r = libusb_open(dev, &Stlink.handle);
|
||||||
if (r == LIBUSB_SUCCESS) {
|
if (r == LIBUSB_SUCCESS) {
|
||||||
uint8_t data[32];
|
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));
|
DEBUG("libusb_claim_interface failed %s\n", libusb_strerror(r));
|
||||||
goto error_1;
|
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.req_trans = libusb_alloc_transfer(0);
|
||||||
Stlink.rep_trans = libusb_alloc_transfer(0);
|
Stlink.rep_trans = libusb_alloc_transfer(0);
|
||||||
stlink_version();
|
stlink_version();
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
# include <netinet/tcp.h>
|
# include <netinet/tcp.h>
|
||||||
# include <sys/select.h>
|
# include <sys/select.h>
|
||||||
|
# include <fcntl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -100,7 +101,33 @@ unsigned char gdb_if_getchar(void)
|
|||||||
|
|
||||||
while(i <= 0) {
|
while(i <= 0) {
|
||||||
if(gdb_if_conn <= 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");
|
DEBUG("Got connection\n");
|
||||||
}
|
}
|
||||||
i = recv(gdb_if_conn, (void*)&ret, 1, 0);
|
i = recv(gdb_if_conn, (void*)&ret, 1, 0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user