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"
44 #include <sys/types.h>
56 /* Give TELNET a way to find out what version this is */
57 int handle_version_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
59 command_print(cmd_ctx
, OPENOCD_VERSION
);
64 static int daemon_startup
= 0;
66 int handle_daemon_startup_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
71 return ERROR_COMMAND_SYNTAX_ERROR
;
73 daemon_startup
= strcmp("reset", args
[0])==0;
75 command_print(cmd_ctx
, OPENOCD_VERSION
);
81 void exit_handler(void)
83 /* close JTAG interface */
84 if (jtag
&& jtag
->quit
)
89 /* OpenOCD can't really handle failure of this command. Patches welcome! :-) */
90 int handle_init_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
93 static int initialized
=0;
99 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
101 atexit(exit_handler
);
104 if (target_init(cmd_ctx
) != ERROR_OK
)
106 LOG_DEBUG("target init complete");
108 if ((retval
=jtag_interface_init(cmd_ctx
)) != ERROR_OK
)
110 /* we must be able to set up the jtag interface */
113 LOG_DEBUG("jtag interface init complete");
115 /* Try to initialize & examine the JTAG chain at this point, but
116 * continue startup regardless
118 if (jtag_init(cmd_ctx
) == ERROR_OK
)
120 LOG_DEBUG("jtag init complete");
121 if (target_examine(cmd_ctx
) == ERROR_OK
)
123 LOG_DEBUG("jtag examine complete");
128 if (flash_init_drivers(cmd_ctx
) != ERROR_OK
)
130 LOG_DEBUG("flash init complete");
132 if (nand_init(cmd_ctx
) != ERROR_OK
)
134 LOG_DEBUG("NAND init complete");
136 if (pld_init(cmd_ctx
) != ERROR_OK
)
138 LOG_DEBUG("pld init complete");
140 /* initialize tcp server */
143 /* initialize telnet subsystem */
144 telnet_init("Open On-Chip Debugger");
151 /* implementations of OpenOCD that uses multithreading needs to lock OpenOCD while calling
152 * OpenOCD fn's. No-op in vanilla OpenOCD
166 command_context_t
*active_cmd_ctx
;
169 new_int_array_element( Jim_Interp
* interp
,
175 Jim_Obj
*nameObjPtr
, *valObjPtr
;
178 namebuf
= alloca( strlen(varname
) + 30 );
179 sprintf( namebuf
, "%s(%d)", varname
, idx
);
182 nameObjPtr
= Jim_NewStringObj(interp
, namebuf
, -1);
183 valObjPtr
= Jim_NewIntObj(interp
, val
);
184 Jim_IncrRefCount(nameObjPtr
);
185 Jim_IncrRefCount(valObjPtr
);
186 result
= Jim_SetVariable(interp
, nameObjPtr
, valObjPtr
);
187 Jim_DecrRefCount(interp
, nameObjPtr
);
188 Jim_DecrRefCount(interp
, valObjPtr
);
189 // printf( "%s = 0%08x\n", namebuf, val );
194 Jim_Command_mem2array( Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
209 /* argv[1] = name of array to receive the data
210 * argv[2] = desired width
211 * argv[3] = memory address
212 * argv[4] = length in bytes to read
215 Jim_WrongNumArgs( interp
, 1, argv
, "varname width addr nelems" );
218 varname
= Jim_GetString( argv
[1], &len
);
219 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
222 e
= Jim_GetLong( interp
, argv
[2], &l
);
228 e
= Jim_GetLong( interp
, argv
[3], &l
);
233 e
= Jim_GetLong( interp
, argv
[4], &l
);
249 Jim_SetResult(interp
,
250 Jim_NewEmptyStringObj(interp
));
251 Jim_AppendStrings( interp
, Jim_GetResult(interp
),
252 "Invalid width param, must be 8/16/32", NULL
);
256 Jim_SetResult(interp
,
257 Jim_NewEmptyStringObj(interp
));
258 Jim_AppendStrings( interp
, Jim_GetResult(interp
),
259 "mem2array: zero width read?", NULL
);
262 if( (addr
+ (len
* width
)) < addr
){
263 Jim_SetResult(interp
,
264 Jim_NewEmptyStringObj(interp
));
265 Jim_AppendStrings( interp
, Jim_GetResult(interp
),
266 "mem2array: addr + len - wraps to zero?", NULL
);
269 /* absurd transfer size? */
271 Jim_SetResult(interp
,
272 Jim_NewEmptyStringObj(interp
));
273 Jim_AppendStrings( interp
, Jim_GetResult(interp
),
274 "mem2array: absurd > 64K item request", NULL
);
279 ((width
== 2) && ((addr
& 1) == 0)) ||
280 ((width
== 4) && ((addr
& 3) == 0)) ){
284 Jim_SetResult(interp
,
285 Jim_NewEmptyStringObj(interp
));
287 "mem2array address: 0x%08x is not aligned for %d byte reads",
290 Jim_AppendStrings( interp
, Jim_GetResult(interp
),
295 target
= get_current_target( active_cmd_ctx
);
305 /* Slurp... in buffer size chunks */
307 count
= len
; /* in objects.. */
308 if( count
> (sizeof(buffer
)/width
)){
309 count
= (sizeof(buffer
)/width
);
312 retval
= target
->type
->read_memory( target
,
318 if( retval
!= ERROR_OK
){
320 LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed",
321 addr
, width
, count
);
322 Jim_SetResult(interp
,
323 Jim_NewEmptyStringObj(interp
));
324 Jim_AppendStrings( interp
, Jim_GetResult(interp
),
325 "mem2array: cannot read memory", NULL
);
329 v
= 0; /* shut up gcc */
330 for( i
= 0 ; i
< count
; i
++, n
++ ){
333 v
= target_buffer_get_u32( target
, &buffer
[i
*width
] );
336 v
= target_buffer_get_u16( target
, &buffer
[i
*width
] );
339 v
= buffer
[i
] & 0x0ff;
342 new_int_array_element( interp
, varname
, n
, v
);
347 Jim_SetResult(interp
,
348 Jim_NewEmptyStringObj(interp
));
353 static void tcl_output(void *privData
, const char *file
, int line
,
354 const char *function
, const char *string
)
356 Jim_Obj
*tclOutput
=(Jim_Obj
*)privData
;
358 Jim_AppendString(interp
, tclOutput
, string
, strlen(string
));
361 /* try to execute as Jim command, otherwise fall back to standard command.
363 Note that even if the Jim command caused an error, then we succeeded
364 to execute it, hence this fn pretty much always returns ERROR_OK.
367 int jim_command(command_context_t
*context
, char *line
)
370 /* FIX!!!! in reality there is only one cmd_ctx handler, but consider
371 what might happen here if there are multiple handlers w/reentrant callback
373 active_cmd_ctx
=context
;
374 int retcode
=Jim_Eval(interp
, line
);
378 result
= Jim_GetString(Jim_GetResult(interp
), &reslen
);
379 if (retcode
== JIM_ERR
) {
382 LOG_USER_N("Runtime error, file \"%s\", line %d:" JIM_NL
,
383 interp
->errorFileName
, interp
->errorLine
);
384 LOG_USER_N(" %s" JIM_NL
,
385 Jim_GetString(interp
->result
, NULL
));
386 Jim_ListLength(interp
, interp
->stackTrace
, &len
);
387 for (i
= 0; i
< len
; i
+= 3) {
389 const char *proc
, *file
, *line
;
391 Jim_ListIndex(interp
, interp
->stackTrace
, i
, &objPtr
, JIM_NONE
);
392 proc
= Jim_GetString(objPtr
, NULL
);
393 Jim_ListIndex(interp
, interp
->stackTrace
, i
+1, &objPtr
,
395 file
= Jim_GetString(objPtr
, NULL
);
396 Jim_ListIndex(interp
, interp
->stackTrace
, i
+2, &objPtr
,
398 line
= Jim_GetString(objPtr
, NULL
);
399 LOG_USER_N("In procedure '%s' called at file \"%s\", line %s" JIM_NL
,
402 } else if (retcode
== JIM_EXIT
) {
404 //exit(Jim_GetExitCode(interp));
409 for (i
=0; i
<reslen
; i
+=256)
415 strncpy(buff
, result
, chunk
);
417 LOG_USER_N("%s", buff
);
419 LOG_USER_N("%s", "\n");
425 static int startLoop
=0;
428 Jim_Command_openocd_ignore(Jim_Interp
*interp
,
430 Jim_Obj
*const *argv
,
434 char *cmd
= (char*)Jim_GetString(argv
[1], NULL
);
438 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
442 // We don't know whether or not the telnet/gdb server is running...
443 target_call_timer_callbacks_now();
446 log_add_callback(tcl_output
, tclOutput
);
447 retval
=command_run_line_internal(active_cmd_ctx
, cmd
);
451 target_call_timer_callbacks_now();
453 log_remove_callback(tcl_output
, tclOutput
);
455 Jim_SetResult(interp
, tclOutput
);
458 return (ignore
||(retval
==ERROR_OK
))?JIM_OK
:JIM_ERR
;
462 Jim_Command_openocd(Jim_Interp
*interp
,
464 Jim_Obj
*const *argv
)
466 return Jim_Command_openocd_ignore(interp
, argc
, argv
, 1);
470 Jim_Command_openocd_throw(Jim_Interp
*interp
,
472 Jim_Obj
*const *argv
)
474 return Jim_Command_openocd_ignore(interp
, argc
, argv
, 0);
480 /* find full path to file */
482 Jim_Command_find(Jim_Interp
*interp
,
484 Jim_Obj
*const *argv
)
488 char *file
= (char*)Jim_GetString(argv
[1], NULL
);
489 char *full_path
=find_file(file
);
492 Jim_Obj
*result
= Jim_NewStringObj(interp
, full_path
, strlen(full_path
));
495 Jim_SetResult(interp
, result
);
500 Jim_Command_echo(Jim_Interp
*interp
,
502 Jim_Obj
*const *argv
)
506 char *str
= (char*)Jim_GetString(argv
[1], NULL
);
512 openocd_jim_fwrite( const void *_ptr
, size_t size
, size_t n
, void *cookie
)
517 /* make it a char easier to read code */
525 if( !active_cmd_ctx
){
526 /* FIXME: Where should this go? */
531 /* do we have to chunk it? */
532 if( ptr
[ nbytes
] == 0 ){
533 /* no it is a C style string */
534 command_output_text( active_cmd_ctx
, ptr
);
537 /* GRR we must chunk - not null terminated */
547 memcpy( chunk
, ptr
, x
);
551 command_output_text( active_cmd_ctx
, chunk
);
560 openocd_jim_fread(void *ptr
, size_t size
, size_t n
, void *cookie
)
562 /* TCL wants to read... tell him no */
568 openocd_jim_vfprintf( void *cookie
, const char *fmt
, va_list ap
)
574 if( active_cmd_ctx
){
575 cp
= alloc_vprintf( fmt
, ap
);
577 command_output_text( active_cmd_ctx
, cp
);
586 openocd_jim_fflush( void *cookie
)
588 /* nothing to flush */
593 openocd_jim_fgets( char *s
, int size
, void *cookie
)
606 /* Create an interpreter */
607 interp
= Jim_CreateInterp();
608 /* Add all the Jim core commands */
609 Jim_RegisterCoreCommands(interp
);
610 Jim_CreateCommand(interp
, "openocd", Jim_Command_openocd
, NULL
, NULL
);
611 Jim_CreateCommand(interp
, "openocd_throw", Jim_Command_openocd_throw
, NULL
, NULL
);
612 Jim_CreateCommand(interp
, "find", Jim_Command_find
, NULL
, NULL
);
613 Jim_CreateCommand(interp
, "echo", Jim_Command_echo
, NULL
, NULL
);
614 Jim_CreateCommand(interp
, "mem2array", Jim_Command_mem2array
, NULL
, NULL
);
616 /* Set Jim's STDIO */
617 interp
->cookie_stdin
= NULL
;
618 interp
->cookie_stdout
= NULL
;
619 interp
->cookie_stderr
= NULL
;
620 interp
->cb_fwrite
= openocd_jim_fwrite
;
621 interp
->cb_fread
= openocd_jim_fread
;
622 interp
->cb_vfprintf
= openocd_jim_vfprintf
;
623 interp
->cb_fflush
= openocd_jim_fflush
;
624 interp
->cb_fgets
= openocd_jim_fgets
;
627 int main(int argc
, char *argv
[])
631 /* initialize commandline interface */
632 command_context_t
*cmd_ctx
, *cfg_cmd_ctx
;
633 cmd_ctx
= command_init();
635 register_command(cmd_ctx
, NULL
, "version", handle_version_command
,
636 COMMAND_EXEC
, "show OpenOCD version");
637 register_command(cmd_ctx
, NULL
, "daemon_startup", handle_daemon_startup_command
, COMMAND_CONFIG
,
638 "deprecated - use \"init\" and \"reset\" at end of startup script instead");
640 /* register subsystem commands */
641 server_register_commands(cmd_ctx
);
642 telnet_register_commands(cmd_ctx
);
643 gdb_register_commands(cmd_ctx
);
644 log_register_commands(cmd_ctx
);
645 jtag_register_commands(cmd_ctx
);
646 interpreter_register_commands(cmd_ctx
);
647 xsvf_register_commands(cmd_ctx
);
648 target_register_commands(cmd_ctx
);
649 flash_register_commands(cmd_ctx
);
650 nand_register_commands(cmd_ctx
);
651 pld_register_commands(cmd_ctx
);
653 if (log_init(cmd_ctx
) != ERROR_OK
)
655 LOG_DEBUG("log init complete");
657 LOG_OUTPUT( OPENOCD_VERSION
"\n" );
660 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
661 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
662 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
663 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
664 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
665 LOG_OUTPUT( "$URL$\n");
666 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
667 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
668 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
669 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
670 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
672 register_command(cmd_ctx
, NULL
, "init", handle_init_command
,
673 COMMAND_ANY
, "initializes target and servers - nop on subsequent invocations");
675 cfg_cmd_ctx
= copy_command_context(cmd_ctx
);
676 cfg_cmd_ctx
->mode
= COMMAND_CONFIG
;
677 command_set_output_handler(cfg_cmd_ctx
, configuration_output_handler
, NULL
);
679 if (parse_cmdline_args(cfg_cmd_ctx
, argc
, argv
) != ERROR_OK
)
682 Jim_Eval(interp
, "source [find tcl/commands.tcl]");
684 if (parse_config_file(cfg_cmd_ctx
) != ERROR_OK
)
687 command_done(cfg_cmd_ctx
);
689 if (command_run_line(cmd_ctx
, "init")!=ERROR_OK
)
693 command_run_line(cmd_ctx
, "reset");
698 /* handle network connections */
699 server_loop(cmd_ctx
);
701 /* shut server down */
704 unregister_all_commands(cmd_ctx
);
706 /* free commandline interface */
707 command_done(cmd_ctx
);
714 * Local Variables: **
716 * 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)