David Kuehling <dvdkhlng@gmx.de> - added jim-eventloop.c
authoroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Thu, 7 Aug 2008 16:37:20 +0000 (16:37 +0000)
committeroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Thu, 7 Aug 2008 16:37:20 +0000 (16:37 +0000)
git-svn-id: svn://svn.berlios.de/openocd/trunk@898 b42882b7-edfa-0310-969c-e2dbd0fdcd60

12 files changed:
src/helper/Makefile.am
src/helper/command.c
src/helper/command.h
src/helper/jim-eventloop.c [new file with mode: 0644]
src/helper/jim-eventloop.h [new file with mode: 0644]
src/helper/jim.h
src/helper/log.c
src/server/server.c
src/target/Makefile.am
src/target/interface/dummy.cfg [new file with mode: 0644]
src/target/interface/olimex-arm-usb-ocd.cfg [new file with mode: 0644]
src/target/target/aduc702x.cfg [new file with mode: 0644]

index 64d051d268a978976eb010173301bf49a9495a7b..2165fad95c8be87d443ccaf893e8cf251c63cbce 100644 (file)
@@ -10,7 +10,7 @@ CONFIGFILES = options.c jim.c
 endif
 
 libhelper_a_SOURCES = binarybuffer.c $(CONFIGFILES) configuration.c log.c command.c time_support.c \
-       replacements.c fileio.c startup_tcl.c
+       replacements.c fileio.c jim-eventloop.c startup_tcl.c
 
 noinst_HEADERS = binarybuffer.h configuration.h types.h log.h command.h \
        time_support.h replacements.h fileio.h jim.h
index 119862284d3fa0d3ffbddc06bd30fab7c36d06bf..811328dc95d42cdd331ce26f90264a1ec9cbcefd 100644 (file)
@@ -34,6 +34,7 @@
 
 #include "log.h"
 #include "time_support.h"
+#include "jim-eventloop.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -654,6 +655,8 @@ command_context_t* command_init()
        
        add_default_dirs();
 
