Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

main.cpp

Go to the documentation of this file.
00001 /*
00002  * This file is part of Jelie,
00003  * (c) 2002 Julien Pilet <julien.pilet@epfl.ch> and
00004  * Stephane Magnenat <stephane.magnenat@epfl.ch>
00005  *
00006  * Jelie is free software; you can redistribute it
00007  * and/or modify it under the terms of the GNU General Public License as
00008  * published by the Free Software Foundation; either version 2 of the License,
00009  * or (at your option) any later version.
00010  *
00011  * Jelie is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with Foobar; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00031 #include <unistd.h>
00032 #include <signal.h>
00033 
00034 #ifdef HAVE_CONFIG_H
00035 #include <config.h>
00036 #endif
00037 
00038 #ifdef HAVE_LIBREADLINE
00039 #include <readline/readline.h>
00040 #include <readline/history.h>
00041 #endif
00042 
00043 #include "gdbremote.h"
00044 #include "jtagpxa250.h"
00045 #include "cmdline.h"
00046 #include "filemanager.h"
00047 #include "debug.h"
00048 #include "jtagctrl_factory.h"
00049 
00051 class EventSelector {
00052 private:
00054         CmdLine cmd;
00055 
00057         GdbRemote gdbRemote;
00058         int tcpPort;    //< tcp port to listen to GDB.
00059 
00063         bool withReadLine;
00064 
00066         int commandResult;
00067 
00068 public:
00069         EventSelector(int tcpPort);
00070 
00072         static void handleInputCommand(char *buffer);
00073 
00075         void read_char();
00076 
00078         void loop();
00079 };
00080 
00082 EventSelector *event;
00083 
00084 #ifdef HAVE_LIBREADLINE
00085 void set_prompt_and_display(void)
00086 {
00087         if (pxa250Ptr->targetReady())
00088                 rl_set_prompt("r> ");
00089         else
00090                 rl_set_prompt("n> ");
00091         rl_redisplay();
00092 }
00093 #endif
00094 
00099 EventSelector::EventSelector(int tcpPort) : gdbRemote(pxa250Ptr), 
00100         tcpPort(tcpPort), commandResult(0) 
00101 {
00102 #ifdef HAVE_LIBREADLINE
00103         if (isatty(fileno(stdin))) {
00104                 // we have a human on stdin. Let's use libreadline.
00105                 if (pxa250Ptr->targetReady())
00106                         rl_callback_handler_install("r> ", handleInputCommand);
00107                 else
00108                         rl_callback_handler_install("n> ", handleInputCommand);
00109 
00110                 rl_redisplay_function = set_prompt_and_display;
00111                 withReadLine = true;
00112         } else {
00113                 withReadLine = false;
00114         }
00115 #else
00116         withReadLine = false;
00117 #endif
00118 }
00119         
00120 void EventSelector::loop() {
00121 
00122         // open the TCP port to listen to GDB.
00123         if (!gdbRemote.openPort(tcpPort)) {
00124                 gdbRemote.printError();
00125         }
00126 
00127         // loop, waiting for user input and polling the debug handler, 
00128         // in case it has something to say.
00129         do {
00130                 fd_set fds;
00131                 struct timeval timeout;
00132                 int max;
00133                 
00134                 FD_ZERO(&fds);
00135                 max = gdbRemote.prepareFD_SET(&fds);
00136                 FD_SET(fileno(stdin), &fds);
00137                 if (fileno(stdin) > max) max = fileno(stdin);
00138                 
00139                 // set the timeout
00140                 timeout.tv_sec = 0;
00141                 timeout.tv_usec = 100; // polling 10 times a second should be ok
00142 
00143                 if (select(max + 1, &fds, 0, 0, &timeout) == 0) {
00144                         // timeout has occured, polls the TX register
00145                         pxa250Ptr->pollForTX();
00146                 } 
00147 
00148                 gdbRemote.processFD_SET(&fds);
00149 
00150                 if (FD_ISSET(fileno(stdin), &fds)) {
00151 #ifdef HAVE_LIBREADLINE
00152                         if (withReadLine)
00153                                 rl_callback_read_char();
00154                         else
00155 #endif
00156                                 read_char();
00157                 }
00158         } while (commandResult != -1);
00159 }
00160 
00161 #define MAX_BUFF_SIZE 256
00162 void EventSelector::read_char() {
00163         static char *buffer = 0;
00164         static int pos;
00165 
00166         if (buffer == 0) {
00167                 buffer = (char *) malloc(MAX_BUFF_SIZE);
00168                 buffer[0]=0;
00169                 pos = 0;
00170         }
00171         
00172         assert(pos < MAX_BUFF_SIZE);
00173 
00174         if (read(fileno(stdin), buffer + pos, 1) <= 0) {
00175                 pos = 0;
00176                 usleep(10);
00177                 return;
00178         }
00179         
00180         if (buffer[pos] == '\n') {
00181                 if (pos) {
00182                         buffer[pos] = 0;
00183 
00184                         // we got a non empty line
00185                         handleInputCommand(buffer);
00186                         buffer = 0;
00187                 }
00188         } else {
00189                 pos++;
00190         }
00191 }
00192         
00194 void EventSelector::handleInputCommand(char *buffer) {
00195         if (!buffer || !buffer[0])
00196                 return;
00197 #ifdef HAVE_LIBREADLINE
00198         add_history(buffer);
00199 #endif
00200 
00201         // before executing a command, make sure the debug handler
00202         // has nothing to say.
00203         pxa250Ptr->pollForTX();
00204 
00205         event->commandResult = event->cmd.exec(buffer);
00206         //if (result != 0 && result != -1)
00207         if (event->commandResult == 0)
00208                 printf("[ok]\n");
00209         else
00210                 printf("[return code %d]\n", event->commandResult);
00211 
00212         free(buffer);
00213         
00214         // we might already have an answer
00215         pxa250Ptr->pollForTX();
00216 }
00217 
00218 void usage(const char *prog) {
00219         fprintf(stderr, "usage:\n"
00220                         "%s [-h] [-p] [-d] [-I <dir>] [-t <tcp port>]\n"
00221                         "-h             prints this help\n"
00222                         "-p             use parallel port (Wiggler)\n"
00223                         "-d             enable debugging\n"
00224                         "-I <dir>       look also in <dir> when searching a file\n"
00225                         "-t <tcp port>  listent to <tcp port> instead of %d\n",
00226                         prog, GDB_REMOTE_DEFAULT_PORT);
00227         exit(-1);
00228 }
00229 
00230 int main(int argc, char *argv[]) {
00231 
00232         printf("This is " PACKAGE " version " VERSION "\n");
00233         printf("Julien Pilet & Stephane Magnenat, 6.2002 - 3.2003.\n");
00234 
00235         bool usePP=false;
00236         int tcpPort = GDB_REMOTE_DEFAULT_PORT;
00237 
00238         // construct the file handling system
00239         fileManagerPtr = new FileManager();
00240 
00241         // check for a '-d' option
00242         for (int i=1; i<argc; i++) {
00243                 if (argv[i][0] == '-') {
00244                         switch (argv[i][1]) {
00245                                 case 'd': 
00246                                         addDebugLevel(CMD_SCRIPT_DEBUG);
00247                                         addDebugLevel(GDB_REMOTE_DEBUG);
00248                                         break;
00249                                 case 'p': 
00250                                         usePP = true; break;
00251                                 case 'I': 
00252                                         ++i; 
00253                                         if (i  < argc) 
00254                                                 fileManagerPtr->addDir(argv[i]);
00255                                         else
00256                                                 usage(argv[0]);
00257                                         break;
00258                                 case 't': 
00259                                         ++i; 
00260                                         if (i< argc) 
00261                                                 tcpPort = atoi(argv[i]); 
00262                                         else
00263                                                 usage(argv[0]);
00264                                         break;
00265                                 case 'h': 
00266                                 default:
00267                                         usage(argv[0]);
00268                         }
00269                 }
00270         }
00271 
00272         // contruct the control object
00273         JTAGControl *jtag=NULL;
00274         JTAGControlFactory factory;
00275         const char *ctlName=NULL;
00276 
00277         if (usePP) {
00278                 ctlName="pp";
00279         } else {
00280                 ctlName="ezusb";
00281         }
00282         jtag = factory.getPrefered(ctlName, argc, argv);
00283         if (!jtag)
00284         {
00285                 fprintf(stderr, "Can't get prefered JTAG control %s, " 
00286                                 "trying another one\n", ctlName);
00287                 jtag = factory.getAvailable(argc, argv);
00288         }
00289         if (!jtag)
00290         {
00291                 fprintf(stderr, "Can't find any JTAG control, critical stop !\n");
00292                 exit(-1);
00293         }
00294 
00295         printf("JTAG control %s used\n", jtag->getName());
00296         JTAGpxa250 pxa(jtag);
00297 
00298         pxa250Ptr = &pxa;
00299 
00300         pxa.loadDebugHandler();
00301         event = new EventSelector(tcpPort);
00302 
00303         event->loop();
00304         delete event;
00305         delete fileManagerPtr;
00306 }

Generated on Fri May 16 13:01:45 2003 for Jelie by doxygen1.2.15