This is an automated email from Gerrit.

Kurt Godwin ([email protected]) just uploaded a new patch set to Gerrit, which 
you can find at http://openocd.zylin.com/4087

-- gerrit

commit e24bf3bc7377a4d8dfc5113cc8b67a22714ea324
Author: kurtgo <[email protected]>
Date:   Wed Mar 29 12:18:53 2017 -0700

    added ucos-ii support
    
    Added ucos 2 support to the rtos extentions.  This allows use of the thread 
command and other things.
    
    Change-Id: I9d0c8e89803d413286691039014df0fd4d25b565
    Signed-off-by: kurtgo <[email protected]>

diff --git a/src/rtos/Makefile.am b/src/rtos/Makefile.am
index c59ee3f..28f2857 100644
--- a/src/rtos/Makefile.am
+++ b/src/rtos/Makefile.am
@@ -22,7 +22,8 @@ noinst_LTLIBRARIES += %D%/librtos.la
        %D%/rtos_chibios_stackings.h \
        %D%/rtos_embkernel_stackings.h \
        %D%/rtos_mqx_stackings.h \
-       %D%/rtos_ucos_iii_stackings.h
+       %D%/rtos_ucos_iii_stackings.h \
+       %D%/ucos.c
 
 %C%_librtos_la_CFLAGS = $(AM_CFLAGS)
 
diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c
index 84ee498..4bd0990 100644
--- a/src/rtos/rtos.c
+++ b/src/rtos/rtos.c
@@ -35,6 +35,7 @@ extern struct rtos_type ChibiOS_rtos;
 extern struct rtos_type embKernel_rtos;
 extern struct rtos_type mqx_rtos;
 extern struct rtos_type uCOS_III_rtos;
