From 8d190cdbb9c4e4377d0c33424e453c5ac166eed8 Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Sun, 10 Jun 2012 16:40:07 +1200 Subject: Renamed platforms to 'native' and 'libftdi' and moved into 'platforms' dir. --- src/platforms/libftdi/gdb_if.c | 114 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 src/platforms/libftdi/gdb_if.c (limited to 'src/platforms/libftdi/gdb_if.c') diff --git a/src/platforms/libftdi/gdb_if.c b/src/platforms/libftdi/gdb_if.c new file mode 100644 index 0000000..4b4f4a5 --- /dev/null +++ b/src/platforms/libftdi/gdb_if.c @@ -0,0 +1,114 @@ +/* + * This file is part of the Black Magic Debug project. + * + * Copyright (C) 2011 Black Sphere Technologies Ltd. + * Written by Gareth McMullin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* This file implements a transparent channel over which the GDB Remote + * Serial Debugging protocol is implemented. This implementation for Linux + * uses a TCP server on port 2000. + */ +#include + +#ifndef WIN32 +# include +# include +# include +#else +# include +# include +#endif + +#include + +#include "general.h" +#include "gdb_if.h" + +static int gdb_if_serv, gdb_if_conn; + +int gdb_if_init(void) +{ +#ifdef WIN32 + WSADATA wsaData; + WSAStartup(MAKEWORD(2, 2), &wsaData); +#endif + struct sockaddr_in addr; + int opt; + + addr.sin_family = AF_INET; + addr.sin_port = htons(2000); + addr.sin_addr.s_addr = htonl(INADDR_ANY); + + assert((gdb_if_serv = socket(PF_INET, SOCK_STREAM, 0)) != -1); + opt = 1; + assert(setsockopt(gdb_if_serv, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) != -1); + + assert(bind(gdb_if_serv, (void*)&addr, sizeof(addr)) != -1); + assert(listen(gdb_if_serv, 1) != -1); + + DEBUG("Listening on TCP:2000\n"); + + return 0; +} + + +unsigned char gdb_if_getchar(void) +{ + unsigned char ret; + int i = 0; + + while(i <= 0) { + if(gdb_if_conn <= 0) { + gdb_if_conn = accept(gdb_if_serv, NULL, NULL); + DEBUG("Got connection\n"); + } + i = recv(gdb_if_conn, &ret, 1, 0); + if(i <= 0) { + gdb_if_conn = -1; + DEBUG("Dropped broken connection\n"); + /* Return '+' in case we were waiting for an ACK */ + return '+'; + } + } + return ret; +} + +unsigned char gdb_if_getchar_to(int timeout) +{ + fd_set fds; + struct timeval tv; + + if(gdb_if_conn == -1) return -1; + + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + + FD_ZERO(&fds); + FD_SET(gdb_if_conn, &fds); + + if(select(gdb_if_conn+1, &fds, NULL, NULL, &tv) > 0) + return gdb_if_getchar(); + + return -1; +} + +void gdb_if_putchar(unsigned char c, int flush) +{ + if(gdb_if_conn > 0) + send(gdb_if_conn, &c, 1, 0); +} + -- cgit v1.2.3