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.
This commit is contained in:
Gareth McMullin 2011-07-02 20:47:39 +12:00
parent bd779aa618
commit adabaa7592
5 changed files with 26 additions and 5 deletions

View File

@ -151,11 +151,13 @@ gdb_main(void)
} }
/* Wait for target halt */ /* Wait for target halt */
while(!target_halt_wait(cur_target)) while(!target_halt_wait(cur_target)) {
if(gdb_if_getchar_to(0) == '\x03') { unsigned char c = gdb_if_getchar_to(0);
if((c == '\x03') || (c == '\x04')) {
target_halt_request(cur_target); target_halt_request(cur_target);
sent_int = 1; sent_int = 1;
} }
}
SET_RUN_STATE(0); SET_RUN_STATE(0);
/* Report reason for halt */ /* Report reason for halt */

View File

@ -46,6 +46,7 @@
static char *get_dev_unique_id(char *serial_no); static char *get_dev_unique_id(char *serial_no);
static int configured; static int configured;
static int cdcacm_gdb_dtr;
static const struct usb_device_descriptor dev = { static const struct usb_device_descriptor dev = {
.bLength = USB_DT_DEVICE_SIZE, .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) { switch(req->bRequest) {
case USB_CDC_REQ_SET_CONTROL_LINE_STATE: case USB_CDC_REQ_SET_CONTROL_LINE_STATE:
/* This Linux cdc_acm driver requires this to be implemented /* Ignore if not for GDB interface */
* even though it's optional in the CDC spec, and we don't if(req->wIndex != 0)
* advertise it in the ACM functional descriptor. */ return 1;
cdcacm_gdb_dtr = req->wValue & 1;
return 1; return 1;
#ifdef INCLUDE_UART_INTERFACE #ifdef INCLUDE_UART_INTERFACE
case USB_CDC_REQ_SET_LINE_CODING: { case USB_CDC_REQ_SET_LINE_CODING: {
@ -402,6 +406,11 @@ int cdcacm_get_config(void)
return configured; return configured;
} }
int cdcacm_get_dtr(void)
{
return cdcacm_gdb_dtr;
}
#ifdef INCLUDE_UART_INTERFACE #ifdef INCLUDE_UART_INTERFACE
static void cdcacm_data_rx_cb(u8 ep) static void cdcacm_data_rx_cb(u8 ep)
{ {

View File

@ -47,6 +47,10 @@ void gdb_if_putchar(unsigned char c, int flush)
unsigned char gdb_if_getchar(void) unsigned char gdb_if_getchar(void)
{ {
while(!(out_ptr < count_out)) { while(!(out_ptr < count_out)) {
/* Detach if port closed */
if(!cdcacm_get_dtr())
return 0x04;
while(cdcacm_get_config() != 1); while(cdcacm_get_config() != 1);
count_out = usbd_ep_read_packet(1, buffer_out, count_out = usbd_ep_read_packet(1, buffer_out,
VIRTUAL_COM_PORT_DATA_SIZE); VIRTUAL_COM_PORT_DATA_SIZE);
@ -61,6 +65,10 @@ unsigned char gdb_if_getchar_to(int timeout)
timeout_counter = timeout/100; timeout_counter = timeout/100;
if(!(out_ptr < count_out)) do { 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, count_out = usbd_ep_read_packet(1, buffer_out,
VIRTUAL_COM_PORT_DATA_SIZE); VIRTUAL_COM_PORT_DATA_SIZE);
out_ptr = 0; out_ptr = 0;

View File

@ -28,6 +28,7 @@
#include <libopencm3/stm32/scb.h> #include <libopencm3/stm32/scb.h>
#include <libopencm3/stm32/nvic.h> #include <libopencm3/stm32/nvic.h>
#include <libopencm3/stm32/usart.h> #include <libopencm3/stm32/usart.h>
#include <libopencm3/usb/usbd.h>
#include "platform.h" #include "platform.h"
#include "jtag_scan.h" #include "jtag_scan.h"

View File

@ -124,6 +124,7 @@ void morse(const char *msg, char repeat);
void cdcacm_init(void); void cdcacm_init(void);
/* Returns current usb configuration, or 0 if not configured. */ /* Returns current usb configuration, or 0 if not configured. */
int cdcacm_get_config(void); int cdcacm_get_config(void);
int cdcacm_get_dtr(void);
/* Use newlib provided integer only stdio functions */ /* Use newlib provided integer only stdio functions */
#define sscanf siscanf #define sscanf siscanf