+extern struct rtos_type ucos_rtos;
 
 static struct rtos_type *rtos_types[] = {
        &ThreadX_rtos,
@@ -45,6 +46,7 @@ static struct rtos_type *rtos_types[] = {
        &embKernel_rtos,
        &mqx_rtos,
        &uCOS_III_rtos,
+       &ucos_rtos,
        NULL
 };
 
diff --git a/src/rtos/ucos.c b/src/rtos/ucos.c
new file mode 100644
index 0000000..bf5f4fd
--- /dev/null
+++ b/src/rtos/ucos.c
@@ -0,0 +1,442 @@
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <helper/time_support.h>
+#include <jtag/jtag.h>
+#include "target/target.h"
+#include "target/target_type.h"
+#include "rtos.h"
+#include "helper/log.h"
+#include "helper/types.h"
+#include "target/armv7m.h"
+#include "rtos_standard_stackings.h"
+
+#define THREAD_DEFAULT_ID 0xff // when ucos is not running, this is the thread 
id
+
+static int ucos_detect_rtos(struct target *target);
+static int ucos_create(struct target *target);
+static int ucos_update_threads(struct rtos *rtos);
+static int ucos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
+                                   char **hex_reg_list);
+static int ucos_get_symbol_list_to_lookup(symbol_table_elem_t * symbol_list[]);
+
+struct ucos_thread_state {
+       int value;
+       char *desc;
+};
+
+struct ucos_thread_state ucos_thread_states[] = {
+       {0, "Ready"},
+       {1, "WaitSemaphore"},
+       {2, "WaitMailbox"},
+       {4, "WaitQ"},
+       {8, "Suspended"},
+       {0x10, "WaitMutex"},
+       {0x20, "WaitFlag"},
+       {0x40, "Sleep"},
+       {0x80, "WaitEvent"},
+};
+
+#define UCOS_NUM_STATES (sizeof(ucos_thread_states)/sizeof(struct 
ucos_thread_state))
+
+struct ucos_params {
+       char *target_name;
+       unsigned char pointer_width;
+       const struct rtos_register_stacking *stacking_info;
+};
+
+static const struct stack_register_offset
+    rtos_ucos_Cortex_M3_stack_offsets[ARMV7M_NUM_CORE_REGS] = {
+       {0x04, 32},             /* r0   */
+       {0x08, 32},             /* r1   */
+       {0x0c, 32},             /* r2   */
+       {0x10, 32},             /* r3   */
+       {0x14, 32},             /* r4   */
+       {0x18, 32},             /* r5   */
+       {0x1c, 32},             /* r6   */
+       {0x20, 32},             /* r7   */
+       {0x24, 32},             /* r8   */
+       {0x28, 32},             /* r9   */
+       {0x2c, 32},             /* r10  */
+       {0x30, 32},             /* r11  */
+       {0x34, 32},             /* r12  */
+       {-2, 32},               /* sp   */// new_stack_ptr
+       {-1, 32},               /* lr   */// zero
+       {0x3c, 32},             /* pc   */
+       {0x00, 32},             /* xPSR */
+};
+
+const struct rtos_register_stacking rtos_ucos_Cortex_M3_stacking = {
+       0x44,                   /* stack_registers_size */
+       -1,                     /* stack_growth_direction */
+       ARMV7M_NUM_CORE_REGS,   /* num_output_registers */
+       rtos_generic_stack_align8,      /* stack_alignment */
+       rtos_ucos_Cortex_M3_stack_offsets       /* register_offsets */
+};
+
+const struct ucos_params ucos_params_list[] = {
+       {
+        "arm7tdmi",            /* target_name */
+        4,                     /* pointer_width; */
+        &rtos_ucos_Cortex_M3_stacking  /* stacking_info */
+        },
+       {
+        "arm926ejs",           /* target_name */
+        4,                                     /* pointer_width; */
+        &rtos_ucos_Cortex_M3_stacking  /* stacking_info */
+        }
+};
+
+#define UCOS_NUM_PARAMS ((int)(sizeof(ucos_params_list)/sizeof(struct 
ucos_params)))
+
+enum ucos_symbol_values {
+       ucos_VAL_OSTCBPrioTbl,
+       ucos_VAL_OSTCBCur,
+       ucos_VAL_idle_stack,
+       ucos_VAL_name_offset,
+       ucos_VAL_size_tcb,
+       ucos_VAL_num_threads,
+       ucos_VAL_status_offset
+};
+
+static char *ucos_symbol_list[] = {
+       "OSTCBPrioTbl",
+       "OSTCBCur",
+       "OSTaskIdleStk",
+       "OSGdbHelpOffsetName",
+       "OSGdbHelpSizeTcb",
+       "OSGdbHelpMaxTcb",
+       "OSGdbHelpOffsetStat",
+       NULL
+};
+
+const struct rtos_type ucos_rtos = {
+       .name = "ucos",
+
+       .detect_rtos = ucos_detect_rtos,
+       .create = ucos_create,
+       .update_threads = ucos_update_threads,
+       .get_thread_reg_list = ucos_get_thread_reg_list,
+       .get_symbol_list_to_lookup = ucos_get_symbol_list_to_lookup,
+
+};
+
+static int ucos_update_threads(struct rtos *rtos)
+{
+       int retval;
+       int tasks_found = 0;
+       const struct ucos_params *param;
+
+       if (rtos == NULL)
+               return -1;
+
+       if (rtos->rtos_specific_params == NULL)
+               return -3;
+
+       param = (const struct ucos_params *)rtos->rtos_specific_params;
+
+       if (rtos->symbols == NULL) {
+               LOG_ERROR("No symbols for ucos");
+               return -4;
+       }
+
+       if (rtos->symbols[ucos_VAL_OSTCBPrioTbl].address == 0) {
+               LOG_ERROR("Don't have the thread list head");
+               return -2;
+       }
+
+       /* wipe out previous thread details if any */
+       rtos_free_threadlist(rtos);
+
+       /* determine the number of current threads */
+       uint32_t num_threads;
+       uint32_t tcb_size;
+       uint32_t name_offset;
+       uint32_t active_threads = 0;
+       uint32_t OSTCBCur;
+       uint32_t status_offset;
+       uint32_t i;
+
+       target_read_buffer(rtos->target,
+                          rtos->symbols[ucos_VAL_num_threads].address,
+                          param->pointer_width, (uint8_t *) & num_threads);
+       target_read_buffer(rtos->target,
+                          rtos->symbols[ucos_VAL_name_offset].address,
+                          param->pointer_width, (uint8_t *) & name_offset);
+       target_read_buffer(rtos->target,
+                          rtos->symbols[ucos_VAL_OSTCBCur].address,
+                          param->pointer_width, (uint8_t *) & OSTCBCur);
+       target_read_buffer(rtos->target,
+                          rtos->symbols[ucos_VAL_status_offset].address,
+                          param->pointer_width, (uint8_t *) & status_offset);
+       target_read_buffer(rtos->target,
+                          rtos->symbols[ucos_VAL_size_tcb].address,
+                          param->pointer_width, (uint8_t *) & tcb_size);
+
+       LOG_INFO
+           ("CurTask: %u TCB size: %u num threads: %u status off: %u name 
off:%u",
+            OSTCBCur, tcb_size, num_threads, status_offset, name_offset);
+
+       num_threads &= 63;
+       uint32_t *OSTCBPrioTbl = malloc(num_threads * param->pointer_width);
+
+       // sanity check
+       if (tcb_size < 0x1000) {
+               target_read_buffer(rtos->target,
+                                  rtos->symbols[ucos_VAL_OSTCBPrioTbl].address,
+                                  param->pointer_width * num_threads,
+                                  (uint8_t *) OSTCBPrioTbl);
+               rtos->current_thread = THREAD_DEFAULT_ID;
+
+               for (i = 0; i < num_threads; ++i) {
+
+                       if (OSTCBPrioTbl[i]) {
+                               ++active_threads;
+                       }
+                       if (OSTCBCur && OSTCBPrioTbl[i] == OSTCBCur) {
+                               rtos->current_thread = i;
+                       }
+
+               }
+               LOG_INFO("Found %u active tasks, %u is current thread",
+                        active_threads, (unsigned)rtos->current_thread);
+       } else {
+               LOG_WARNING
+                   ("ucos TCB size out of range.  Maybe the code is not loade 
yet??");
+               rtos->current_thread = THREAD_DEFAULT_ID;
+       }
+
+       tasks_found = 0;
+       if ((active_threads == 0)
+           || (rtos->current_thread == THREAD_DEFAULT_ID)) {
+               /* Either : No RTOS threads - there is always at least the 
current execution though */
+               /* OR     : No current thread - all threads suspended - show 
the current execution
+                * of idling */
+               LOG_INFO("ucos not running, defaulting to current execution");
+               char tmp_str[] = "Current Execution";
+               active_threads++;
+               tasks_found++;
+               rtos->thread_details =
+                   malloc(sizeof(struct thread_detail) * active_threads);
+               rtos->thread_details->threadid = THREAD_DEFAULT_ID;
+               rtos->thread_details->exists = true;
+               rtos->thread_details->extra_info_str = NULL;
+               rtos->thread_details->thread_name_str = malloc(sizeof(tmp_str));
+               strcpy(rtos->thread_details->thread_name_str, tmp_str);
+               rtos->current_thread = 0;
+
+               if (active_threads == 1) {
+                       rtos->thread_count = 1;
+                       retval = ERROR_OK;
+                       goto exit;
+               }
+       } else {
+               /* create space for new thread details */
+               rtos->thread_details =
+                   malloc(sizeof(struct thread_detail) * active_threads);
+       }
+
+       for (i = 0; i < num_threads; ++i) {
+               // get the trhead status
+               uint8_t thread_state;
+               uint8_t thread_prio;
+               uint8_t both[2];
+
+               if (OSTCBPrioTbl[i]) {
+                       char tmp_str[tcb_size - name_offset + 1];
+                       retval = target_read_buffer(rtos->target,
+                                                   OSTCBPrioTbl[i] +
+                                                   status_offset, 2,
+                                                   (uint8_t *) both);
+                       if (retval != ERROR_OK) {
+                               LOG_ERROR
+                                   ("Could not read ucos thread status from 
target");
+                               goto exit;
+                       }
+                       thread_state = both[0];
+                       thread_prio = both[1];
+                       rtos->thread_details[tasks_found].threadid =
+                           thread_prio;
+                       rtos->thread_details->exists = true;
+                       memset(tmp_str, 0, sizeof(tmp_str));
+                       retval = target_read_buffer(rtos->target,
+                                                   OSTCBPrioTbl[i] +
+                                                   name_offset,
+                                                   sizeof(tmp_str) - 1,
+                                                   (uint8_t *) tmp_str);
+
+                       if (retval != ERROR_OK) {
+                               LOG_ERROR
+                                   ("Could not read ucos thread name from 
target");
+                               goto exit;
+                       }
+
+                       LOG_INFO("Task %x: id: %d: name: %s detected",
+                                OSTCBPrioTbl[i], thread_prio, tmp_str);
+
+                       if (tmp_str[0] == '\x00')
+                               strcpy(tmp_str, "No Name");
+
+                       rtos->thread_details[tasks_found].thread_name_str =
+                           malloc(strlen(tmp_str) + 1);
+                       strcpy(rtos->thread_details[tasks_found].
+                              thread_name_str, tmp_str);
+
+                       uint32_t j;
+                       for (j = 0;
+                            (j < UCOS_NUM_STATES)
+                            && (ucos_thread_states[j].value != thread_state);
+                            j++) {
+                               /*
+                                * empty
+                                */
+                       }
+
+                       char *state_desc;
+                       if (j < UCOS_NUM_STATES)
+                               state_desc = ucos_thread_states[j].desc;
+                       else {
+                               sprintf(tmp_str, "state:%x", thread_state);
+                               state_desc = tmp_str;
+                       }
+                       if (OSTCBPrioTbl[i] == OSTCBCur) {
+                               state_desc = "Running";
+                       }
+
+                       rtos->thread_details[tasks_found].extra_info_str =
+                           malloc(strlen(state_desc) + 1);
+                       strcpy(rtos->thread_details[tasks_found].extra_info_str,
+                              state_desc);
+
+                       rtos->thread_details[tasks_found].exists = true;
+
+                       ++tasks_found;
+               }
+       }
+
+       LOG_INFO("Tasks found: %u", tasks_found);
+       retval = 0;
+
+ exit:
+       rtos->thread_count = tasks_found;
+
+       free(OSTCBPrioTbl);
+       return retval;
+}
+
+static int ucos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
+                                   char **hex_reg_list)
+{
+       int retval;
+       const struct ucos_params *param;
+
+       *hex_reg_list = NULL;
+
+       if (rtos == NULL)
+               return -1;
+
+       if (thread_id == THREAD_DEFAULT_ID)
+               return -1;
+
+       //if (thread_id == 0)
+       //    return -2;
+
+       if (rtos->rtos_specific_params == NULL)
+               return -3;
+
+       param = (const struct ucos_params *)rtos->rtos_specific_params;
+
+       /* Find the thread with that thread id */
+       uint32_t tcb_ptr = 0;
+       uint32_t thread_list_head =
+           rtos->symbols[ucos_VAL_OSTCBPrioTbl].address;
+
+       retval = target_read_buffer(rtos->target,
+                                   thread_list_head +
+                                   ((thread_id) * param->pointer_width),
+                                   param->pointer_width,
+                                   (uint8_t *) & tcb_ptr);
+
+       if (retval != ERROR_OK || tcb_ptr == 0) {
+               LOG_ERROR
+                   ("Error reading tcb from ucos thread (err: %d id: %u ptr: 
%u:%u",
+                    retval, (unsigned)thread_id,
+                    thread_list_head +
+                    ((unsigned)thread_id * param->pointer_width), tcb_ptr);
+               return retval;
+       }
+
+       uint32_t stack_ptr;
+       // read the stack pointer
+       target_read_buffer(rtos->target, tcb_ptr,       // stack pointer is the 
first thing in the TCB
+                          param->pointer_width, (uint8_t *) & stack_ptr);
+
+       LOG_INFO("Query regs for thread id %u, stack: %x", (int)thread_id,
+                stack_ptr);
+
+       return rtos_generic_stack_read(rtos->target,
+                                      param->stacking_info,
+                                      stack_ptr, hex_reg_list);
+
+}
+
+static int ucos_get_symbol_list_to_lookup(symbol_table_elem_t * symbol_list[])
+{
+       unsigned int i;
+       *symbol_list =
+           malloc(sizeof(symbol_table_elem_t) * ARRAY_SIZE(ucos_symbol_list));
+
+       for (i = 0; i < ARRAY_SIZE(ucos_symbol_list); i++)
+               (*symbol_list)[i].symbol_name = ucos_symbol_list[i];
+
+       return 0;
+}
+
+static int ucos_detect_rtos(struct target *target)
+{
+
+       if ((target->rtos->symbols != NULL) &&
+           (target->rtos->symbols[ucos_VAL_OSTCBPrioTbl].address != 0)) {
+               /* looks like ucos */
+               return 1;
+       }
+       return 0;
+}
+
+static int ucos_create(struct target *target)
+{
+       int i = 0;
+       while ((i < UCOS_NUM_PARAMS) &&
+              (0 !=
+               strcmp(ucos_params_list[i].target_name, target->type->name))) {
+               i++;
+       }
+       if (i >= UCOS_NUM_PARAMS) {
+               LOG_ERROR("Could not find target in ucos compatibility list");
+               return -1;
+       }
+
+       target->rtos->rtos_specific_params = (void *)&ucos_params_list[i];
+       target->rtos->current_thread = 0;
+       target->rtos->thread_details = NULL;
+       return 0;
+}

-- 

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to