From eb99256e6887be73b98d9cb232d8acfc8358b658 Mon Sep 17 00:00:00 2001 From: Marcel Telka Date: Sun, 16 Feb 2003 22:28:52 +0000 Subject: [PATCH] 2003-02-16 Marcel Telka * src/jtag.c (jtag_creae_jtagdir): New function (Alessandro Zummo). (jtag_load_history): Ditto. (jtag_save_history): Ditto. (jtag_readline_loop): Ditto. (jtag_parse_file): Ditto. (jtag_parse_rc): Ditto. (jtag_parse_line): New funcion, content extracted from main function, added new 'script' command (Alessandro Zummo). (main): Moved parsing capability to jtag_parse_line function (Alessandro Zummo). git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@360 b68d4a1b-bc3d-0410-92ed-d4ac073336b7 --- jtag/ChangeLog | 12 ++ jtag/NEWS | 3 +- jtag/TODO | 1 - jtag/src/jtag.c | 385 ++++++++++++++++++++++++++++++++++-------------- 4 files changed, 292 insertions(+), 109 deletions(-) diff --git a/jtag/ChangeLog b/jtag/ChangeLog index 3d82fc25..3790fb6f 100644 --- a/jtag/ChangeLog +++ b/jtag/ChangeLog @@ -1,3 +1,15 @@ +2003-02-16 Marcel Telka + + * src/jtag.c (jtag_creae_jtagdir): New function (Alessandro Zummo). + (jtag_load_history): Ditto. + (jtag_save_history): Ditto. + (jtag_readline_loop): Ditto. + (jtag_parse_file): Ditto. + (jtag_parse_rc): Ditto. + (jtag_parse_line): New funcion, content extracted from main function, added new + 'script' command (Alessandro Zummo). + (main): Moved parsing capability to jtag_parse_line function (Alessandro Zummo). + 2003-02-16 Marcel Telka * src/flash.c (flash_drivers): Added missing 1 x 16 Intel flash driver. diff --git a/jtag/NEWS b/jtag/NEWS index a77ba56e..a7628d0e 100644 --- a/jtag/NEWS +++ b/jtag/NEWS @@ -11,9 +11,10 @@ $Id$ * Added JTAG declarations for Xilinx XC2C256-TQ144 (Alessandro Zummo). * Added support for 1 x 16 bit memory configuration (Christian Pellegrin). * Added buffered file reads/writes (Christian Pellegrin). - * Added command history load/save support (August Hörandl). * Added support for flash drivers (August Hörandl). * Added flash driver for AMD chips (August Hörandl). + * Added support for rc and history files (Alessandro Zummo). + * Added new 'script' command (Alessandro Zummo). * Some bugs fixed. jtag-0.2.2 (2003-02-04): diff --git a/jtag/TODO b/jtag/TODO index d6a2da33..7d208e08 100644 --- a/jtag/TODO +++ b/jtag/TODO @@ -2,7 +2,6 @@ $Id$ * Add 'get signal' command. * Add support for non-IDCODE-capable parts. -* Add support for script execution and .jtagrc. * Support for display the result of a boundary scan formated according to the CPU definitions (e.g. MA[0-26] = 0x00001c00). * Remove direct relation between JTAG instruction and data register (e.g. ARM7TDMI). * Configurable big endian vs. little endian access. diff --git a/jtag/src/jtag.c b/jtag/src/jtag.c index 4ab44b8a..6f552050 100644 --- a/jtag/src/jtag.c +++ b/jtag/src/jtag.c @@ -28,6 +28,8 @@ #include #include +#include +#include #include #include @@ -39,7 +41,7 @@ #include "bus.h" cable_driver_t *cable = NULL; - +parts *ps = NULL; bus_driver_t *bus_driver = NULL; static char * @@ -57,46 +59,103 @@ void help( const char *cmd ); void discovery( const char *filename ); -int -main( void ) +int jtag_parse_file( const char *filename ); + +#define JTAGDIR ".jtag" +#define HISTORYFILE "history" +#define RCFILE "rc" + +void +jtag_create_jtagdir( void ) { - char *line = NULL; - parts *ps = NULL; + char *home = getenv( "HOME" ); + char *jdir; - printf( - "%s\n" - "Copyright (C) 2002, 2003 ETC s.r.o.\n" - "%s is free software, covered by the GNU General Public License, and you are\n" - "welcome to change it and/or distribute copies of it under certain conditions.\n" - "There is absolutely no warranty for %s.\n\n", PACKAGE_STRING, PACKAGE, PACKAGE - ); + if (!home) + return; - printf( "Warning: %s may damage your hardware! Type \"quit\" for exit!\n\n", PACKAGE ); - printf( "Type \"help\" for help.\n\n" ); + jdir = malloc( strlen(home) + strlen(JTAGDIR) + 2 ); /* "/" and trailing \0 */ + if (!jdir) + return; + + strcpy( jdir, home ); + strcat( jdir, "/" ); + strcat( jdir, JTAGDIR ); + + /* Create the directory if it doesn't exists. */ + mkdir( jdir, 0755 ); + + free( jdir ); +} + +void +jtag_load_history( void ) +{ + char *home = getenv( "HOME" ); + char *file; using_history(); - read_history(".jtag_history"); - for (;;) { - char *t; + if (!home) + return; - free( line ); - line = readline( "jtag> " ); + file = malloc( strlen(home) + strlen(JTAGDIR) + strlen(HISTORYFILE) + 3 ); /* 2 x "/" and trailing \0 */ + if (!file) + return; + + strcpy( file, home ); + strcat( file, "/" ); + strcat( file, JTAGDIR ); + strcat( file, "/" ); + strcat( file, HISTORYFILE ); + + read_history( file ); - if (!line || !*line) - continue; - add_history( line ); + free( file ); +} + +void +jtag_save_history( void ) +{ + char *home = getenv( "HOME" ); + char *file; + + if (!home) + return; + + file = malloc( strlen(home) + strlen(JTAGDIR) + strlen(HISTORYFILE) + 3); /* 2 x "/" and trailing \0 */ + if (!file) + return; + + strcpy( file, home ); + strcat( file, "/" ); + strcat( file, JTAGDIR ); + strcat( file, "/"); + strcat( file, HISTORYFILE ); + + write_history( file ); + + free( file ); +} + +int +jtag_parse_line( char *line ) +{ + char *t; + + if (!line || !(strlen( line ) > 0)) + return 1; t = get_token( line ); if (!t) - continue; + return 1; if (strcmp( t, "quit" ) == 0) { if (get_token( NULL )) { printf( "quit: syntax error\n\nType \"help\" for help.\n\n" ); - continue; + return 1; } - break; + return 0; } if (strcmp( t, "help" ) == 0) { @@ -105,7 +164,7 @@ main( void ) printf( "help: Syntax error!\n" ); else help( t ); - continue; + return 1; } if (strcmp( t, "frequency" ) == 0) { @@ -114,22 +173,22 @@ main( void ) t = get_token( NULL ); if (!t) { printf( "Missing argument(s)\n" ); - continue; + return 1; } if ((sscanf( t, "0x%x", &freq ) != 1) && (sscanf( t, "%u", &freq ) != 1)) { printf( "syntax error\n" ); - continue; + return 1; } if (get_token( NULL )) { printf( "frequency: syntax error\n" ); - continue; + return 1; } printf( "Setting TCK frequency to %u Hz\n", freq ); frequency = freq; - continue; + return 1; } if (strcmp( t, "cable" ) == 0) { @@ -139,38 +198,38 @@ main( void ) t = get_token( NULL ); if (!t) { printf( "Missing argument(s)\n" ); - continue; + return 1; } if (strcmp( t, "parallel" ) != 0) { printf( "syntax error!\n" ); - continue; + return 1; } t = get_token( NULL ); if (!t) { printf( "Missing argument(s)\n" ); - continue; + return 1; } if ((sscanf( t, "0x%x", &port ) != 1) && (sscanf( t, "%d", &port ) != 1)) { printf( "syntax error\n" ); - continue; + return 1; } t = get_token( NULL ); if (!t) { printf( "Missing argument(s)\n" ); - continue; + return 1; } if (get_token( NULL )) { printf( "syntax error!\n" ); - continue; + return 1; } if (strcmp( t, "none" ) == 0) { printf( "Changed cable to 'none'\n" ); cable = NULL; - continue; + return 1; } for (i = 0; cable_drivers[i]; i++) @@ -179,7 +238,7 @@ main( void ) if (!cable_drivers[i]) { printf( "Unknown cable: %s\n", t ); - continue; + return 1; } cable = cable_drivers[i]; @@ -187,44 +246,44 @@ main( void ) if (!cable->init( port )) { printf( "Error: Cable driver initialization failed!\n" ); cable = NULL; - continue; + return 1; } cable->set_trst( 0 ); cable->set_trst( 1 ); tap_reset(); - continue; + return 1; } if (strcmp( t, "discovery" ) == 0) { if (!cable) { printf( "Error: Cable not configured. Use 'cable' command first!\n" ); - continue; + return 1; } t = get_token( NULL ); if (!t) { printf( "discovery: missing filename\n" ); - continue; + return 1; } if (get_token( NULL )) { printf( "syntax error!\n" ); - continue; + return 1; } discovery( t ); - continue; + return 1; } if (strcmp( t, "detect" ) == 0) { if (!cable) { printf( "Error: Cable not configured. Use 'cable' command first!\n" ); - continue; + return 1; } if (get_token( NULL )) { printf( "detect: syntax error\n" ); - continue; + return 1; } parts_free( ps ); @@ -232,7 +291,7 @@ main( void ) if (!ps->len) { parts_free( ps ); ps = NULL; - continue; + return 1; } parts_set_instruction( ps, "SAMPLE/PRELOAD" ); parts_shift_instructions( ps ); @@ -245,7 +304,7 @@ main( void ) bus_driver = &pxa250_bus_driver; if (strcmp( ps->parts[0]->part, "IXP425" ) == 0) bus_driver = &ixp425_bus_driver; - continue; + return 1; } if (strcmp( t, "flashmem" ) == 0) { @@ -255,23 +314,23 @@ main( void ) if (!cable) { printf( "Error: Cable not configured. Use 'cable' command first!\n" ); - continue; + return 1; } if (!ps) { printf( "Run \"detect\" first.\n" ); - continue; + return 1; } t = get_token( NULL ); if (!t) { printf( "flashmem: Missing argument(s)\n" ); - continue; + return 1; } if (strcmp( t, "msbin" ) != 0) { if ((sscanf( t, "0x%x", &addr ) != 1) && (sscanf( t, "%d", &addr ) != 1)) { printf( "error\n" ); - continue; + return 1; } printf( "0x%08X\n", addr ); } else @@ -280,23 +339,23 @@ main( void ) t = get_token( NULL ); if (!t) { printf( "flashmem: missing filename\n" ); - continue; + return 1; } if (get_token( NULL )) { printf( "syntax error!\n" ); - continue; + return 1; } f = fopen( t, "r" ); if (!f) { printf( "Unable to open file `%s'!\n", t ); - continue; + return 1; } if (msbin) flashmsbin( ps, f ); else flashmem( ps, f, addr ); fclose( f ); - continue; + return 1; } if (strcmp( t, "readmem" ) == 0) { @@ -306,89 +365,89 @@ main( void ) if (!cable) { printf( "Error: Cable not configured. Use 'cable' command first!\n" ); - continue; + return 1; } if (!ps) { printf( "Run \"detect\" first.\n" ); - continue; + return 1; } t = get_token( NULL ); if (!t) { printf( "flashmem: Missing argument(s)\n" ); - continue; + return 1; } if ((sscanf( t, "0x%x", &addr ) != 1) && (sscanf( t, "%d", &addr ) != 1)) { printf( "syntax error\n" ); - continue; + return 1; } t = get_token( NULL ); if (!t) { printf( "flashmem: Missing argument(s)\n" ); - continue; + return 1; } if ((sscanf( t, "0x%x", &len ) != 1) && (sscanf( t, "%d", &len ) != 1)) { printf( "syntax error\n" ); - continue; + return 1; } /* filename */ t = get_token( NULL ); if (!t) { printf( "flashmem: missing filename\n" ); - continue; + return 1; } if (get_token( NULL )) { printf( "syntax error!\n" ); - continue; + return 1; } f = fopen( t, "w" ); if (!f) { printf( "Unable to create file `%s'!\n", t ); - continue; + return 1; } readmem( ps, f, addr, len ); fclose( f ); - continue; + return 1; } if (strcmp( t, "detectflash" ) == 0) { if (get_token( NULL )) { printf( "detectflash: syntax error\n" ); - continue; + return 1; } if (!cable) { printf( "Error: Cable not configured. Use 'cable' command first!\n" ); - continue; + return 1; } if (!ps) { printf( "Run \"detect\" first.\n" ); - continue; + return 1; } detectflash( ps ); - continue; + return 1; } if (strcmp( t, "print" ) == 0) { if (get_token( NULL )) { printf( "print: syntax error\n" ); - continue; + return 1; } if (!cable) { printf( "Error: Cable not configured. Use 'cable' command first!\n" ); - continue; + return 1; } parts_print( ps, 1 ); - continue; + return 1; } if (strcmp( t, "instruction" ) == 0) { @@ -396,69 +455,69 @@ main( void ) if (!cable) { printf( "Error: Cable not configured. Use 'cable' command first!\n" ); - continue; + return 1; } if (!ps) { printf( "Run \"detect\" first.\n" ); - continue; + return 1; } t = get_token( NULL ); if (!t) { printf( "instruction: syntax error\n" ); - continue; + return 1; } n = strtol( t, &t, 10 ); if (t && *t) { printf( "instruction: syntax error\n" ); - continue; + return 1; } if ((n < 0) || (n >= ps->len)) { printf( "instruction: invalid part number\n" ); - continue; + return 1; } t = get_token( NULL ); if (!t) { printf( "instruction: missing instruction name\n" ); - continue; + return 1; } if (get_token( NULL )) { printf( "instruction: syntax error\n" ); - continue; + return 1; } part_set_instruction( ps->parts[n], t ); if (ps->parts[n]->active_instruction == NULL) printf( "instruction: unknown instruction %s\n", t ); - continue; + return 1; } if (strcmp( t, "shift" ) == 0) { if (!cable) { printf( "Error: Cable not configured. Use 'cable' command first!\n" ); - continue; + return 1; } t = get_token( NULL ); if (t && (strcmp( t, "ir" ) == 0)) { parts_shift_instructions( ps ); - continue; + return 1; } if (t && (strcmp( t, "dr" ) == 0)) { parts_shift_data_registers( ps ); - continue; + return 1; } printf( "shift: syntax error\n" ); - continue; + return 1; } if (strcmp( t, "dr" ) == 0) { @@ -468,29 +527,29 @@ main( void ) if (!cable) { printf( "Error: Cable not configured. Use 'cable' command first!\n" ); - continue; + return 1; } if (!ps) { printf( "Run \"detect\" first.\n" ); - continue; + return 1; } t = get_token( NULL ); if (!t) { printf( "dr: syntax error\n" ); - continue; + return 1; } n = strtol( t, &t, 10 ); if (t && *t) { printf( "dr: syntax error\n" ); - continue; + return 1; } if ((n < 0) || (n >= ps->len)) { printf( "dr: invalid part number\n" ); - continue; + return 1; } t = get_token( NULL ); @@ -503,12 +562,12 @@ main( void ) dir = 1; else { printf( "dr: syntax error\n" ); - continue; + return 1; } if (get_token( NULL )) { printf( "dr: syntax error\n" ); - continue; + return 1; } } @@ -518,7 +577,7 @@ main( void ) r = ps->parts[n]->active_instruction->data_register->in; printf( "%s\n", register_get_string( r ) ); - continue; + return 1; } if (strcmp( t, "set" ) == 0) { @@ -529,46 +588,46 @@ main( void ) if (!cable) { printf( "Error: Cable not configured. Use 'cable' command first!\n" ); - continue; + return 1; } if (!ps) { printf( "Run \"detect\" first.\n" ); - continue; + return 1; } t = get_token( NULL ); if (!t || strcmp( t, "signal" ) != 0) { printf( "set: syntax error\n" ); - continue; + return 1; } t = get_token( NULL ); if (!t) { printf( "set: syntax error\n" ); - continue; + return 1; } n = strtol( t, &t, 10 ); if (t && *t) { printf( "set: syntax error\n" ); - continue; + return 1; } if ((n < 0) || (n >= ps->len)) { printf( "set: invalid part number\n" ); - continue; + return 1; } s = get_token( NULL ); /* signal name */ if (!s) { printf( "set: syntax error\n" ); - continue; + return 1; } t = get_token( NULL ); /* direction */ if (!t || (strcmp( t, "in" ) != 0 && strcmp( t, "out" ) != 0)) { printf( "set: syntax error\n" ); - continue; + return 1; } dir = (strcmp( t, "in" ) == 0) ? 0 : 1; @@ -577,27 +636,140 @@ main( void ) data = strtol( t, &t, 10 ); if (t && *t) { printf( "set: syntax error\n" ); - continue; + return 1; } if ((data < 0) || (data > 1)) { printf( "set: invalid data value\n" ); - continue; + return 1; } } else data = 0; part_set_signal( ps->parts[n], s, dir, data ); - continue; + return 1; + } + + if (strcmp( t, "script" ) == 0) { + t = get_token( NULL ); /* filename */ + if (!t) { + printf( "script: missing filename\n" ); + return 1; + } + if (get_token( NULL )) { + printf( "script: syntax error\n" ); + return 1; + } + + jtag_parse_file( t ); + + return 1; } printf( "%s: unknown command\n", t ); - } + return 1; +} + +void +jtag_readline_loop( const char *prompt ) +{ + char *line = NULL; + + /* Iterate */ + while (jtag_parse_line( line )) { + free( line ); + + /* Read a line from the terminal */ + line = readline( prompt ); + + /* Check if we actually got something */ + if (line && (strlen( line ) > 0)) + add_history( line ); + } free( line ); - parts_free( ps ); +} + +int +jtag_parse_file( const char *filename ) +{ + FILE *f; + int go = 1; + char *line = NULL; + int n; + + f = fopen( filename, "r" ); + if (!f) { + printf( "Unable to open file `%s'!\n", filename); + return 1; + } + + while (getline( &line, &n, f ) != -1) + if (strlen(line) > 0) + go = jtag_parse_line(line); + + free(line); + fclose(f); + + return go; +} + +void +jtag_parse_rc( void ) +{ + char *home = getenv( "HOME" ); + char *file; + + if (!home) + return; + + file = malloc( strlen(home) + strlen(JTAGDIR) + strlen(RCFILE) + 3 ); /* 2 x "/" and trailing \0 */ + if (!file) + return; + strcpy( file, home ); + strcat( file, "/" ); + strcat( file, JTAGDIR ); + strcat( file, "/" ); + strcat( file, RCFILE ); + + jtag_parse_file( file ); + + free( file ); +} + +int +main( void ) +{ + printf( + "%s\n" + "Copyright (C) 2002, 2003 ETC s.r.o.\n" + "%s is free software, covered by the GNU General Public License, and you are\n" + "welcome to change it and/or distribute copies of it under certain conditions.\n" + "There is absolutely no warranty for %s.\n\n", PACKAGE_STRING, PACKAGE, PACKAGE + ); + + printf( "Warning: %s may damage your hardware! Type \"quit\" for exit!\n\n", PACKAGE ); + printf( "Type \"help\" for help.\n\n" ); + + /* Create ~/.jtag */ + jtag_create_jtagdir(); + + /* Parse and execute the RC file */ + jtag_parse_rc(); + + /* Load history */ + jtag_load_history(); + + /* main loop */ + jtag_readline_loop( "jtag> " ); + + /* Save history */ + jtag_save_history(); + + parts_free( ps ); + if (cable) { cable->set_trst( 0 ); cable->set_trst( 1 ); @@ -607,6 +779,5 @@ main( void ) cable = NULL; } - write_history(".jtag_history"); return 0; }