X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=gdbserver%2Fgdb-server.c;h=32f0d8bafa6197ad14f2da2162fef58d7aae01d1;hb=2216d28452f5e97088fbfd4bd6f6daf187d5e53a;hp=f92fc05f06aa7c11f437c67ab252561fbccf85bc;hpb=bbecbc1e81b15b85829149424d048d96bd844939;p=fw%2Fstlink diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index f92fc05..32f0d8b 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -36,6 +36,8 @@ //Allways update the FLASH_PAGE before each use, by calling stlink_calculate_pagesize #define FLASH_PAGE (sl->flash_pgsz) +stlink_t *connected_stlink = NULL; + static const char hex[] = "0123456789abcdef"; static const char* current_memory_map = NULL; @@ -47,12 +49,23 @@ typedef struct _st_state_t { char devicename[100]; int logging_level; int listen_port; + int persistent; } st_state_t; -int serve(stlink_t *sl, int port); +int serve(stlink_t *sl, st_state_t *st); char* make_memory_map(stlink_t *sl); +static void cleanup(int signal __attribute__((unused))) { + if (connected_stlink) { + /* Switch back to mass storage mode before closing. */ + stlink_run(connected_stlink); + stlink_exit_debug_mode(connected_stlink); + stlink_close(connected_stlink); + } + + exit(1); +} int parse_options(int argc, char** argv, st_state_t *st) { static struct option long_options[] = { @@ -62,6 +75,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { {"stlink_version", required_argument, NULL, 's'}, {"stlinkv1", no_argument, NULL, '1'}, {"listen_port", required_argument, NULL, 'p'}, + {"multi", optional_argument, NULL, 'm'}, {0, 0, 0, 0}, }; const char * help_str = "%s - usage:\n\n" @@ -76,13 +90,16 @@ int parse_options(int argc, char** argv, st_state_t *st) { " -p 4242, --listen_port=1234\n" "\t\t\tSet the gdb server listen port. " "(default port: " STRINGIFY(DEFAULT_GDB_LISTEN_PORT) ")\n" + " -m, --multi\n" + "\t\t\tSet gdb server to extended mode.\n" + "\t\t\tst-util will continue listening for connections after disconnect.\n" ; int option_index = 0; int c; int q; - while ((c = getopt_long(argc, argv, "hv::d:s:1p:", long_options, &option_index)) != -1) { + while ((c = getopt_long(argc, argv, "hv::d:s:1p:m", long_options, &option_index)) != -1) { switch (c) { case 0: printf("XXXXX Shouldn't really normally come here, only if there's no corresponding option\n"); @@ -129,6 +146,9 @@ int parse_options(int argc, char** argv, st_state_t *st) { } st->listen_port = q; break; + case 'm': + st->persistent = 1; + break; } } @@ -164,6 +184,9 @@ int main(int argc, char** argv) { break; } + connected_stlink = sl; + signal(SIGINT, &cleanup); + printf("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); sl->verbose=0; @@ -177,7 +200,9 @@ int main(int argc, char** argv) { } #endif - while(serve(sl, state.listen_port) == 0); + do { + serve(sl, &state); + } while (state.persistent); #ifdef __MINGW32__ winsock_error: @@ -625,7 +650,7 @@ error: return error; } -int serve(stlink_t *sl, int port) { +int serve(stlink_t *sl, st_state_t *st) { int sock = socket(AF_INET, SOCK_STREAM, 0); if(sock < 0) { perror("socket"); @@ -639,7 +664,7 @@ int serve(stlink_t *sl, int port) { memset(&serv_addr,0,sizeof(struct sockaddr_in)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - serv_addr.sin_port = htons(port); + serv_addr.sin_port = htons(st->listen_port); if(bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { perror("bind"); @@ -650,14 +675,13 @@ int serve(stlink_t *sl, int port) { perror("listen"); return 1; } - -start_again: + stlink_force_debug(sl); stlink_reset(sl); init_code_breakpoints(sl); init_data_watchpoints(sl); - printf("Listening at *:%d...\n", port); + printf("Listening at *:%d...\n", st->listen_port); int client = accept(sock, NULL, NULL); //signal (SIGINT, SIG_DFL); @@ -682,7 +706,7 @@ start_again: int status = gdb_recv_packet(client, &packet); if(status < 0) { fprintf(stderr, "cannot recv: %d\n", status); - goto start_again; + return 1; } #ifdef DEBUG @@ -1190,6 +1214,12 @@ start_again: * We do support that always. */ + /* + * Also, set to persistent mode + * to allow GDB disconnect. + */ + st->persistent = 1; + reply = strdup("OK"); break; @@ -1223,7 +1253,7 @@ start_again: fprintf(stderr, "cannot send: %d\n", result); free(reply); free(packet); - goto start_again; + return 1; } free(reply);