From adabaa759296b8f2470d7c562963d4e34dc35b19 Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Sat, 2 Jul 2011 20:47:39 +1200 Subject: [PATCH] Halt and detach target if host releases DTR. Port reads 0x04 (EOF) when DTR is released. GDB loop detaches from target if EOF is read. Fixes bug 3307433. --- src/gdb_main.c | 6 ++++-- src/stm32/cdcacm.c | 15 ++++++++++++--- src/stm32/gdb_if.c | 8 ++++++++ src/stm32/platform.c | 1 + src/stm32/platform.h | 1 + 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/gdb_main.c b/src/gdb_main.c index 0ffa4eca..1851b2c4 100644 --- a/src/gdb_main.c +++ b/src/gdb_main.c @@ -151,11 +151,13 @@ gdb_main(void) } /* Wait for target halt */ - while(!target_halt_wait(cur_target)) - if(gdb_if_getchar_to(0) == '\x03') { + while(!target_halt_wait(cur_target)) { + unsigned char c = gdb_if_getchar_to(0); + if((c == '\x03') || (c == '\x04')) { target_halt_request(cur_target); sent_int = 1; } + } SET_RUN_STATE(0); /* Report reason for halt */ diff --git a/src/stm32/cdcacm.c b/src/stm32/cdcacm.c index 9cbd44b2..a4f0527f 100644 --- a/src/stm32/cdcacm.c +++ b/src/stm32/cdcacm.c @@ -46,6 +46,7 @@ static char *get_dev_unique_id(char *serial_no); static int configured; +static int cdcacm_gdb_dtr; static const struct usb_device_descriptor dev = { .bLength = USB_DT_DEVICE_SIZE, @@ -346,9 +347,12 @@ static int cdcacm_control_request(struct usb_setup_data *req, uint8_t **buf, switch(req->bRequest) { case USB_CDC_REQ_SET_CONTROL_LINE_STATE: - /* This Linux cdc_acm driver requires this to be implemented - * even though it's optional in the CDC spec, and we don't - * advertise it in the ACM functional descriptor. */ + /* Ignore if not for GDB interface */ + if(req->wIndex != 0) + return 1; + + cdcacm_gdb_dtr = req->wValue & 1; + return 1; #ifdef INCLUDE_UART_INTERFACE case USB_CDC_REQ_SET_LINE_CODING: { @@ -402,6 +406,11 @@ int cdcacm_get_config(void) return configured; } +int cdcacm_get_dtr(void) +{ + return cdcacm_gdb_dtr; +} + #ifdef INCLUDE_UART_INTERFACE static void cdcacm_data_rx_cb(u8 ep) { diff --git a/src/stm32/gdb_if.c b/src/stm32/gdb_if.c index 08dfa030..2ed8c416 100644 --- a/src/stm32/gdb_if.c +++ b/src/stm32/gdb_if.c @@ -47,6 +47,10 @@ void gdb_if_putchar(unsigned char c, int flush) unsigned char gdb_if_getchar(void) { while(!(out_ptr < count_out)) { + /* Detach if port closed */ + if(!cdcacm_get_dtr()) + return 0x04; + while(cdcacm_get_config() != 1); count_out = usbd_ep_read_packet(1, buffer_out, VIRTUAL_COM_PORT_DATA_SIZE); @@ -61,6 +65,10 @@ unsigned char gdb_if_getchar_to(int timeout) timeout_counter = timeout/100; if(!(out_ptr < count_out)) do { + /* Detach if port closed */ + if(!cdcacm_get_dtr()) + return 0x04; + count_out = usbd_ep_read_packet(1, buffer_out, VIRTUAL_COM_PORT_DATA_SIZE); out_ptr = 0; diff --git a/src/stm32/platform.c b/src/stm32/platform.c index 71458b13..d4a4471f 100644 --- a/src/stm32/platform.c +++ b/src/stm32/platform.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "platform.h" #include "jtag_scan.h" diff --git a/src/stm32/platform.h b/src/stm32/platform.h index 2925ae8e..93f1694b 100644 --- a/src/stm32/platform.h +++ b/src/stm32/platform.h @@ -124,6 +124,7 @@ void morse(const char *msg, char repeat); void cdcacm_init(void); /* Returns current usb configuration, or 0 if not configured. */ int cdcacm_get_config(void); +int cdcacm_get_dtr(void); /* Use newlib provided integer only stdio functions */ #define sscanf siscanf