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

cmdline.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 #ifdef HAVE_CONFIG_H
00032 #include "config.h"
00033 #endif
00034 #include <ctype.h>
00035 #include <stdlib.h>
00036 #include <stdio.h>
00037 #include <sys/time.h>
00038 #include "cmdline.h"
00039 #include "jtagpxa250.h"
00040 #include "filemanager.h"
00041 #include "debug.h"
00042 #include <unistd.h>
00043 
00045 // Commands
00047 
00048 char *LoadICCmd::getDescr() { 
00049         return  "loadic <file> <address> [mini]\n"
00050                 "Load the file given as parameter into the instruction cache\n"
00051                 "If \"mini\" is not specified, code will be loaded in main IC.\n"
00052                 "Example:\n\tloadic file.bin 0f0000 mini\n";
00053 }
00054 
00055 int LoadICCmd::exec(int argc, char *argv[]) {
00056         assert(pxa250Ptr);
00057         if (argc < 3) {
00058                 printf(getDescr());
00059                 return 1;
00060         }
00061 
00062         unsigned int address;
00063         sscanf(argv[2], "%x", &address);
00064 
00065         FILE *f = fileManagerPtr->openFP(argv[1], "r");
00066 
00067         if (!f) {
00068                 perror(argv[1]);
00069                 return 1;
00070         } else {
00071                 bool mini = argc >= 4 && strcmp(argv[3], "mini")==0;
00072                 unsigned int buffer[8*1024];    // 32kbyte buffer (8k instructions)
00073                 int nbi = fread(buffer, 4, 8*1024, f);  // read instructions 
00074                 printf("%d instructions read from file %s\n", nbi, argv[1]);
00075                 printf("Ready to upload in the %s instruction cache, at address 0x%X\n",
00076                                 mini ? "mini" : "main",
00077                                 address);
00078                 printf("First instruction: 0x%08X (lsB 0x%02X)\n", buffer[0], buffer[0]&0xFF);
00079 
00080 #ifdef WORDS_BIGENDIAN
00081                 for (int i=0; i<nbi;i++) {
00082                         unsigned char *cp= (unsigned char *) &buffer[i];
00083                         buffer[i] = JTAGpxa250::charArrayLEToInt(cp);
00084                 }
00085 #endif
00086 
00087                 if (mini & nbi > 512) {
00088                         printf("WARNING: trying to load more than 512 instructions in the mini instruction cache!\n");
00089                 }
00090 
00091                 pxa250Ptr->loadIC(mini, address, buffer, nbi);
00092                 // wait for proc to be ready
00093                 return 0;
00094         }
00095 }
00096 
00097 int CheckCmd::exec(int argc, char *argv[]) {
00098 
00099         assert(pxa250Ptr);
00100         if (pxa250Ptr->check()) {
00101                 printf("Success\n");
00102                 return 0;
00103         } else {
00104                 printf("Failure\n");
00105                 return 1;
00106         }
00107 }
00108 
00109 int InitCmd::exec(int argc, char *argv[]) {
00110 
00111         assert(pxa250Ptr);
00112         if (pxa250Ptr->init(argc, argv)) {
00113                 printf("Success\n");
00114                 return 0;
00115         } else {
00116                 printf("Failure\n");
00117                 return 1;
00118         }
00119 }
00120 
00121 int StopCmd::exec(int argc, char *argv[]) {
00122         assert(pxa250Ptr);
00123         pxa250Ptr->getReadyForUpload();
00124         return 0;
00125 }
00126 
00127 int BootCmd::exec(int argc, char *argv[]) {
00128         assert(pxa250Ptr);
00129         pxa250Ptr->boot();
00130         return 0;
00131 }
00132 
00133 int ResetCmd::exec(int argc, char *argv[]) {
00134         assert(pxa250Ptr);
00135         pxa250Ptr->jtag->jtagReset();
00136         return 0;
00137 }
00138 
00139 int QuitCmd::exec(int argc, char *argv[]) {
00140         printf("quitting.\n");
00141         return -1;
00142 }
00143 
00144 int HelpCmd::exec(int argc, char *argv[]) {
00145 
00146         if (argc > 1) {
00147                 // look for the command whose name is passed as argument
00148                 std::vector<Command *>::iterator it;
00149                 for (it = cmds.begin(); it != cmds.end(); ++it) {
00150                         if (strcmp(argv[1], (*it)->getName()) == 0) {
00151                                 printf("%s:\n%s\n", argv[1], (*it)->getDescr());
00152                                 return 0;
00153                         }
00154                 }
00155                 printf("%s: command not found.\n", argv[1]);
00156                 return 1;
00157         } else {
00158                 // list all commands
00159                 std::vector<Command *>::iterator it;
00160                 for (it = cmds.begin(); it != cmds.end(); ++it) {
00161                         printf("%20s - %s\n", (*it)->getName(), (*it)->getBrief());
00162                 }
00163                 return 0;
00164         }
00165 }
00166 
00167 long long GetTick()
00168 {
00169         struct timeval now;
00170 
00171         gettimeofday(&now, NULL);
00172         return (now.tv_sec)*1000+(now.tv_usec)/1000;
00173 }
00174 
00175 int LoadCmd::exec(int argc, char *argv[])
00176 {
00177         assert(pxa250Ptr);
00178 
00179         unsigned int address;
00180         unsigned int fileSize;
00181         unsigned int fileSizeAligned;
00182         unsigned int *data;
00183         bool halfword = false;
00184 
00185         if (argc < 2)
00186         {
00187                 printf(getDescr());
00188                 return 1;
00189         }
00190         else if (argc == 2)
00191         {
00192                 address = 0xa0000000;
00193         }
00194         else
00195         {
00196                 sscanf(argv[2], "%x", &address);
00197                 if (argc>= 4 && argv[3][0] == 'h')
00198                         halfword = true;
00199         }
00200 
00201         FILE *fp=fileManagerPtr->openFP(argv[1], "r");
00202         if (fp)
00203         {
00204                 // get file length
00205                 fseek(fp, 0, SEEK_END);
00206                 fileSize=ftell(fp);
00207                 fileSizeAligned = (fileSize&0x3) ? ((fileSize&(~0x3))+4) : fileSize;
00208                 fseek(fp, 0, SEEK_SET);
00209 
00210                 if (halfword) {
00211                         fileSizeAligned*=2;
00212                 }
00213 
00214                 // allocate array
00215                 data = (unsigned int *)malloc(fileSizeAligned);
00216 
00217                 // read data
00218                 if (halfword) {
00219                         for (unsigned int i=0; i<fileSizeAligned; i++) {
00220                                 unsigned short s;
00221                                 fread(&s, 2, 1, fp);
00222                                 data[i] = s;
00223                         }
00224                 } else {
00225                         fread(data, 1, fileSize, fp);
00226                 }
00227                 fclose(fp);
00228 
00229                 // put data into memory
00230                 long long startTick=GetTick();
00231                 printf("Sending %d words into the device's memory... ", fileSizeAligned / 4);
00232                 fflush(stdout);
00233                 pxa250Ptr->putData(address, fileSizeAligned / 4, data);
00234                 float duration= ((float)GetTick()-startTick)/1000.0f;
00235                 printf("done in %.3f s (%.3f KByte/s)\n", duration, fileSizeAligned/(duration*1000.0f));
00236 
00237                 /*
00238                    Verification phase, skipped
00239                 // get data from memory
00240                 printf("Verifying %d bytes from the device's memory", fileSize);
00241                 fflush(stdout);
00242                 pxa250Ptr->getData(address, fileSize, data);
00243                 printf("done\n");
00244                  */
00245 
00246                 free(data);
00247 
00248                 return 0;
00249         }
00250         else
00251                 return 1;
00252 }
00253 
00254 int PutCmd::exec(int argc, char *argv[])
00255 { 
00256         assert(pxa250Ptr);
00257 
00258         if (argc < 3)
00259         {
00260                 printf(getDescr());
00261                 return 1;
00262         }
00263 
00264         bool halfword = false;
00265         if ((argc >= 4) && (argv[3][0]=='h'))
00266                 halfword = true;
00267         
00268         unsigned int address, value;
00269         sscanf(argv[1], "%x", &address);
00270         sscanf(argv[2], "%x", &value);
00271         pxa250Ptr->putData(address, 1, &value, halfword);
00272 
00273         return 0;
00274 }
00275 
00276 int EraseFlashCmd::exec(int argc, char *argv[])
00277 {
00278         assert(pxa250Ptr);
00279         bool fullErase = false;
00280 
00281         // chip erase
00282         if (argc == 1)
00283                 fullErase = true;
00284 
00285         // erase command
00286         pxa250Ptr->putData(0x555 * 2, 0xaa, true);
00287         pxa250Ptr->putData(0x2aa * 2, 0x55, true);
00288         pxa250Ptr->putData(0x555 * 2, 0x80, true);
00289         pxa250Ptr->putData(0x555 * 2, 0xaa, true);
00290         pxa250Ptr->putData(0x2aa * 2, 0x55, true);
00291         
00292         // sector by sector or full
00293         unsigned int address, data;
00294         if (fullErase)
00295         {
00296                 // full chip erase command
00297                 address = 0x555 * 2; // we prepare address for the DQ7 polling next in the program
00298                 pxa250Ptr->putData(0x555 * 2, 0x10, true);
00299         }
00300         else
00301         {
00302                 // get address
00303                 unsigned int i;
00304                 for (i=1; i<(unsigned)argc; i++)
00305                 {
00306                         sscanf(argv[i], "%x", &address);
00307 
00308                         // wait for DQ3 == 0
00309                         do
00310                         {
00311                                 pxa250Ptr->getData(address, 1, &data);
00312                         } while ((data&(1<<3)) != 0);
00313 
00314                         // erase sector
00315                         pxa250Ptr->putData(address, 0x30, true);
00316                 }
00317         }
00318         
00319         // wait for DQ7 == 1
00320         do
00321         {
00322                 pxa250Ptr->getData(address, 1, &data);
00323         } while ((data&(1<<7)) == 0);
00324 
00325         return 0;
00326 }
00327 
00328 ProgramFlashCmd::ProgramFlashCmd(CmdLine &cmdLine) : cmdLine(cmdLine)
00329 {
00330 }
00331 
00338 int ProgramFlashCmd::exec(int argc, char *argv [])
00339 {
00340         assert(pxa250Ptr);
00341 
00342         unsigned int address, i;
00343         unsigned int fileSize;
00344         unsigned int fileSizeAligned;
00345         unsigned short *data;
00346 
00347         if (argc < 2)
00348         {
00349                 printf(getDescr());
00350                 return 1;
00351         }
00352         else if (argc == 2)
00353         {
00354                 address = 0x00000000;
00355         }
00356         else
00357         {
00358                 sscanf(argv[2], "%x", &address);
00359         }
00360 
00361         // check flash id, before continuing
00362         pxa250Ptr->putData(0x555 * 2, 0xaa, true);
00363         pxa250Ptr->putData(0x2aa * 2, 0x55, true);
00364         pxa250Ptr->putData(0x555 * 2, 0x90, true);
00365         unsigned flashid=0;
00366         pxa250Ptr->getData(0, 1, &flashid);
00367 
00368         if (flashid != 0x225b0052) {
00369                 printf("The flash is not AS29LV800B. Sorry.\n");
00370                 return 1;
00371         }
00372 
00373 
00374         FILE *fp=fileManagerPtr->openFP(argv[1], "r");
00375         if (fp)
00376         {
00377                 // get file length
00378                 fseek(fp, 0, SEEK_END);
00379                 fileSize=ftell(fp);
00380                 fileSizeAligned = (fileSize&0x1) ? fileSize+1 : fileSize;
00381                 fclose(fp);
00382 
00383                 // prepare the command line to call 'enp.lnj'
00384                 char call[256];
00385 
00387                 sprintf(call, "flash/enp.lnj %s %x %x\n", 
00388                                 argv[1],
00389                                 address,
00390                                 fileSize/2);
00391                 printf("calling: \"%s\"\n", call);
00392 
00393                 long long startTick=GetTick();
00394 
00395                 if (cmdLine.exec(call)) 
00396                         return 3;
00397                 
00398                 cmdLine.exec("wait");
00399 
00400                 printf("Embedded flasher returned %d\n", pxa250Ptr->getSavePlace(0));
00401 
00402                 float duration= ((float)GetTick()-startTick)/1000.0f;
00403                 printf("done in %.3f s (%.3f KByte/s)\n", duration, fileSizeAligned/(duration*1000.0f));
00404 
00405                 return 0;
00406         }
00407         else
00408                 return 2;
00409 }
00410 
00411 int GetCmd::exec(int argc, char *argv[])
00412 { 
00413         assert(pxa250Ptr);
00414         unsigned int address;
00415         unsigned int size;
00416         unsigned int *data;
00417 
00418         if (argc < 2)
00419         {
00420                 printf(getDescr());
00421                 return 1;
00422         }
00423         else if (argc == 2)
00424         {
00425                 size = 1;
00426         }
00427         else
00428         {
00429                 sscanf(argv[2], "%x", &size);
00430         }
00431 
00432         sscanf(argv[1], "%x", &address);
00433 
00434         data = (unsigned int *)malloc(size*sizeof(unsigned int));
00435         pxa250Ptr->getData(address, size, data);
00436         
00437         for (unsigned i=0; i<size; i++)
00438         {
00439                 printf("%08x : %08x\n", address+(i*4), data[i]);
00440         }
00441         
00442         free(data);
00443         
00444         return 0;
00445 }
00446 
00447 int ExecCmd::exec(int argc, char *argv[])
00448 {
00449         assert(pxa250Ptr);
00450         unsigned int address;
00451         unsigned int sp;
00452 
00453         if (argc<2)
00454         {
00455                 address=0xa0000000;
00456                 sp=0xa0000000+(64*1024*1024);
00457         }
00458         else if (argc<3)
00459         {
00460                 sscanf(argv[1], "%x", &address);
00461                 sp=0xa0000000+(64*1024*1024);
00462         }
00463         else
00464         {
00465                 sscanf(argv[1], "%x", &address);
00466                 sscanf(argv[2], "%x", &sp);
00467         }
00468 
00469         pxa250Ptr->execute(address, sp);
00470 
00471         return 0;
00472 }
00473 
00474 int ExtBreakCmd::exec(int argc, char *argv[]) {
00475         assert(pxa250Ptr);
00476         pxa250Ptr->extBreak();
00477 
00478         return 0;
00479 }
00480 
00481 int RebootCmd::exec(int argc, char *argv[]) {
00482         assert(pxa250Ptr);
00483         pxa250Ptr->reboot();
00484         return 0;
00485 }
00486 
00487 int ContinueCmd::exec(int argc, char *argv[]) {
00488         assert(pxa250Ptr);
00489         pxa250Ptr->continueCmd();
00490         return 0;
00491 }
00492 
00493 int RegisterCmd::exec(int argc, char *argv[]) {
00494         assert(pxa250Ptr);
00495         if (argc < 2) {
00496                 printf("%s",getDescr());
00497                 return 1;
00498         }
00499 
00500         unsigned int reg = strtoul(argv[1], 0, 10);
00501 
00502         if (argc >= 3) {
00503                 // this is a write
00504                 unsigned int val = strtoul(argv[2], 0, 16);
00505 
00506                 return pxa250Ptr->setSavePlace(reg, val) ? 0 : 2;
00507         } else {
00508                 // this is a read
00509                 unsigned int val = pxa250Ptr->getSavePlace(reg);
00510                 printf("Register %d = %08x (%d)\n", reg, val, val);
00511                 return 0;
00512         }
00513 }
00514 
00515 int HwBreakCmd::exec(int argc, char *argv[]) {
00516 
00517         if (argc < 2) {
00518                 printf("%s", getDescr());
00519                 return 1;
00520         }
00521 
00522         // activate or remove breakpoint ?
00523         bool enable;
00524 
00525         if (strcmp("on", argv[1]) == 0) {
00526                 enable = true;
00527         } else {
00528                 if (strcmp("off", argv[1]) == 0)
00529                         enable = false;
00530                 else {
00531                         printf("%s", getDescr());
00532                         return 2;
00533                 }
00534         }
00535 
00536         // at what address ?
00537         unsigned int addr;
00538         
00539         if (argc >= 3)
00540                 addr = strtoul(argv[2], 0, 16);
00541         else 
00542                 addr = pxa250Ptr->getSavePlace(15);
00543 
00544         JTAGpxa250::Cp15Reg reg=JTAGpxa250::IBCR0;
00545 
00546         if (argc >= 4) {
00547                 switch (argv[3][0]) {
00548                 case '0': reg = JTAGpxa250::IBCR0; break;
00549                 case '1': reg = JTAGpxa250::IBCR1; break;
00550                 default:
00551                         printf("%s", getDescr());
00552                         return 3;
00553                 }
00554         } 
00555 
00556         // now load the debug register
00557         if (pxa250Ptr->setCp15DebugRegister(addr | ( enable ? 1 : 0), reg))
00558                 return 0;
00559         else
00560                 return 4;
00561 }
00562                 
00563 int WaitCmd::exec(int argc, char *argv[]) {
00564         
00565         while (!pxa250Ptr->targetReady()) {
00566                 usleep(100);
00567                 pxa250Ptr->pollForTX();
00568         }
00569         return 0;
00570 }
00571         
00573 // CmdLine class implementation
00575 
00577 CmdLine::CmdLine() {
00578         commands.push_back(new InitCmd());
00579         commands.push_back(new CheckCmd());
00580         commands.push_back(new StopCmd());
00581         commands.push_back(new LoadICCmd());
00582         commands.push_back(new QuitCmd());
00583         commands.push_back(new ResetCmd());
00584         commands.push_back(new BootCmd());
00585         commands.push_back(new LoadCmd());
00586         commands.push_back(new PutCmd());
00587         commands.push_back(new GetCmd());
00588         commands.push_back(new ExecCmd());
00589         commands.push_back(new ExtBreakCmd());
00590         commands.push_back(new ContinueCmd());
00591         commands.push_back(new RebootCmd());
00592         commands.push_back(new RegisterCmd());
00593         commands.push_back(new HwBreakCmd());
00594         commands.push_back(new HelpCmd(commands));
00595         //commands.push_back(new EraseFlashCmd());
00596         commands.push_back(new WaitCmd());
00597         commands.push_back(new ProgramFlashCmd(*this));
00598 }
00599 
00601 CmdLine::~CmdLine() {
00602         std::vector<Command *>::iterator it;
00603         for (it = commands.begin(); it != commands.end(); ++it) {
00604                 delete *it;
00605                 *it = 0;
00606         }
00607 }
00608 
00625 int CmdLine::exec(const char *cmdLine, int argc, char **argv) {
00626         // copy the command line
00627         char *cmd = strdup(cmdLine);
00628         char *words[256];
00629         int nbWords = splitString(cmd, words, 256, " \t\r\n");
00630 
00631         assert(cmd);
00632         assert(words);
00633 
00634         // ignore comments and empty lines
00635         if ((nbWords==0) || (words[0][0] == '#')) {
00636                 free(cmd);
00637                 return 0;
00638         }
00639 
00640         // parameters replacement and comment ignoring
00641         for (int i=0; i< nbWords; i++) {
00642                 if (words[i][0] == '#') {
00643                         nbWords = i;
00644                         break;
00645                 } 
00646 
00647                 if (argc && words[i][0] == '\\' && isdigit(words[i][1])) {
00648                         long p = strtoul(words[i] + 1, 0, 10);
00649                         if (p < 0) p = 0;
00650                         if (p < argc)
00651                                 words[i] = argv[p];
00652                 }
00653         }
00654 
00655         // search for a matching command
00656         std::vector<Command *>::iterator it;
00657         for (it = commands.begin(); it != commands.end(); ++it) {
00658                 if (strcmp((*it)->getName(), words[0]) == 0) {
00659                         int ret= (*it)->exec(nbWords, words);
00660                         free(cmd);
00661                         return ret;
00662                 }
00663         }
00664 
00665         // look for a script of the corresponding name
00666         FILE *f = fileManagerPtr->openFP(words[0], "rt");
00667         if (f) {
00668                 char line[256];
00669                 int ln=0;
00670                 while (fgets(line, sizeof(line), f)) {
00671                         ln++;
00672                         debugMessage(CMD_SCRIPT_DEBUG, "%s:%d: %s\n", words[0], ln, line);
00673                         int r=exec(line, nbWords, words);
00674                         if (r) {
00675                                 printf("%s:%d: command returned %d\n", 
00676                                                 words[0], ln, r);
00677                                 fclose(f);
00678                                 free(cmd);
00679                                 return -3;
00680                         }
00681                                 
00682                 }
00683                 fclose(f);
00684                 free(cmd);
00685                 return 0;
00686         }
00687 
00688         fprintf(stderr, "%s: command not found\n", words[0]);
00689         free(cmd);
00690         return -2;
00691 }
00692 
00693 int CmdLine::getNextToken(const char *string, const char *delim) {
00694 
00695         for (int i=0; string[i]; i++) {
00696                 for (int c=0; delim[c]; c++) {
00697                         if (string[i] != delim[c])
00698                                 return i;
00699                 }
00700         }
00701         return -1;
00702 }
00703 
00704 
00716 int CmdLine::splitString(char *inputString, char **outputArray, 
00717                         unsigned arraySize, const char *delimiters)
00718 {
00719         char *c;
00720         unsigned arrayPos=0;
00721         int inWord = 0;
00722 
00723         if (!inputString) return 0;
00724         for (c= inputString; *c; c++) {
00725                 if (index(delimiters, *c)) {
00726                         *c = 0;
00727                         inWord = 0;
00728                 } else {
00729                         if (!inWord && arrayPos < arraySize) {
00730                                 inWord = 1;
00731                                 outputArray[arrayPos++] = c;
00732                         }
00733                 }
00734         }
00735         return arrayPos;
00736 }
00737 

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