Browse Source

Jim Tcl support added

git-svn-id: svn://svn.berlios.de/openocd/trunk@739 b42882b7-edfa-0310-969c-e2dbd0fdcd60
tags/v0.1.0
oharboe 15 years ago
parent
commit
a521e674cf
3 changed files with 182 additions and 5 deletions
  1. +5
    -1
      src/Makefile.am
  2. +173
    -4
      src/openocd.c
  3. +4
    -0
      src/tcl/commands.tcl

+ 5
- 1
src/Makefile.am View File

@@ -7,7 +7,7 @@ MAINFILE = openocd.c
endif


openocd_SOURCES = $(MAINFILE)
openocd_SOURCES = $(MAINFILE) jim.c

# set the include path found by configure
INCLUDES = -I$(top_srcdir)/src/helper \
@@ -78,3 +78,7 @@ openocd_LDADD = $(top_builddir)/src/xsvf/libxsvf.a \
$(top_builddir)/src/flash/libflash.a $(top_builddir)/src/target/libtarget.a \
$(top_builddir)/src/pld/libpld.a \
$(FTDI2232LIB) $(FTD2XXLIB) $(MINGWLDADD) $(LIBUSB)

nobase_dist_pkglib_DATA = tcl/commands.tcl

+ 173
- 4
src/openocd.c View File

@@ -49,6 +49,10 @@
#include <unistd.h>
#include <errno.h>

#define JIM_EMBEDDED
#include "jim.h"


/* Give TELNET a way to find out what version this is */
int handle_version_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
@@ -154,15 +158,175 @@ void unlockBigLock()
{
}

/* Hook to add scripting language */




Jim_Interp *interp;
command_context_t *active_cmd_ctx;

static void tcl_output(void *privData, const char *file, int line,
const char *function, const char *string)
{
Jim_Obj *tclOutput=(Jim_Obj *)privData;

Jim_AppendString(interp, tclOutput, string, strlen(string));
}

/* try to execute as Jim command, otherwise fall back to standard command.

Note that even if the Jim command caused an error, then we succeeded
to execute it, hence this fn pretty much always returns ERROR_OK.

*/
int jim_command(command_context_t *context, char *line)
{
LOG_ERROR("Syntax error");
return ERROR_COMMAND_SYNTAX_ERROR;
int retval=ERROR_OK;
active_cmd_ctx=context;
int retcode=Jim_Eval(interp, line);
active_cmd_ctx=NULL;
const char *result;
int reslen;
result = Jim_GetString(Jim_GetResult(interp), &reslen);
if (retcode == JIM_ERR) {
int len, i;
LOG_USER_N("Runtime error, file \"%s\", line %d:" JIM_NL,
interp->errorFileName, interp->errorLine);
LOG_USER_N(" %s" JIM_NL,
Jim_GetString(interp->result, NULL));
Jim_ListLength(interp, interp->stackTrace, &len);
for (i = 0; i < len; i+= 3) {
Jim_Obj *objPtr;
const char *proc, *file, *line;
Jim_ListIndex(interp, interp->stackTrace, i, &objPtr, JIM_NONE);
proc = Jim_GetString(objPtr, NULL);
Jim_ListIndex(interp, interp->stackTrace, i+1, &objPtr,
JIM_NONE);
file = Jim_GetString(objPtr, NULL);
Jim_ListIndex(interp, interp->stackTrace, i+2, &objPtr,
JIM_NONE);
line = Jim_GetString(objPtr, NULL);
LOG_USER_N("In procedure '%s' called at file \"%s\", line %s" JIM_NL,
proc, file, line);
}
} else if (retcode == JIM_EXIT) {
// ignore.
//exit(Jim_GetExitCode(interp));
} else {
if (reslen) {
int i;
char buff[256+1];
for (i=0; i<reslen; i+=256)
{
int chunk;
chunk=reslen-i;
if (chunk>256)
chunk=256;
strncpy(buff, result, chunk);
buff[chunk]=0;
LOG_USER_N("%s", buff);
}
LOG_USER_N("%s", "\n");
}
}
return retval;
}

static int startLoop=0;

static int
Jim_Command_openocd_ignore(Jim_Interp *interp,
int argc,
Jim_Obj *const *argv,
int ignore)
{
int retval;
char *cmd = (char*)Jim_GetString(argv[1], NULL);

lockBigLock();
Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
if (startLoop)
{
// We don't know whether or not the telnet/gdb server is running...
target_call_timer_callbacks_now();
}
log_add_callback(tcl_output, tclOutput);
retval=command_run_line_internal(active_cmd_ctx, cmd);
if (startLoop)
{
target_call_timer_callbacks_now();
}
log_remove_callback(tcl_output, tclOutput);
Jim_SetResult(interp, tclOutput);
unlockBigLock();
return (ignore||(retval==ERROR_OK))?JIM_OK:JIM_ERR;
}

static int
Jim_Command_openocd(Jim_Interp *interp,
int argc,
Jim_Obj *const *argv)
{
return Jim_Command_openocd_ignore(interp, argc, argv, 1);
}

static int
Jim_Command_openocd_throw(Jim_Interp *interp,
int argc,
Jim_Obj *const *argv)
{
return Jim_Command_openocd_ignore(interp, argc, argv, 0);
}



/* find full path to file */
static int
Jim_Command_find(Jim_Interp *interp,
int argc,
Jim_Obj *const *argv)
{
if (argc!=2)
return JIM_ERR;
char *file = (char*)Jim_GetString(argv[1], NULL);
char *full_path=find_file(file);
if (full_path==NULL)
return JIM_ERR;
Jim_Obj *result = Jim_NewStringObj(interp, full_path, strlen(full_path));
free(full_path);
Jim_SetResult(interp, result);
return JIM_OK;
}


void initJim(void)
{
Jim_InitEmbedded();
/* Create an interpreter */
interp = Jim_CreateInterp();
/* Add all the Jim core commands */
Jim_RegisterCoreCommands(interp);
Jim_CreateCommand(interp, "openocd", Jim_Command_openocd, NULL, NULL);
Jim_CreateCommand(interp, "openocd_throw", Jim_Command_openocd_throw, NULL, NULL);
Jim_CreateCommand(interp, "find", Jim_Command_find, NULL, NULL);
}

int main(int argc, char *argv[])
{
initJim();
/* initialize commandline interface */
command_context_t *cmd_ctx, *cfg_cmd_ctx;
cmd_ctx = command_init();
@@ -188,7 +352,7 @@ int main(int argc, char *argv[])
if (log_init(cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;
LOG_DEBUG("log init complete");
LOG_OUTPUT( OPENOCD_VERSION "\n" );
@@ -214,6 +378,8 @@ int main(int argc, char *argv[])
if (parse_cmdline_args(cfg_cmd_ctx, argc, argv) != ERROR_OK)
return EXIT_FAILURE;

Jim_Eval(interp, "source [find tcl/commands.tcl]");

if (parse_config_file(cfg_cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;
@@ -225,6 +391,9 @@ int main(int argc, char *argv[])
if (daemon_startup)
command_run_line(cmd_ctx, "reset");


startLoop=1;

/* handle network connections */
server_loop(cmd_ctx);



+ 4
- 0
src/tcl/commands.tcl View File

@@ -0,0 +1,4 @@
# implements Tcl procedures/functions
proc peek {address} {
return [openocd mdw $address]
}

Loading…
Cancel
Save