1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
21 #define OPENOCD_VERSION "Open On-Chip Debugger " VERSION " (" PKGBLDDATE ") svn:" PKGBLDREV
30 #include "configuration.h"
31 #include "interpreter.h"
40 #include "telnet_server.h"
41 #include "gdb_server.h"
42 #include "tcl_server.h"
45 #include <sys/types.h>
54 /* Jim is provied by eCos */
55 #include <cyg/jimtcl/jim.h>
64 int launchTarget(struct command_context_s
*cmd_ctx
)
67 /* Try to examine & validate jtag chain, though this may require a reset first
68 * in which case we continue setup */
71 /* try to examine target at this point. If it fails, perhaps a reset will
72 * bring it up later on via a telnet/gdb session */
73 target_examine(cmd_ctx
);
75 retval
=flash_init_drivers(cmd_ctx
);
78 LOG_DEBUG("flash init complete");
80 retval
=nand_init(cmd_ctx
);
83 LOG_DEBUG("NAND init complete");
85 retval
=pld_init(cmd_ctx
);
88 LOG_DEBUG("pld init complete");
92 /* Give TELNET a way to find out what version this is */
93 int handle_version_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
95 command_print(cmd_ctx
, OPENOCD_VERSION
);
100 static int daemon_startup
= 0;
102 int handle_daemon_startup_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
107 return ERROR_COMMAND_SYNTAX_ERROR
;
109 daemon_startup
= strcmp("reset", args
[0])==0;
111 command_print(cmd_ctx
, OPENOCD_VERSION
);
117 void exit_handler(void)
119 /* close JTAG interface */
120 if (jtag
&& jtag
->quit
)
125 /* OpenOCD can't really handle failure of this command. Patches welcome! :-) */
126 int handle_init_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
129 static int initialized
=0;
135 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
137 atexit(exit_handler
);
140 if (target_init(cmd_ctx
) != ERROR_OK
)
142 LOG_DEBUG("target init complete");
144 if ((retval
=jtag_interface_init(cmd_ctx
)) != ERROR_OK
)
146 /* we must be able to set up the jtag interface */
149 LOG_DEBUG("jtag interface init complete");
151 /* Try to initialize & examine the JTAG chain at this point, but
152 * continue startup regardless
154 if (jtag_init(cmd_ctx
) == ERROR_OK
)
156 LOG_DEBUG("jtag init complete");
157 if (target_examine(cmd_ctx
) == ERROR_OK
)
159 LOG_DEBUG("jtag examine complete");
164 if (flash_init_drivers(cmd_ctx
) != ERROR_OK
)
166 LOG_DEBUG("flash init complete");
168 if (nand_init(cmd_ctx
) != ERROR_OK
)
170 LOG_DEBUG("NAND init complete");
172 if (pld_init(cmd_ctx
) != ERROR_OK
)
174 LOG_DEBUG("pld init complete");
176 /* initialize tcp server */
179 /* initialize telnet subsystem */
180 telnet_init("Open On-Chip Debugger");
182 tcl_init(); /* allows tcl to just connect without going thru telnet */
189 void unlockBigLock();
194 command_context_t
*active_cmd_ctx
;
197 new_int_array_element( Jim_Interp
* interp
,
203 Jim_Obj
*nameObjPtr
, *valObjPtr
;
206 namebuf
= alloc_printf("%s(%d)", varname
, idx
);
209 nameObjPtr
= Jim_NewStringObj(interp
, namebuf
, -1);
210 valObjPtr
= Jim_NewIntObj(interp
, val
);
211 Jim_IncrRefCount(nameObjPtr
);
212 Jim_IncrRefCount(valObjPtr
);
213 result
= Jim_SetVariable(interp
, nameObjPtr
, valObjPtr
);
214 Jim_DecrRefCount(interp
, nameObjPtr
);
215 Jim_DecrRefCount(interp
, valObjPtr
);
217 // printf( "%s = 0%08x\n", namebuf, val );
222 Jim_Command_mem2array( Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
236 /* argv[1] = name of array to receive the data
237 * argv[2] = desired width
238 * argv[3] = memory address
239 * argv[4] = length in bytes to read
242 Jim_WrongNumArgs( interp
, 1, argv
, "varname width addr nelems" );
245 varname
= Jim_GetString( argv
[1], &len
);
246 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
249 e
= Jim_GetLong( interp
, argv
[2], &l
);
255 e
= Jim_GetLong( interp
, argv
[3], &l
);
260 e
= Jim_GetLong( interp
, argv
[4], &l
);
276 Jim_SetResult(interp
,
277 Jim_NewEmptyStringObj(interp
));
278 Jim_AppendStrings( interp
, Jim_GetResult(interp
),
279 "Invalid width param, must be 8/16/32", NULL
);
283 Jim_SetResult(interp
,
284 Jim_NewEmptyStringObj(interp
));
285 Jim_AppendStrings( interp
, Jim_GetResult(interp
),
286 "mem2array: zero width read?", NULL
);
289 if( (addr
+ (len
* width
)) < addr
){
290 Jim_SetResult(interp
,
291 Jim_NewEmptyStringObj(interp
));
292 Jim_AppendStrings( interp
, Jim_GetResult(interp
),
293 "mem2array: addr + len - wraps to zero?", NULL
);
296 /* absurd transfer size? */
298 Jim_SetResult(interp
,
299 Jim_NewEmptyStringObj(interp
));
300 Jim_AppendStrings( interp
, Jim_GetResult(interp
),
301 "mem2array: absurd > 64K item request", NULL
);
306 ((width
== 2) && ((addr
& 1) == 0)) ||
307 ((width
== 4) && ((addr
& 3) == 0)) ){
311 Jim_SetResult(interp
,
312 Jim_NewEmptyStringObj(interp
));
314 "mem2array address: 0x%08x is not aligned for %d byte reads",
317 Jim_AppendStrings( interp
, Jim_GetResult(interp
),
322 target
= get_current_target( active_cmd_ctx
);
332 /* Slurp... in buffer size chunks */
334 count
= len
; /* in objects.. */
335 if( count
> (sizeof(buffer
)/width
)){
336 count
= (sizeof(buffer
)/width
);
339 retval
= target
->type
->read_memory( target
,
345 if( retval
!= ERROR_OK
){
347 LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed",
348 addr
, width
, count
);
349 Jim_SetResult(interp
,
350 Jim_NewEmptyStringObj(interp
));
351 Jim_AppendStrings( interp
, Jim_GetResult(interp
),
352 "mem2array: cannot read memory", NULL
);
356 v
= 0; /* shut up gcc */
357 for( i
= 0 ; i
< count
; i
++, n
++ ){
360 v
= target_buffer_get_u32( target
, &buffer
[i
*width
] );
363 v
= target_buffer_get_u16( target
, &buffer
[i
*width
] );
366 v
= buffer
[i
] & 0x0ff;
369 new_int_array_element( interp
, varname
, n
, v
);
374 Jim_SetResult(interp
,
375 Jim_NewEmptyStringObj(interp
));
380 static void tcl_output(void *privData
, const char *file
, int line
,
381 const char *function
, const char *string
)
383 Jim_Obj
*tclOutput
=(Jim_Obj
*)privData
;
385 Jim_AppendString(interp
, tclOutput
, string
, strlen(string
));
388 /* try to execute as Jim command, otherwise fall back to standard command.
390 Note that even if the Jim command caused an error, then we succeeded
391 to execute it, hence this fn pretty much always returns ERROR_OK.
394 int jim_command(command_context_t
*context
, char *line
)
397 /* FIX!!!! in reality there is only one cmd_ctx handler, but consider
398 what might happen here if there are multiple handlers w/reentrant callback
400 active_cmd_ctx
=context
;
401 int retcode
=Jim_Eval(interp
, line
);
405 result
= Jim_GetString(Jim_GetResult(interp
), &reslen
);
406 if (retcode
== JIM_ERR
) {
409 LOG_USER_N("Runtime error, file \"%s\", line %d:" JIM_NL
,
410 interp
->errorFileName
, interp
->errorLine
);
411 LOG_USER_N(" %s" JIM_NL
,
412 Jim_GetString(interp
->result
, NULL
));
413 Jim_ListLength(interp
, interp
->stackTrace
, &len
);
414 for (i
= 0; i
< len
; i
+= 3) {
416 const char *proc
, *file
, *line
;
418 Jim_ListIndex(interp
, interp
->stackTrace
, i
, &objPtr
, JIM_NONE
);
419 proc
= Jim_GetString(objPtr
, NULL
);
420 Jim_ListIndex(interp
, interp
->stackTrace
, i
+1, &objPtr
,
422 file
= Jim_GetString(objPtr
, NULL
);
423 Jim_ListIndex(interp
, interp
->stackTrace
, i
+2, &objPtr
,
425 line
= Jim_GetString(objPtr
, NULL
);
426 LOG_USER_N("In procedure '%s' called at file \"%s\", line %s" JIM_NL
,
429 } else if (retcode
== JIM_EXIT
) {
431 //exit(Jim_GetExitCode(interp));
436 for (i
=0; i
<reslen
; i
+=256)
442 strncpy(buff
, result
, chunk
);
444 LOG_USER_N("%s", buff
);
446 LOG_USER_N("%s", "\n");
455 Jim_Command_openocd_ignore(Jim_Interp
*interp
,
457 Jim_Obj
*const *argv
,
461 char *cmd
= (char*)Jim_GetString(argv
[1], NULL
);
465 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
469 // We don't know whether or not the telnet/gdb server is running...
470 target_call_timer_callbacks_now();
473 log_add_callback(tcl_output
, tclOutput
);
474 retval
=command_run_line_internal(active_cmd_ctx
, cmd
);
478 target_call_timer_callbacks_now();
480 log_remove_callback(tcl_output
, tclOutput
);
482 Jim_SetResult(interp
, tclOutput
);
485 return (ignore
||(retval
==ERROR_OK
))?JIM_OK
:JIM_ERR
;
489 Jim_Command_openocd(Jim_Interp
*interp
,
491 Jim_Obj
*const *argv
)
493 return Jim_Command_openocd_ignore(interp
, argc
, argv
, 1);
497 Jim_Command_openocd_throw(Jim_Interp
*interp
,
499 Jim_Obj
*const *argv
)
501 return Jim_Command_openocd_ignore(interp
, argc
, argv
, 0);
507 /* find full path to file */
509 Jim_Command_find(Jim_Interp
*interp
,
511 Jim_Obj
*const *argv
)
515 char *file
= (char*)Jim_GetString(argv
[1], NULL
);
516 char *full_path
=find_file(file
);
519 Jim_Obj
*result
= Jim_NewStringObj(interp
, full_path
, strlen(full_path
));
522 Jim_SetResult(interp
, result
);
527 Jim_Command_echo(Jim_Interp
*interp
,
529 Jim_Obj
*const *argv
)
533 char *str
= (char*)Jim_GetString(argv
[1], NULL
);
538 void command_output_text( command_context_t
*context
, const char *data
);
541 openocd_jim_fwrite( const void *_ptr
, size_t size
, size_t n
, void *cookie
)
546 /* make it a char easier to read code */
554 if( !active_cmd_ctx
){
555 /* FIXME: Where should this go? */
560 /* do we have to chunk it? */
561 if( ptr
[ nbytes
] == 0 ){
562 /* no it is a C style string */
563 command_output_text( active_cmd_ctx
, ptr
);
566 /* GRR we must chunk - not null terminated */
576 memcpy( chunk
, ptr
, x
);
580 command_output_text( active_cmd_ctx
, chunk
);
589 openocd_jim_fread(void *ptr
, size_t size
, size_t n
, void *cookie
)
591 /* TCL wants to read... tell him no */
597 openocd_jim_vfprintf( void *cookie
, const char *fmt
, va_list ap
)
603 if( active_cmd_ctx
){
604 cp
= alloc_vprintf( fmt
, ap
);
606 command_output_text( active_cmd_ctx
, cp
);
615 openocd_jim_fflush( void *cookie
)
617 /* nothing to flush */
622 openocd_jim_fgets( char *s
, int size
, void *cookie
)
633 Jim_CreateCommand(interp
, "openocd", Jim_Command_openocd
, NULL
, NULL
);
634 Jim_CreateCommand(interp
, "openocd_throw", Jim_Command_openocd_throw
, NULL
, NULL
);
635 Jim_CreateCommand(interp
, "find", Jim_Command_find
, NULL
, NULL
);
636 Jim_CreateCommand(interp
, "echo", Jim_Command_echo
, NULL
, NULL
);
637 Jim_CreateCommand(interp
, "mem2array", Jim_Command_mem2array
, NULL
, NULL
);
639 /* Set Jim's STDIO */
640 interp
->cookie_stdin
= NULL
;
641 interp
->cookie_stdout
= NULL
;
642 interp
->cookie_stderr
= NULL
;
643 interp
->cb_fwrite
= openocd_jim_fwrite
;
644 interp
->cb_fread
= openocd_jim_fread
;
645 interp
->cb_vfprintf
= openocd_jim_vfprintf
;
646 interp
->cb_fflush
= openocd_jim_fflush
;
647 interp
->cb_fgets
= openocd_jim_fgets
;
650 /* after command line parsing */
653 Jim_Eval(interp
, "source [find tcl/commands.tcl]");
656 command_context_t
*setup_command_handler()
658 command_context_t
*cmd_ctx
;
660 cmd_ctx
= command_init();
662 register_command(cmd_ctx
, NULL
, "version", handle_version_command
,
663 COMMAND_EXEC
, "show OpenOCD version");
664 register_command(cmd_ctx
, NULL
, "daemon_startup", handle_daemon_startup_command
, COMMAND_CONFIG
,
665 "deprecated - use \"init\" and \"reset\" at end of startup script instead");
667 /* register subsystem commands */
668 server_register_commands(cmd_ctx
);
669 telnet_register_commands(cmd_ctx
);
670 gdb_register_commands(cmd_ctx
);
671 tcl_register_commands(cmd_ctx
); /* tcl server commands */
672 log_register_commands(cmd_ctx
);
673 jtag_register_commands(cmd_ctx
);
674 interpreter_register_commands(cmd_ctx
);
675 xsvf_register_commands(cmd_ctx
);
676 target_register_commands(cmd_ctx
);
677 flash_register_commands(cmd_ctx
);
678 nand_register_commands(cmd_ctx
);
679 pld_register_commands(cmd_ctx
);
681 if (log_init(cmd_ctx
) != ERROR_OK
)
685 LOG_DEBUG("log init complete");
687 LOG_OUTPUT( OPENOCD_VERSION
"\n" );
690 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
691 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
692 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
693 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
694 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
695 LOG_OUTPUT( "$URL$\n");
696 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
697 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
698 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
699 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
700 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
702 register_command(cmd_ctx
, NULL
, "init", handle_init_command
,
703 COMMAND_ANY
, "initializes target and servers - nop on subsequent invocations");
709 normally this is the main() function entry, but if OpenOCD is linked
710 into application, then this fn will not be invoked, but rather that
711 application will have it's own implementation of main().
713 int openocd_main(int argc
, char *argv
[])
717 /* Create an interpreter */
718 interp
= Jim_CreateInterp();
719 /* Add all the Jim core commands */
720 Jim_RegisterCoreCommands(interp
);
725 /* initialize commandline interface */
726 command_context_t
*cmd_ctx
;
727 cmd_ctx
=setup_command_handler();
729 command_context_t
*cfg_cmd_ctx
;
730 cfg_cmd_ctx
= copy_command_context(cmd_ctx
);
731 cfg_cmd_ctx
->mode
= COMMAND_CONFIG
;
732 command_set_output_handler(cfg_cmd_ctx
, configuration_output_handler
, NULL
);
734 if (parse_cmdline_args(cfg_cmd_ctx
, argc
, argv
) != ERROR_OK
)
739 if (parse_config_file(cfg_cmd_ctx
) != ERROR_OK
)
742 command_done(cfg_cmd_ctx
);
744 if (command_run_line(cmd_ctx
, "init")!=ERROR_OK
)
748 command_run_line(cmd_ctx
, "reset");
753 /* handle network connections */
754 server_loop(cmd_ctx
);
756 /* shut server down */
759 unregister_all_commands(cmd_ctx
);
761 /* free commandline interface */
762 command_done(cmd_ctx
);
769 * Local Variables: **
771 * c-basic-offset: 4 **
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)