X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=gdbserver%2Fgdb-server.c;h=a6de1b20d2db8f68fc6f2891e2b5e1f338ce809e;hb=5851dee3cd95d7b0276caa22b9d2992c8b1147fa;hp=f92fc05f06aa7c11f437c67ab252561fbccf85bc;hpb=bbecbc1e81b15b85829149424d048d96bd844939;p=fw%2Fstlink diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index f92fc05..a6de1b2 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,28 @@ typedef struct _st_state_t { char devicename[100]; int logging_level; int listen_port; + int persistent; + int reset; } 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); +#ifndef __MINGW32__ +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); +} +#endif + + int parse_options(int argc, char** argv, st_state_t *st) { static struct option long_options[] = { @@ -62,6 +80,8 @@ 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'}, + {"no-reset", optional_argument, NULL, 'n'}, {0, 0, 0, 0}, }; const char * help_str = "%s - usage:\n\n" @@ -76,13 +96,18 @@ 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" + " -n, --no-reset\n" + "\t\t\tDo not reset board on connection.\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:mn", 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 +154,12 @@ int parse_options(int argc, char** argv, st_state_t *st) { } st->listen_port = q; break; + case 'm': + st->persistent = 1; + break; + case 'n': + st->reset = 0; + break; } } @@ -143,6 +174,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { int main(int argc, char** argv) { + uint32_t voltage; stlink_t *sl = NULL; @@ -152,20 +184,36 @@ int main(int argc, char** argv) { state.stlink_version = 2; state.logging_level = DEFAULT_LOGGING_LEVEL; state.listen_port = DEFAULT_GDB_LISTEN_PORT; + state.reset = 1; /* By default, reset board */ parse_options(argc, argv, &state); switch (state.stlink_version) { case 2: - sl = stlink_open_usb(state.logging_level); + sl = stlink_open_usb(state.logging_level, 0); if(sl == NULL) return 1; break; case 1: - sl = stlink_v1_open(state.logging_level); + sl = stlink_v1_open(state.logging_level, 0); if(sl == NULL) return 1; break; } + connected_stlink = sl; +#ifndef __MINGW32__ + signal(SIGINT, &cleanup); + signal(SIGTERM, &cleanup); +#endif + + if (state.reset) { + stlink_reset(sl); + } + printf("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); + voltage = stlink_target_voltage(sl); + if (voltage != -1) { + printf("Target voltage is %d mV.\n", voltage); + } + sl->verbose=0; current_memory_map = make_memory_map(sl); @@ -177,7 +225,12 @@ int main(int argc, char** argv) { } #endif - while(serve(sl, state.listen_port) == 0); + do { + serve(sl, &state); + + /* Continue */ + stlink_run(sl); + } while (state.persistent); #ifdef __MINGW32__ winsock_error: @@ -185,7 +238,6 @@ winsock_error: #endif /* Switch back to mass storage mode before closing. */ - stlink_run(sl); stlink_exit_debug_mode(sl); stlink_close(sl); @@ -342,7 +394,7 @@ struct code_hw_watchpoint { struct code_hw_watchpoint data_watches[DATA_WATCH_NUM]; static void init_data_watchpoints(stlink_t *sl) { - #ifdef DEBUG + #if DEBUG printf("init watchpoints\n"); #endif @@ -377,7 +429,7 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr for(i = 0; i < DATA_WATCH_NUM; i++) { // is this an empty slot ? if(data_watches[i].fun == WATCHDISABLED) { - #ifdef DEBUG + #if DEBUG printf("insert watchpoint %d addr %x wf %u mask %u len %d\n", i, addr, wf, mask, len); #endif @@ -401,7 +453,7 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr } } - #ifdef DEBUG + #if DEBUG printf("failure: add watchpoints addr %x wf %u len %u\n", addr, wf, len); #endif return -1; @@ -413,7 +465,7 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) for(i = 0 ; i < DATA_WATCH_NUM; i++) { if((data_watches[i].addr == addr) && (data_watches[i].fun != WATCHDISABLED)) { - #ifdef DEBUG + #if DEBUG printf("delete watchpoint %d addr %x\n", i, addr); #endif @@ -424,7 +476,7 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) } } - #ifdef DEBUG + #if DEBUG printf("failure: delete watchpoint addr %x\n", addr); #endif @@ -485,7 +537,7 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { else brk->type &= ~type; if(brk->type == 0) { - #ifdef DEBUG + #if DEBUG printf("clearing hw break %d\n", id); #endif @@ -493,7 +545,7 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { } else { uint32_t mask = (brk->addr) | 1 | (brk->type << 30); - #ifdef DEBUG + #if DEBUG printf("setting hw break %d at %08x (%d)\n", id, brk->addr, brk->type); printf("reg %08x \n", @@ -589,7 +641,7 @@ static int flash_go(stlink_t *sl) { stlink_reset(sl); for(struct flash_block* fb = flash_root; fb; fb = fb->next) { - #ifdef DEBUG + #if DEBUG printf("flash_do: block %08x -> %04x\n", fb->addr, fb->length); #endif @@ -599,7 +651,7 @@ static int flash_go(stlink_t *sl) { //Update FLASH_PAGE stlink_calculate_pagesize(sl, page); - #ifdef DEBUG + #if DEBUG printf("flash_do: page %08x\n", page); #endif @@ -625,7 +677,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"); @@ -638,8 +690,8 @@ int serve(stlink_t *sl, int port) { struct sockaddr_in serv_addr; 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_addr.s_addr = INADDR_ANY; + serv_addr.sin_port = htons(st->listen_port); if(bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { perror("bind"); @@ -650,14 +702,8 @@ 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); @@ -668,6 +714,13 @@ start_again: close(sock); + stlink_force_debug(sl); + if (st->reset) { + stlink_reset(sl); + } + init_code_breakpoints(sl); + init_data_watchpoints(sl); + printf("GDB connected.\n"); /* @@ -682,10 +735,10 @@ 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 + #if DEBUG printf("recv: %s\n", packet); #endif @@ -710,7 +763,7 @@ start_again: char* queryName = calloc(queryNameLength + 1, 1); strncpy(queryName, &packet[1], queryNameLength); - #ifdef DEBUG + #if DEBUG printf("query: %s;%s\n", queryName, params); #endif @@ -735,7 +788,7 @@ start_again: unsigned addr = strtoul(__s_addr, NULL, 16), length = strtoul(s_length, NULL, 16); - #ifdef DEBUG + #if DEBUG printf("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n", type, op, annex, addr, length); #endif @@ -772,7 +825,7 @@ start_again: if (!strncmp(params,"726573756d65",12)) {// resume -#ifdef DEBUG +#if DEBUG printf("Rcmd: resume\n"); #endif stlink_run(sl); @@ -783,7 +836,7 @@ start_again: stlink_force_debug(sl); -#ifdef DEBUG +#if DEBUG printf("Rcmd: halt\n"); #endif } else if (!strncmp(params,"6a7461675f7265736574",20)) { //jtag_reset @@ -793,7 +846,7 @@ start_again: stlink_jtag_reset(sl, 0); stlink_force_debug(sl); -#ifdef DEBUG +#if DEBUG printf("Rcmd: jtag_reset\n"); #endif } else if (!strncmp(params,"7265736574",10)) { //reset @@ -804,11 +857,11 @@ start_again: init_code_breakpoints(sl); init_data_watchpoints(sl); -#ifdef DEBUG +#if DEBUG printf("Rcmd: reset\n"); #endif } else { -#ifdef DEBUG +#if DEBUG printf("Rcmd: %s\n", params); #endif @@ -840,7 +893,7 @@ start_again: unsigned addr = strtoul(__s_addr, NULL, 16), length = strtoul(s_length, NULL, 16); - #ifdef DEBUG + #if DEBUG printf("FlashErase: addr:%08x,len:%04x\n", addr, length); #endif @@ -878,7 +931,7 @@ start_again: if(dec_index % 2 != 0) dec_index++; - #ifdef DEBUG + #if DEBUG printf("binary packet %d -> %d\n", data_length, dec_index); #endif @@ -1190,6 +1243,12 @@ start_again: * We do support that always. */ + /* + * Also, set to persistent mode + * to allow GDB disconnect. + */ + st->persistent = 1; + reply = strdup("OK"); break; @@ -1214,7 +1273,7 @@ start_again: } if(reply) { - #ifdef DEBUG + #if DEBUG printf("send: %s\n", reply); #endif @@ -1223,7 +1282,7 @@ start_again: fprintf(stderr, "cannot send: %d\n", result); free(reply); free(packet); - goto start_again; + return 1; } free(reply);