+       Jim_EventLoopOnLoad(interp);
+
        if (Jim_Eval(interp, startup_tcl)==JIM_ERR)
        {
                LOG_ERROR("Failed to run startup.tcl (embedded into OpenOCD compile time)");
@@ -705,6 +708,18 @@ int handle_fast_command(struct command_context_s *cmd_ctx, char *cmd, char **arg
        return ERROR_OK;
 }
 
+void process_jim_events() 
+{
+       static int recursion = 0;
+
+       if (!recursion) 
+       {
+               recursion++;
+               Jim_ProcessEvents (interp, JIM_ALL_EVENTS|JIM_DONT_WAIT);
+               recursion--;
+       }
+}
+
 void register_jim(struct command_context_s *cmd_ctx, const char *name, int (*cmd)(Jim_Interp *interp, int argc, Jim_Obj *const *argv), const char *help)
 {
        Jim_CreateCommand(interp, name, cmd, NULL, NULL);
index 097a8d37e6ea1ac474b5a2ae7aec867294b99aa1..b410edb7d6af694c1f3385e25daea272d7eb291e 100644 (file)
@@ -79,6 +79,8 @@ extern int command_run_line(command_context_t *context, char *line);
 extern int command_run_linef(command_context_t *context, char *format, ...);
 extern void command_output_text(command_context_t *context, const char *data);
 
+extern void process_jim_events();
+
 #define                ERROR_COMMAND_CLOSE_CONNECTION          (-600)
 #define                ERROR_COMMAND_SYNTAX_ERROR                      (-601)
 #define                ERROR_COMMAND_NOTFOUND                          (-602)
diff --git a/src/helper/jim-eventloop.c b/src/helper/jim-eventloop.c
new file mode 100644 (file)
index 0000000..c3c49d4
--- /dev/null
@@ -0,0 +1,545 @@
+/* Jim - A small embeddable Tcl interpreter\r
+ *\r
+ * Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>\r
+ * Copyright 2005 Clemens Hintze <c.hintze@gmx.net>\r
+ * Copyright 2005 patthoyts - Pat Thoyts <patthoyts@users.sf.net> \r
+ * Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com\r
+ * Copyright 2008 Andrew Lunn <andrew@lunn.ch>\r
+ * Copyright 2008 Duane Ellis <openocd@duaneellis.com>\r
+ * Copyright 2008 Uwe Klein <uklein@klein-messgeraete.de>\r
+ * \r
+ * The FreeBSD license\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above\r
+ *    copyright notice, this list of conditions and the following\r
+ *    disclaimer in the documentation and/or other materials\r
+ *    provided with the distribution.\r
+ * \r
+ * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY\r
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\r
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\r
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
+ * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\r
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ * The views and conclusions contained in the software and documentation\r
+ * are those of the authors and should not be interpreted as representing\r
+ * official policies, either expressed or implied, of the Jim Tcl Project.\r
+ **/\r
+/* TODO:\r
+ *\r
+ *  - to really use flags in Jim_ProcessEvents()\r
+ *  - more complete [after] command with [after info] and other subcommands.\r
+ *  - Win32 port\r
+ */\r
+\r
+#define JIM_EXTENSION\r
+#define __JIM_EVENTLOOP_CORE__\r
+#ifdef __ECOS\r
+#include <pkgconf/jimtcl.h>\r
+#endif\r
+#ifdef __ECOS\r
+#include <cyg/jimtcl/jim.h>\r
+#include <cyg/jimtcl/jim-eventloop.h>\r
+#else\r
+#include "jim.h"\r
+#include "jim-eventloop.h"\r
+#endif\r
+\r
+/* POSIX includes */\r
+#include <sys/time.h>\r
+#include <sys/types.h>\r
+#include <unistd.h>\r
+#include <sys/select.h>\r
+#include <errno.h>\r
+       extern int errno;\r
+/* --- */\r
+\r
+/* File event structure */\r
+typedef struct Jim_FileEvent {\r
+    void *handle;\r
+    int mask; /* one of JIM_EVENT_(READABLE|WRITABLE|EXCEPTION) */\r
+    Jim_FileProc *fileProc;\r
+    Jim_EventFinalizerProc *finalizerProc;\r
+    void *clientData;\r
+    struct Jim_FileEvent *next;\r
+} Jim_FileEvent;\r
+\r
+/* Time event structure */\r
+typedef struct Jim_TimeEvent {\r
+    jim_wide id; /* time event identifier. */\r
+    int mode;  /* restart, repetitive .. UK */\r
+    long initialms; /* initial relativ timer value UK */\r
+    long when_sec; /* seconds */\r
+    long when_ms; /* milliseconds */\r
+    Jim_TimeProc *timeProc;\r
+    Jim_EventFinalizerProc *finalizerProc;\r
+    void *clientData;\r
+    struct Jim_TimeEvent *next;\r
+} Jim_TimeEvent;\r
+\r
+/* Per-interp stucture containing the state of the event loop */\r
+typedef struct Jim_EventLoop {\r
+    jim_wide timeEventNextId;\r
+    Jim_FileEvent *fileEventHead;\r
+    Jim_TimeEvent *timeEventHead;\r
+} Jim_EventLoop;\r
+\r
+void Jim_CreateFileHandler(Jim_Interp *interp, void *handle, int mask,\r
+        Jim_FileProc *proc, void *clientData,\r
+        Jim_EventFinalizerProc *finalizerProc)\r
+{\r
+    Jim_FileEvent *fe;\r
+    Jim_EventLoop *eventLoop = Jim_GetAssocData(interp, "eventloop");\r
+\r
+       // fprintf(stderr,"rein\n");\r
+    fe = Jim_Alloc(sizeof(*fe));\r
+    fe->handle = handle;\r
+    fe->mask = mask;\r
+    fe->fileProc = proc;\r
+    fe->finalizerProc = finalizerProc;\r
+    fe->clientData = clientData;\r
+    fe->next = eventLoop->fileEventHead;\r
+    eventLoop->fileEventHead = fe;\r
+       // fprintf(stderr,"raus\n");\r
+}\r
+\r
+void Jim_DeleteFileHandler(Jim_Interp *interp, void *handle)\r
+{\r
+    Jim_FileEvent *fe, *prev = NULL;\r
+    Jim_EventLoop *eventLoop = Jim_GetAssocData(interp, "eventloop");\r
+\r
+    fe = eventLoop->fileEventHead;\r
+    while(fe) {\r
+        if (fe->handle == handle) {\r
+            if (prev == NULL)\r
+                eventLoop->fileEventHead = fe->next;\r
+            else\r
+                prev->next = fe->next;\r
+            if (fe->finalizerProc)\r
+                fe->finalizerProc(interp, fe->clientData);\r
+            Jim_Free(fe);\r
+            return;\r
+        }\r
+        prev = fe;\r
+        fe = fe->next;\r
+    }\r
+}\r
+\r
+// The same for signals.\r
+void Jim_CreateSignalHandler(Jim_Interp *interp, int signum, \r
+        Jim_FileProc *proc, void *clientData,\r
+        Jim_EventFinalizerProc *finalizerProc)\r
+{\r
+}\r
+void Jim_DeleteSignalHandler(Jim_Interp *interp, int signum) \r
+{\r
+}\r
+\r
+/* That's another part of this extension that needs to be ported\r
+ * to WIN32. */\r
+static void JimGetTime(long *seconds, long *milliseconds)\r
+{\r
+    struct timeval tv;\r
+\r
+    gettimeofday(&tv, NULL);\r
+    *seconds = tv.tv_sec;\r
+    *milliseconds = tv.tv_usec/1000;\r
+}\r
+\r
+jim_wide Jim_CreateTimeHandler(Jim_Interp *interp, jim_wide milliseconds,\r
+        Jim_TimeProc *proc, void *clientData,\r
+        Jim_EventFinalizerProc *finalizerProc)\r
+{\r
+    Jim_EventLoop *eventLoop = Jim_GetAssocData(interp, "eventloop");\r
+    jim_wide id = eventLoop->timeEventNextId++;\r
+    Jim_TimeEvent *te;\r
+    long cur_sec, cur_ms;\r
+\r
+    JimGetTime(&cur_sec, &cur_ms);\r
+\r
+    te = Jim_Alloc(sizeof(*te));\r
+    te->id = id;\r
+    te->mode = 0;\r
+    te->initialms = milliseconds;\r
+    te->when_sec = cur_sec + milliseconds/1000;\r
+    te->when_ms = cur_ms + milliseconds%1000;\r
+    if (te->when_ms >= 1000) {\r
+        te->when_sec ++;\r
+        te->when_ms -= 1000;\r
+    }\r
+    te->timeProc = proc;\r
+    te->finalizerProc = finalizerProc;\r
+    te->clientData = clientData;\r
+    te->next = eventLoop->timeEventHead;\r
+    eventLoop->timeEventHead = te;\r
+    return id;\r
+}\r
+\r
+jim_wide Jim_DeleteTimeHandler(Jim_Interp *interp, jim_wide id)\r
+{\r
+    Jim_TimeEvent *te, *prev = NULL;\r
+    Jim_EventLoop *eventLoop = Jim_GetAssocData(interp, "eventloop");\r
+    long cur_sec, cur_ms;\r
+    jim_wide remain ;\r
+\r
+    JimGetTime(&cur_sec, &cur_ms);\r
+\r
+    te = eventLoop->timeEventHead;\r
+    if (id >= eventLoop->timeEventNextId) \r
+       return -2; /* wrong event ID */\r
+    while(te) {\r
+        if (te->id == id) {\r
+            remain  = (te->when_sec - cur_sec) * 1000;\r
+            remain += (te->when_ms  - cur_ms) ;\r
+           remain = (remain < 0) ? 0 : remain ;\r
+\r
+            if (prev == NULL)\r
+                eventLoop->timeEventHead = te->next;\r
+            else\r
+                prev->next = te->next;\r
+            if (te->finalizerProc)\r
+                te->finalizerProc(interp, te->clientData);\r
+            Jim_Free(te);\r
+            return remain;\r
+        }\r
+        prev = te;\r
+        te = te->next;\r
+    }\r
+    return -1; /* NO event with the specified ID found */\r
+}\r
+\r
+/* Search the first timer to fire.\r
+ * This operation is useful to know how many time the select can be\r
+ * put in sleep without to delay any event.\r
+ * If there are no timers NULL is returned. */\r
+static Jim_TimeEvent *JimSearchNearestTimer(Jim_EventLoop *eventLoop)\r
+{\r
+    Jim_TimeEvent *te = eventLoop->timeEventHead;\r
+    Jim_TimeEvent *nearest = NULL;\r
+\r
+    while(te) {\r
+        if (!nearest || te->when_sec < nearest->when_sec ||\r
+                (te->when_sec == nearest->when_sec &&\r
+                 te->when_ms < nearest->when_ms))\r
+            nearest = te;\r
+        te = te->next;\r
+    }\r
+    return nearest;\r
+}\r
+\r
+/* Process every pending time event, then every pending file event\r
+ * (that may be registered by time event callbacks just processed).\r
+ * Without special flags the function sleeps until some file event\r
+ * fires, or when the next time event occurrs (if any).\r
+ *\r
+ * If flags is 0, the function does nothing and returns.\r
+ * if flags has JIM_ALL_EVENTS set, all the kind of events are processed.\r
+ * if flags has JIM_FILE_EVENTS set, file events are processed.\r
+ * if flags has JIM_TIME_EVENTS set, time events are processed.\r
+ * if flags has JIM_DONT_WAIT set the function returns ASAP until all\r
+ * the events that's possible to process without to wait are processed.\r
+ *\r
+ * The function returns the number of events processed. */\r
+int Jim_ProcessEvents(Jim_Interp *interp, int flags)\r
+{\r
+    int maxfd = 0, numfd = 0, processed = 0;\r
+    fd_set rfds, wfds, efds;\r
+    Jim_EventLoop *eventLoop = Jim_GetAssocData(interp, "eventloop");\r
+    Jim_FileEvent *fe = eventLoop->fileEventHead;\r
+    Jim_TimeEvent *te;\r
+    jim_wide maxId;\r
+    JIM_NOTUSED(flags);\r
+\r
+    FD_ZERO(&rfds);\r
+    FD_ZERO(&wfds);\r
+    FD_ZERO(&efds);\r
+\r
+    /* Check file events */\r
+    while (fe != NULL) {\r
+        int fd = fileno(fe->handle);\r
+\r
+        if (fe->mask & JIM_EVENT_READABLE) \r
+               FD_SET(fd, &rfds);\r
+        if (fe->mask & JIM_EVENT_WRITABLE) FD_SET(fd, &wfds);\r
+        if (fe->mask & JIM_EVENT_EXCEPTION) FD_SET(fd, &efds);\r
+        if (maxfd < fd) maxfd = fd;\r
+        numfd++;\r
+        fe = fe->next;\r
+    }\r
+    /* Note that we want call select() even if there are no\r
+     * file events to process as long as we want to process time\r
+     * events, in order to sleep until the next time event is ready\r
+     * to fire. */\r
+    if (numfd || ((flags & JIM_TIME_EVENTS) && !(flags & JIM_DONT_WAIT))) {\r
+        int retval;\r
+        Jim_TimeEvent *shortest;\r
+        struct timeval tv, *tvp;\r
+       jim_wide dt;\r
+\r
+        shortest = JimSearchNearestTimer(eventLoop);\r
+        if (shortest) {\r
+            long now_sec, now_ms;\r
+\r
+            /* Calculate the time missing for the nearest\r
+             * timer to fire. */\r
+            JimGetTime(&now_sec, &now_ms);\r
+            tvp = &tv;\r
+           dt   = 1000 * (shortest->when_sec - now_sec);\r
+           dt  += ( shortest->when_ms  - now_ms);\r
+            if (dt < 0) {\r
+               dt = 1;\r
+           }\r
+           tvp->tv_sec  = dt / 1000;\r
+           tvp->tv_usec = dt % 1000;\r
+           // fprintf(stderr,"Next %d.% 8d\n",(int)tvp->tv_sec,(int)tvp->tv_usec);\r
+        } else {\r
+            tvp = NULL; /* wait forever */\r
+               // fprintf(stderr,"No Event\n");\r
+        }\r
+\r
+        retval = select(maxfd+1, &rfds, &wfds, &efds, tvp);\r
+        if (retval < 0) {\r
+          switch (errno) {\r
+              case EINTR:   fprintf(stderr,"select EINTR\n"); break;\r
+              case EINVAL:  fprintf(stderr,"select EINVAL\n"); break;\r
+              case ENOMEM:  fprintf(stderr,"select ENOMEM\n"); break;\r
+          }\r
+       } else if (retval > 0) {\r
+            fe = eventLoop->fileEventHead;\r
+            while(fe != NULL) {\r
+                int fd = fileno(fe->handle);\r
+\r
+               // fprintf(stderr,"fd: %d mask: %02x \n",fd,fe->mask);\r
+\r
+                if ((fe->mask & JIM_EVENT_READABLE && FD_ISSET(fd, &rfds)) ||\r
+                    (fe->mask & JIM_EVENT_WRITABLE && FD_ISSET(fd, &wfds)) ||\r
+                    (fe->mask & JIM_EVENT_EXCEPTION && FD_ISSET(fd, &efds)))\r
+                {\r
+                    int mask = 0;\r
+\r
+                    if (fe->mask & JIM_EVENT_READABLE && FD_ISSET(fd, &rfds)) {\r
+                        mask |= JIM_EVENT_READABLE;\r
+                       if ((fe->mask & JIM_EVENT_FEOF) && feof((FILE *)fe->handle))\r
+                               mask |= JIM_EVENT_FEOF;\r
+                   }\r
+                    if (fe->mask & JIM_EVENT_WRITABLE && FD_ISSET(fd, &wfds))\r
+                        mask |= JIM_EVENT_WRITABLE;\r
+                    if (fe->mask & JIM_EVENT_EXCEPTION && FD_ISSET(fd, &efds))\r
+                        mask |= JIM_EVENT_EXCEPTION;\r
+                    if (fe->fileProc(interp, fe->clientData, mask) == JIM_ERR) {\r
+                        /* Remove the element on handler error */\r
+                        Jim_DeleteFileHandler(interp, fe->handle);\r
+                    }\r
+                    processed++;\r
+                    /* After an event is processed our file event list\r
+                     * may no longer be the same, so what we do\r
+                     * is to clear the bit for this file descriptor and\r
+                     * restart again from the head. */\r
+                    fe = eventLoop->fileEventHead;\r
+                    FD_CLR(fd, &rfds);\r
+                    FD_CLR(fd, &wfds);\r
+                    FD_CLR(fd, &efds);\r
+                } else {\r
+                    fe = fe->next;\r
+                }\r
+            }\r
+        }\r
+    }\r
+    /* Check time events */\r
+    te = eventLoop->timeEventHead;\r
+    maxId = eventLoop->timeEventNextId-1;\r
+    while(te) {\r
+        long now_sec, now_ms;\r
+        jim_wide id;\r
+\r
+        if (te->id > maxId) {\r
+            te = te->next;\r
+            continue;\r
+        }\r
+        JimGetTime(&now_sec, &now_ms);\r
+        if (now_sec > te->when_sec ||\r
+            (now_sec == te->when_sec && now_ms >= te->when_ms))\r
+        {\r
+            id = te->id;\r
+            te->timeProc(interp, te->clientData);\r
+            /* After an event is processed our time event list may\r
+             * no longer be the same, so we restart from head.\r
+             * Still we make sure to don't process events registered\r
+             * by event handlers itself in order to don't loop forever\r
+             * even in case an [after 0] that continuously register\r
+             * itself. To do so we saved the max ID we want to handle. */\r
+            Jim_DeleteTimeHandler(interp, id);\r
+            te = eventLoop->timeEventHead;\r
+        } else {\r
+            te = te->next;\r
+        }\r
+    }\r
+\r
+    return processed;\r
+}\r
+/* ---------------------------------------------------------------------- */\r
+\r
+void JimELAssocDataDeleProc(Jim_Interp *interp, void *data)\r
+{\r
+    void *next;\r
+    Jim_FileEvent *fe;\r
+    Jim_TimeEvent *te;\r
+    Jim_EventLoop *eventLoop = data;\r
+\r
+    fe = eventLoop->fileEventHead;\r
+    while(fe) {\r
+        next = fe->next;\r
+        if (fe->finalizerProc)\r
+            fe->finalizerProc(interp, fe->clientData);\r
+        Jim_Free(fe);\r
+        fe = next;\r
+    }\r
+\r
+    te = eventLoop->timeEventHead;\r
+    while(te) {\r
+        next = te->next;\r
+        if (te->finalizerProc)\r
+            te->finalizerProc(interp, te->clientData);\r
+        Jim_Free(te);\r
+        te = next;\r
+    }\r
+    Jim_Free(data);\r
+}\r
+\r
+static int JimELVwaitCommand(Jim_Interp *interp, int argc, \r
+        Jim_Obj *const *argv)\r
+{\r
+    Jim_Obj *oldValue;\r
+\r
+    if (argc != 2) {\r
+        Jim_WrongNumArgs(interp, 1, argv, "name");\r
+        return JIM_ERR;\r
+    }\r
+    oldValue = Jim_GetGlobalVariable(interp, argv[1], JIM_NONE);\r
+    if (oldValue) Jim_IncrRefCount(oldValue);\r
+    while (1) {\r
+        Jim_Obj *currValue;\r
+\r
+        Jim_ProcessEvents(interp, JIM_ALL_EVENTS);\r
+        currValue = Jim_GetGlobalVariable(interp, argv[1], JIM_NONE);\r
+        /* Stop the loop if the vwait-ed variable changed value,\r
+         * or if was unset and now is set (or the contrary). */\r
+        if ((oldValue && !currValue) ||\r
+            (!oldValue && currValue) ||\r
+            (oldValue && currValue &&\r
+             !Jim_StringEqObj(oldValue, currValue, JIM_CASESENS)))\r
+            break;\r
+    }\r
+    if (oldValue) Jim_DecrRefCount(interp, oldValue);\r
+    return JIM_OK;\r
+}\r
+\r
+void JimAfterTimeHandler(Jim_Interp *interp, void *clientData)\r
+{\r
+    Jim_Obj *objPtr = clientData;\r
+\r
+    Jim_EvalObjBackground(interp, objPtr);\r
+}\r
+\r
+void JimAfterTimeEventFinalizer(Jim_Interp *interp, void *clientData)\r
+{\r
+    Jim_Obj *objPtr = clientData;\r
+\r
+    Jim_DecrRefCount(interp, objPtr);\r
+}\r
+\r
+static int JimELAfterCommand(Jim_Interp *interp, int argc, \r
+        Jim_Obj *const *argv)\r
+{\r
+    jim_wide ms, id;\r
+    Jim_Obj *objPtr, *idObjPtr;\r
+    const char *options[] = {\r
+       "info", "cancel", "restart", "expire", NULL\r
+    };\r
+    enum {INFO, CANCEL, RESTART, EXPIRE, CREATE };\r
+    int option = CREATE ;\r
+\r
+    if (argc < 3) {\r
+        Jim_WrongNumArgs(interp, 1, argv, "<after milliseconds> script");\r
+        return JIM_ERR;\r
+    }\r
+    if (Jim_GetWide(interp, argv[1], &ms) != JIM_OK)\r
+        if (Jim_GetEnum(interp, argv[1], options, &option, "after options",\r
+                    JIM_ERRMSG) != JIM_OK)\r
+            return JIM_ERR;\r
+    switch (option) {\r
+    case CREATE:\r
+        Jim_IncrRefCount(argv[2]);\r
+        id = Jim_CreateTimeHandler(interp, ms, JimAfterTimeHandler, argv[2],\r
+                JimAfterTimeEventFinalizer);\r
+        objPtr = Jim_NewStringObj(interp, NULL, 0);\r
+        Jim_AppendString(interp, objPtr, "after#", -1);\r
+        idObjPtr = Jim_NewIntObj(interp, id);\r
+        Jim_IncrRefCount(idObjPtr);\r
+        Jim_AppendObj(interp, objPtr, idObjPtr);\r
+        Jim_DecrRefCount(interp, idObjPtr);\r
+        Jim_SetResult(interp, objPtr);\r
+        return JIM_OK;\r
+    case CANCEL:\r
+       {\r
+       int tlen ;\r
+       jim_wide remain = 0;\r
+       const char *tok = Jim_GetString(argv[2], &tlen);\r
+       if ( sscanf(tok,"after#%lld",&id) == 1) {\r
+               remain =  Jim_DeleteTimeHandler(interp, id);\r
+               if (remain > -2)  {\r
+                       Jim_SetResult(interp, Jim_NewIntObj(interp, remain));\r
+                       return JIM_OK;\r
+               }\r
+       }\r
+        Jim_SetResultString(interp, "invalid event" , -1);\r
+        return JIM_ERR;\r
+       }\r
+    default:\r
+       fprintf(stderr,"unserviced option to after %d\n",option);\r
+    } \r
+    return JIM_OK;\r
+}\r
+\r
+/* This extension is not dynamically loaded, instead it's linked statically,\r
+   which is why we shouldn't use the unspecific 'Jim_OnLoad' name */\r
+#define Jim_OnLoad Jim_EventLoopOnLoad\r
+\r
+int Jim_OnLoad(Jim_Interp *interp)\r
+{\r
+    Jim_EventLoop *eventLoop;\r
+\r
+    Jim_InitExtension(interp);\r
+    if (Jim_PackageProvide(interp, "eventloop", "1.0", JIM_ERRMSG) != JIM_OK)\r
+        return JIM_ERR;\r
+\r
+    eventLoop = Jim_Alloc(sizeof(*eventLoop));\r
+    eventLoop->fileEventHead = NULL;\r
+    eventLoop->timeEventHead = NULL;\r
+    eventLoop->timeEventNextId = 1;\r
+    Jim_SetAssocData(interp, "eventloop", JimELAssocDataDeleProc, eventLoop);\r
+\r
+    Jim_CreateCommand(interp, "vwait", JimELVwaitCommand, NULL, NULL);\r
+    Jim_CreateCommand(interp, "after", JimELAfterCommand, NULL, NULL);\r
+\r
+    /* Export events API */\r
+    Jim_RegisterApi(interp, "Jim_CreateFileHandler", Jim_CreateFileHandler);\r
+    Jim_RegisterApi(interp, "Jim_DeleteFileHandler", Jim_DeleteFileHandler);\r
+    Jim_RegisterApi(interp, "Jim_CreateTimeHandler", Jim_CreateTimeHandler);\r
+    Jim_RegisterApi(interp, "Jim_DeleteTimeHandler", Jim_DeleteTimeHandler);\r
+    Jim_RegisterApi(interp, "Jim_ProcessEvents", Jim_ProcessEvents);\r
+    return JIM_OK;\r
+}\r
diff --git a/src/helper/jim-eventloop.h b/src/helper/jim-eventloop.h
new file mode 100644 (file)
index 0000000..3923463
--- /dev/null
@@ -0,0 +1,110 @@
+/* Jim - A small embeddable Tcl interpreter\r
+ *\r
+ * Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>\r
+ * Copyright 2005 Clemens Hintze <c.hintze@gmx.net>\r
+ * Copyright 2005 patthoyts - Pat Thoyts <patthoyts@users.sf.net> \r
+ * Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com\r
+ * Copyright 2008 Andrew Lunn <andrew@lunn.ch>\r
+ * Copyright 2008 Duane Ellis <openocd@duaneellis.com>\r
+ * Copyright 2008 Uwe Klein <uklein@klein-messgeraete.de>\r
+ * \r
+ * The FreeBSD license\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above\r
+ *    copyright notice, this list of conditions and the following\r
+ *    disclaimer in the documentation and/or other materials\r
+ *    provided with the distribution.\r
+ * \r
+ * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY\r
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\r
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\r
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
+ * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\r
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ * The views and conclusions contained in the software and documentation\r
+ * are those of the authors and should not be interpreted as representing\r
+ * official policies, either expressed or implied, of the Jim Tcl Project.\r
+ **/\r
+/* ------ USAGE -------\r
+ *\r
+ * In order to use this file from other extensions include it in every\r
+ * file where you need to call the eventloop API, also in the init\r
+ * function of your extension call Jim_ImportEventloopAPI(interp)\r
+ * after the Jim_InitExtension() call.\r
+ *\r
+ * See the UDP extension as example.\r
+ */\r
+\r
+\r
+#ifndef __JIM_EVENTLOOP_H__\r
+#define __JIM_EVENTLOOP_H__\r
+\r
+typedef int Jim_FileProc(Jim_Interp *interp, void *clientData, int mask);\r
+typedef int Jim_SignalProc(Jim_Interp *interp, void *clientData, void *msg);\r
+typedef void Jim_TimeProc(Jim_Interp *interp, void *clientData);\r
+typedef void Jim_EventFinalizerProc(Jim_Interp *interp, void *clientData);\r
+\r
+/* File event structure */\r
+#define JIM_EVENT_READABLE 1\r
+#define JIM_EVENT_WRITABLE 2\r
+#define JIM_EVENT_EXCEPTION 4\r
+#define JIM_EVENT_FEOF 8\r
+\r
+#define JIM_API(x) x\r
+#define JIM_STATIC \r
+\r
+/* --- POSIX version of Jim_ProcessEvents, for now the only available --- */\r
+#define JIM_FILE_EVENTS 1\r
+#define JIM_TIME_EVENTS 2\r
+#define JIM_ALL_EVENTS (JIM_FILE_EVENTS|JIM_TIME_EVENTS)\r
+#define JIM_DONT_WAIT 4\r
+\r
+JIM_STATIC void JIM_API(Jim_CreateFileHandler) (Jim_Interp *interp,\r
+        void *handle, int mask,\r
+        Jim_FileProc *proc, void *clientData,\r
+        Jim_EventFinalizerProc *finalizerProc);\r
+JIM_STATIC void JIM_API(Jim_DeleteFileHandler) (Jim_Interp *interp,\r
+        void *handle);\r
+JIM_STATIC jim_wide JIM_API(Jim_CreateTimeHandler) (Jim_Interp *interp,\r
+        jim_wide milliseconds,\r
+        Jim_TimeProc *proc, void *clientData,\r
+        Jim_EventFinalizerProc *finalizerProc);\r
+JIM_STATIC jim_wide JIM_API(Jim_DeleteTimeHandler) (Jim_Interp *interp, jim_wide id);\r
+JIM_STATIC int JIM_API(Jim_ProcessEvents) (Jim_Interp *interp, int flags);\r
+\r
+#undef JIM_STATIC\r
+#undef JIM_API\r
+\r
+#ifndef __JIM_EVENTLOOP_CORE__\r
+\r
+#define JIM_GET_API(name) \\r
+    Jim_GetApi(interp, "Jim_" #name, ((void *)&Jim_ ## name))\r
+\r
+#if defined(JIM_EXTENSION) || defined(JIM_EMBEDDED)\r
+/* This must be included "inline" inside the extension */\r
+static void Jim_ImportEventloopAPI(Jim_Interp *interp)\r
+{\r
+  JIM_GET_API(CreateFileHandler);\r
+  JIM_GET_API(DeleteFileHandler);\r
+  JIM_GET_API(CreateTimeHandler);\r
+  JIM_GET_API(DeleteTimeHandler);\r
+  JIM_GET_API(ProcessEvents);\r
+}\r
+#endif /* defined JIM_EXTENSION || defined JIM_EMBEDDED */\r
+#undef JIM_GET_API\r
+#endif /* __JIM_EVENTLOOP_CORE__ */\r
+\r
+#endif /* __JIM_EVENTLOOP_H__ */\r
index a9af02512606b78246cfbfc095266ad4a0458ee8..32020cccc524da2375eb7d5d5b6a902384dd642e 100644 (file)
@@ -50,6 +50,7 @@ extern "C" {
 #include <limits.h>
 #include <stdio.h>  /* for the FILE typedef definition */
 #include <stdlib.h> /* In order to export the Jim_Free() macro */
+#include <stdarg.h> /* In order to get type va_list */
 
 /* -----------------------------------------------------------------------------
 * Some /very/ old compiler maybe do not know how to
index 567320cdf4b3de1c61cb34778f204f72abf446e1..f8dc1a3a199f95cca7f1a3bd0e3ff3c51da7431c 100644 (file)
@@ -27,6 +27,7 @@
 #include "log.h"
 #include "configuration.h"
 #include "time_support.h"
+#include "command.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -368,6 +369,11 @@ void keep_alive()
                LOG_USER_N("%s", "");
                last_time=current_time;
        }
+
+       /* also process TCL events (we have to do this from 'log.c' since its
+        * keep_alive() is the only routine guaranteed to be called at least
+        * once per second :( */
+       process_jim_events ();
 }
 
 /* reset keep alive timer without sending message */
index 062d74e6d851b16550e326481ed3ff8e8db09145..26610cfd90265c895f58dff50aca7cf97f98588d 100644 (file)
@@ -346,6 +346,7 @@ int server_loop(command_context_t *command_context)
                }
                
                target_call_timer_callbacks();
+               process_jim_events ();
 
                if (retval == 0)
                {
@@ -455,6 +456,7 @@ int server_init(void)
        signal(SIGBREAK, sig_handler);
        signal(SIGABRT, sig_handler);
 #endif
+
        
        return ERROR_OK;
 }
@@ -486,3 +488,5 @@ int handle_shutdown_command(struct command_context_s *cmd_ctx, char *cmd, char *
 
        return ERROR_COMMAND_CLOSE_CONNECTION;
 }
+
+
index be3e31462892049ca7aa3fe49603514a509a589c..a8e435b3512bd8405cba3eb976700faa7566a87f 100644 (file)
@@ -37,5 +37,5 @@ nobase_dist_pkglib_DATA = xscale/debug_handler.bin event/at91eb40a_reset.script
        interface/signalyzer.cfg event/eir-sam7se512_reset.script target/eir-sam7se512.cfg \
        event/hammer_reset.script interface/flyswatter.cfg target/hammer.cfg target/mx31.cfg  \
        event/str730_program.script event/str750_program.script interface/olimex-jtag-tiny-a.cfg \
-       target/pic32mx.cfg
+       target/pic32mx.cfg target/aduc702x.cfg interface/dummy.cfg interface/olimex-arm-usb-ocd.cfg
 
diff --git a/src/target/interface/dummy.cfg b/src/target/interface/dummy.cfg
new file mode 100644 (file)
index 0000000..939803d
--- /dev/null
@@ -0,0 +1 @@
+interface dummy\r
diff --git a/src/target/interface/olimex-arm-usb-ocd.cfg b/src/target/interface/olimex-arm-usb-ocd.cfg
new file mode 100644 (file)
index 0000000..6e47f37
--- /dev/null
@@ -0,0 +1,4 @@
+interface ft2232\r
+ft2232_device_desc "Olimex OpenOCD JTAG"\r
+ft2232_layout olimex-jtag\r
+ft2232_vid_pid 0x15ba 0x0003\r
diff --git a/src/target/target/aduc702x.cfg b/src/target/target/aduc702x.cfg
new file mode 100644 (file)
index 0000000..4269f38
--- /dev/null
@@ -0,0 +1,38 @@
+## -*- tcl -*-\r
+##\r
+\r
+# This is for the case that TRST/SRST is not wired on your JTAG adaptor.\r
+# Don't really need them anyways.  \r
+reset_config none\r
+\r
+## JTAG scan chain\r
+#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)\r
+jtag_device 4 0x1 0xf 0xe\r
+\r
+##\r
+## Target configuration\r
+##\r
+target arm7tdmi little 0\r
+\r
+## software initiated reset (if your SRST isn't wired)\r
+#proc target_0_reset {} { mwb 0x0ffff0230 04 }\r
+\r
+# use top 1k of SRAM for as temporary JTAG memory \r
+#working_area 0 0x11C00 0x400 backup\r
+\r
+## flash configuration\r
+## AdUC702x not yet spported  :(\r
+\r
+## If you use the watchdog, the following code makes sure that the board\r
+## doesn't reboot when halted via JTAG.  Yes, on the older generation\r
+## AdUC702x, timer3 continues running even when the CPU is halted.\r
+\r
+proc watchdog_service {} {\r
+    global watchdog_hdl\r
+    mww 0xffff036c 0\r
+#    puts "watchdog!!"\r
+    set watchdog_hdl [after 500 watchdog_service]\r
+}\r
+\r
+proc target_0_post_halt {} { watchdog_service }\r
+proc arget_0_pre_resume {} { global watchdog_hdl; after cancel $watchdog_hdl }\r

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)