This is an automated email from Gerrit.

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

-- gerrit

commit 2c1cb9de9551fb1dd0f01fab1175cf5c78d52e7b
Author: Kurt Go <[email protected]>
Date:   Fri Oct 28 12:02:59 2016 -0700

    Added ucos support
    
    Change-Id: I6266298b4eb45121ded33cc54c115317d5bdf1ff
    Signed-off-by: Paul Fertser <[email protected]>

diff --git a/src/rtos/Makefile.am b/src/rtos/Makefile.am
index fdca394..712b6b3 100644
--- a/src/rtos/Makefile.am
+++ b/src/rtos/Makefile.am
@@ -21,7 +21,7 @@ include $(top_srcdir)/common.mk
 METASOURCES = AUTO
 noinst_LTLIBRARIES = librtos.la
 noinst_HEADERS = rtos.h rtos_standard_stackings.h rtos_ecos_stackings.h 
linux_header.h rtos_chibios_stackings.h rtos_embkernel_stackings.h 
rtos_mqx_stackings.h
-librtos_la_SOURCES = rtos.c rtos_standard_stackings.c rtos_ecos_stackings.c  
rtos_chibios_stackings.c rtos_embkernel_stackings.c rtos_mqx_stackings.c 
FreeRTOS.c ThreadX.c eCos.c linux.c ChibiOS.c embKernel.c mqx.c
+librtos_la_SOURCES = rtos.c rtos_standard_stackings.c rtos_ecos_stackings.c  
rtos_chibios_stackings.c rtos_embkernel_stackings.c rtos_mqx_stackings.c 
FreeRTOS.c ThreadX.c eCos.c linux.c ChibiOS.c embKernel.c mqx.c ucos.c
 
 librtos_la_CFLAGS =
 if IS_MINGW
diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c
index 448c49c..e1b8465 100644
--- a/src/rtos/rtos.c
+++ b/src/rtos/rtos.c
@@ -34,6 +34,7 @@ extern struct rtos_type Linux_os;
 extern struct rtos_type ChibiOS_rtos;
 extern struct rtos_type embKernel_rtos;
 extern struct rtos_type mqx_rtos;
+extern struct rtos_type ucos_rtos;
 
 static struct rtos_type *rtos_types[] = {
        &ThreadX_rtos,
@@ -43,6 +44,7 @@ static struct rtos_type *rtos_types[] = {
        &ChibiOS_rtos,
        &embKernel_rtos,
        &mqx_rtos,
+       &ucos_rtos,
        NULL
 };
 
diff --git a/src/rtos/ucos.c b/src/rtos/ucos.c
new file mode 100644
index 0000000..ffd84af
--- /dev/null
+++ b/src/rtos/ucos.c
@@ -0,0 +1,420 @@
+/***************************************************************************
+ *                                                                         *
+ *   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 */
+        }
+};
+
+#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;
+}

-- 

------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today.http://sdm.link/intel
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to