gdb.c
来自「完整的Bell实验室的嵌入式文件系统TFS」· C语言 代码 · 共 201 行
C
201 行
/* gdb.c: * The code in this file allows a gdb debugger on a host to connect to the * monitor. * Unlike the typical commands in the monitor's command set, the gdb serial * line protocol does not break the line up into whitespace delimited tokens * so the monitor's command interpreter must pass all lines that start with * a '$' to gdb_cmd() and let it do the rest. * NOTE: this is a VERY basic and incomplete implementation of the gdb * interface. My intent was to simply have the ability to peek and poke * memory with gdb. * * I got the information for this out of ESP magazine Sept 1999 issue also * had some discussion with Dave Thomas. * * General notice: * This code is part of a boot-monitor package developed as a generic base * platform for embedded system designs. As such, it is likely to be * distributed to various projects beyond the control of the original * author. Please notify the author of any enhancements made or bugs found * so that all may benefit from the changes. In addition, notification back * to the author will allow the new user to pick up changes that may have * been made by other users after this version of the code was distributed. * * Note1: the majority of this code was edited with 4-space tabs. * Note2: as more and more contributions are accepted, the term "author" * is becoming a mis-representation of credit. * * Original author: Ed Sutter * Email: esutter@lucent.com * Phone: 908-582-2351 */#include "config.h"#include "genlib.h"#include "ether.h"#include "stddefs.h"#include "cli.h"/* gdb_m(): * GDB memory read command... * mADDR,LEN */intgdb_m(char *line){ int len, i; uchar *addr, *lp, csum; addr = (uchar *)strtol(line+1,(char **)&lp,16); len = (int)strtol(lp+1,0,16); csum = 0; printf("+$"); for(i=0;i<len;i++,addr++) { printf("%02x",*addr); csum += *addr; } printf("#%02x",csum); return(0);}intgdb_M(char *line){ printf("gdb_M: %s\n",line); return(0);}/* gdb_cmd(): * First function called out of the monitor's command interpreter. It * does a basic syntax verification and then passes parameters to the * appropriate handler above. * Incoming syntax is * * $ CMD # CSUM (of CMD) * * where: * $ is the ascii '$' character (0x24) * # is the ascii '#' character (0x23) * CMD is some command line consisting of a command and arguments * CSUM is the checksum of the characters in CMD * * for example: * * $m4015bc,2#5a * * Returns... * 0 if command is not processed; * 1 if command is processed; * -1 if command is processed but has an error; * * If this code detects an error, then send an error code back to GDB. * According to the article, there are no defined error codes in GDB so * we will use the following... * E01 indicates a missing '#' at the end of the string. * E02 indicates a bad checksum calculation. * E03 indicates some command processing error. */intgdb_cmd(uchar *line){ int len, clen, err, i; uchar mycsum, incsum; len = strlen(line); if (line[len-3] != '#') { printf("+$E01#a6"); /* Missing ending '#' */ return(-1); } clen = len - 3; mycsum = 0; for(i=1;i<clen;i++) mycsum += line[i]; incsum = (uchar)strtol(line+len-2,(char **)0,16); if (mycsum != incsum) { printf("+$E02#a7"); /* Checksum failure */ return(-1); } err = 0; line++; switch(*line) { case 'm': /* Memory read */ err = gdb_m(line); break; case 'M': /* Memory write */ err = gdb_M(line); break; case 's': /* step */ case 'c': /* continue */ case '?': /* last signal */ printf("+$S05#b8"); break; case 'g': /* get all registers */ printf("+$00000000#80"); break; case 'q': /* */ printf("+$Text=0;Data=0;Bss=0#04"); break; case 'H': /* */ printf("+$OK#9a"); break; default: /* Unknown... return empty response. */ printf("+$#00"); break; } if (err) printf("+$E03#a8"); /* Command processing error */ return(1);}char *GdbHelp[] = { "Enter gdb mode", "(no options)", 0,};intGdb(int argc, char *argv){ int state; char line[64], *lp, c; printf("Entering gdb mode, type ctrl-a to exit.\n"); state = -1; while(1) { c = getchar(); if (c == '$') { lp = line; state = 0; } if (c == 0x01) /* ctrl-a terminates */ break; switch(state) { case 0: if (c == '#') state = 1; *lp++ = c; break; case 1: *lp++ = c; state = 2; break; case 2: *lp++ = c; *lp = 0; state = -1; gdb_cmd(line); break; default: break; }#if INCLUDE_ETHERNET pollethernet();#endif } return(CMD_SUCCESS);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?