📄 main.cpp
字号:
/* * This file is part of Jelie, * (c) 2002 Julien Pilet <julien.pilet@epfl.ch> and * Stephane Magnenat <stephane.magnenat@epfl.ch> * * Jelie 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 2 of the License, * or (at your option) any later version. * * Jelie 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 Foobar; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//*! \file * * In this file, main() initialize everything, and the EventSelector class take * care of getting input from readline, stdin, tcp or usb. Event treatment is * then done by GdbRemote or CmdLine. * * \author Julien Pilet <julien.pilet@epfl.ch> * \author Stephane Magnenat <stephane.magnenat@epfl.ch> */#include <unistd.h>#include <signal.h>#ifdef HAVE_CONFIG_H#include <config.h>#endif#ifdef HAVE_LIBREADLINE#include <readline/readline.h>#include <readline/history.h>#endif#include "gdbremote.h"#include "jtagpxa250.h"#include "cmdline.h"#include "filemanager.h"#include "debug.h"#include "jtagctrl_factory.h"//! this class waits for inputs events and then dispatch them for treatment.class EventSelector {private: //! keyboard or stdin input is treated by CmdLine CmdLine cmd; //! tcp/ip data is passed to GdbRemote for treatment GdbRemote gdbRemote; int tcpPort; //< tcp port to listen to GDB. /*! true if using libreadline. Impossible to use libreadline if stdin * is not a terminal. */ bool withReadLine; //! Stores the result of a command. int commandResult;public: EventSelector(int tcpPort); //! callback for readline static void handleInputCommand(char *buffer); //! equivalent to handleInputCommand when readline is not used void read_char(); //! wait for events and process them. void loop();};//! has to be global, for the handleInputCommand callback for readline.EventSelector *event;#ifdef HAVE_LIBREADLINEvoid set_prompt_and_display(void){ if (pxa250Ptr->targetReady()) rl_set_prompt("r> "); else rl_set_prompt("n> "); rl_redisplay();}#endif/*! Constructs the EventSelector and configures libreadline. * Check if stdin is a terminal or not, to decide wether to use libreadline or not. * Also constructs a GdbRemote object by passing it pxa250Ptr. */EventSelector::EventSelector(int tcpPort) : gdbRemote(pxa250Ptr), tcpPort(tcpPort), commandResult(0) {#ifdef HAVE_LIBREADLINE if (isatty(fileno(stdin))) { // we have a human on stdin. Let's use libreadline. if (pxa250Ptr->targetReady()) rl_callback_handler_install("r> ", handleInputCommand); else rl_callback_handler_install("n> ", handleInputCommand); rl_redisplay_function = set_prompt_and_display; withReadLine = true; } else { withReadLine = false; }#else withReadLine = false;#endif} void EventSelector::loop() { // open the TCP port to listen to GDB. if (!gdbRemote.openPort(tcpPort)) { gdbRemote.printError(); } // loop, waiting for user input and polling the debug handler, // in case it has something to say. do { fd_set fds; struct timeval timeout; int max; FD_ZERO(&fds); max = gdbRemote.prepareFD_SET(&fds); FD_SET(fileno(stdin), &fds); if (fileno(stdin) > max) max = fileno(stdin); // set the timeout timeout.tv_sec = 0; timeout.tv_usec = 100; // polling 10 times a second should be ok if (select(max + 1, &fds, 0, 0, &timeout) == 0) { // timeout has occured, polls the TX register pxa250Ptr->pollForTX(); } gdbRemote.processFD_SET(&fds); if (FD_ISSET(fileno(stdin), &fds)) {#ifdef HAVE_LIBREADLINE if (withReadLine) rl_callback_read_char(); else#endif read_char(); } } while (commandResult != -1);}#define MAX_BUFF_SIZE 256void EventSelector::read_char() { static char *buffer = 0; static int pos; if (buffer == 0) { buffer = (char *) malloc(MAX_BUFF_SIZE); buffer[0]=0; pos = 0; } assert(pos < MAX_BUFF_SIZE); if (read(fileno(stdin), buffer + pos, 1) <= 0) { pos = 0; usleep(10); return; } if (buffer[pos] == '\n') { if (pos) { buffer[pos] = 0; // we got a non empty line handleInputCommand(buffer); buffer = 0; } } else { pos++; }} //! Handler for libreadlinevoid EventSelector::handleInputCommand(char *buffer) { if (!buffer || !buffer[0]) return;#ifdef HAVE_LIBREADLINE add_history(buffer);#endif // before executing a command, make sure the debug handler // has nothing to say. pxa250Ptr->pollForTX(); event->commandResult = event->cmd.exec(buffer); //if (result != 0 && result != -1) if (event->commandResult == 0) printf("[ok]\n"); else printf("[return code %d]\n", event->commandResult); free(buffer); // we might already have an answer pxa250Ptr->pollForTX();}void usage(const char *prog) { fprintf(stderr, "usage:\n" "%s [-h] [-p] [-d] [-I <dir>] [-t <tcp port>]\n" "-h prints this help\n" "-p use parallel port (Wiggler)\n" "-d enable debugging\n" "-I <dir> look also in <dir> when searching a file\n" "-t <tcp port> listent to <tcp port> instead of %d\n", prog, GDB_REMOTE_DEFAULT_PORT); exit(-1);}int main(int argc, char *argv[]) { printf("This is " PACKAGE " version " VERSION "\n"); printf("Julien Pilet & Stephane Magnenat, 6.2002 - 3.2003.\n"); bool usePP=false; int tcpPort = GDB_REMOTE_DEFAULT_PORT; // construct the file handling system fileManagerPtr = new FileManager(); // check for a '-d' option for (int i=1; i<argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { case 'd': addDebugLevel(CMD_SCRIPT_DEBUG); addDebugLevel(GDB_REMOTE_DEBUG); break; case 'p': usePP = true; break; case 'I': ++i; if (i < argc) fileManagerPtr->addDir(argv[i]); else usage(argv[0]); break; case 't': ++i; if (i< argc) tcpPort = atoi(argv[i]); else usage(argv[0]); break; case 'h': default: usage(argv[0]); } } } // contruct the control object JTAGControl *jtag=NULL; JTAGControlFactory factory; const char *ctlName=NULL; if (usePP) { ctlName="pp"; } else { ctlName="ezusb"; } jtag = factory.getPrefered(ctlName, argc, argv); if (!jtag) { fprintf(stderr, "Can't get prefered JTAG control %s, " "trying another one\n", ctlName); jtag = factory.getAvailable(argc, argv); } if (!jtag) { fprintf(stderr, "Can't find any JTAG control, critical stop !\n"); exit(-1); } printf("JTAG control %s used\n", jtag->getName()); JTAGpxa250 pxa(jtag); pxa250Ptr = &pxa; pxa.loadDebugHandler(); event = new EventSelector(tcpPort); event->loop(); delete event; delete fileManagerPtr;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -