This is an automated email from Gerrit.

Vlad Ivanov (vlad@ivanov.email) just uploaded a new patch set to Gerrit, which 
you can find at http://openocd.zylin.com/4486

-- gerrit

commit 401842e04dcff12afbc0e5a0247c34675f29ff35
Author: Vlad Ivanov <vlad@ivanov.email>
Date:   Mon Apr 9 06:12:40 2018 -0400

    Implement serdes_print_struct and RTOS conf listing
    
    Change-Id: Ic90bc275d177bd9c70f64560ed2610a6dfc1b645
    Signed-off-by: Vlad Ivanov <vlad@ivanov.email>

diff --git a/src/helper/serdes.c b/src/helper/serdes.c
index e992587..acfc7db 100644
--- a/src/helper/serdes.c
+++ b/src/helper/serdes.c
@@ -25,8 +25,51 @@
 #include "log.h"
 #include "serdes.h"
 
+union value_target {
+       void *data;
+       uint8_t *data_uint8;
+       int8_t *data_int8;
+       uint32_t *data_uint32;
+       int32_t *data_int32;
+};
+
+static char *string_trim(const char *str, size_t in_length,
+               size_t *out_length) {
+       size_t pos = 0;
+       size_t last_char = 0;
+       size_t result_length = strnlen(str, in_length);
+       char *result = calloc(result_length, 1);
+       bool started = false;
+
+       for (size_t i = 0; i < result_length; i++) {
+               if (!started) {
+                       if (str[i] != ' ') {
+                               started = true;
+                               result[pos] = str[i];
+                               last_char = pos;
+                               pos++;
+                       }
+               } else {
+                       result[pos] = str[i];
+                       pos++;
+
+                       if (str[i] != ' ') {
+                               last_char = pos;
+                       }
+               }
+       }
+
+       result[last_char] = '\0';
+
+       if (out_length) {
+               *out_length = last_char;
+       }
+
+       return result;
+}
+
 static int read_value(Jim_Interp *interp, Jim_Obj *value,
-               const struct serdes_field *field, void *storage)
+               enum serdes_type type, void *storage)
 {
        static struct {
                jim_wide lower;
@@ -38,7 +81,7 @@ static int read_value(Jim_Interp *interp, Jim_Obj *value,
                [serdes_int32]  = { INT32_MIN, INT32_MAX },
        };
 
-       switch (field->type) {
+       switch (type) {
                case serdes_uint8:
                case serdes_int8:
                case serdes_uint32:
@@ -51,36 +94,30 @@ static int read_value(Jim_Interp *interp, Jim_Obj *value,
                                return ERROR_FAIL;
                        }
 
-                       upper_limit = number_limits[field->type].upper;
-                       lower_limit = number_limits[field->type].lower;
+                       upper_limit = number_limits[type].upper;
+                       lower_limit = number_limits[type].lower;
 
                        if (wide > upper_limit || wide < lower_limit) {
                                LOG_ERROR("serdes: value %" JIM_WIDE_MODIFIER " 
is out of range", wide);
                                return ERROR_FAIL;
                        }
 
-                       union {
-                               void * data;
-                               uint8_t * data_uint8;
-                               int8_t * data_int8;
-                               uint32_t * data_uint32;
-                               int32_t * data_int32;
-                       } target = {
+                       union value_target target = {
                                .data = storage
                        };
 
-                       switch (field->type) {
+                       switch (type) {
                        case serdes_uint8:
-                               * target.data_uint8 = wide;
+                               *target.data_uint8 = wide;
                                break;
                        case serdes_int8:
-                               * target.data_int8 = wide;
+                               *target.data_int8 = wide;
                                break;
                        case serdes_uint32:
-                               * target.data_uint32 = wide;
+                               *target.data_uint32 = wide;
                                break;
                        case serdes_int32:
-                               * target.data_int32 = wide;
+                               *target.data_int32 = wide;
                                break;
                        default:
                                return ERROR_FAIL;
@@ -110,8 +147,42 @@ static int read_value(Jim_Interp *interp, Jim_Obj *value,
        return ERROR_OK;
 }
 
+static int print_value(const struct serdes_field *field, void *storage)
+{
+       union value_target target = {
+               .data = storage
+       };
+
+       fprintf(stderr, "\t.%s = ", field->name);
+
+       switch (field->type) {
+       case serdes_int8:
+               fprintf(stderr, "%" PRId8 ",", *target.data_int8);
+               break;
+       case serdes_uint8:
+               fprintf(stderr, "%" PRIu8 ",", *target.data_uint8);
+               break;
+       case serdes_int32:
+               fprintf(stderr, "%" PRId32 ",", *target.data_int32);
+               break;
+       case serdes_uint32:
+               fprintf(stderr, "%" PRIu32 ",", *target.data_uint32);
+               break;
+       case serdes_string:
+               fprintf(stderr, "%s", *(const char **) target.data);
+               break;
+       default:
+               return ERROR_FAIL;
+       }
+
+       fprintf(stderr, "\n");
+
+       return ERROR_OK;
+}
+
 int serdes_read_struct(Jim_Interp *interp, Jim_Obj **objects,
-               const struct serdes_field *fields, void *storage)
+               const struct serdes_field *fields, const struct serdes_wordset 
*wordset,
+               void *storage)
 {
        int result = ERROR_FAIL;
 
@@ -120,21 +191,67 @@ int serdes_read_struct(Jim_Interp *interp, Jim_Obj 
**objects,
        }
 
        const struct serdes_field *field;
+       Jim_Obj **object = objects;
+       char *key_trimmed = NULL;
 
-       // Skip first key
-       objects += 1;
        field = fields;
 
-       for (; field->offset != -1; field++, objects += 2) {
-               Jim_Obj *object = objects[0];
-               void * target = (void *) ((uintptr_t) storage + (uintptr_t) 
field->offset);
+       for (; field->offset != -1; field++) {
+               int len = 0;
+               size_t key_trimmed_length = 0;
+               const char *key_string = Jim_GetString(*object, &len);
 
-               if (read_value(interp, object, field, target) != ERROR_OK) {
+               key_trimmed = string_trim(key_string, len, &key_trimmed_length);
+               void *key = wordset->check(key_trimmed, key_trimmed_length);
+
+               if (!key) {
+                       LOG_ERROR("Unknown struct field: %s", key_trimmed);
                        goto error;
                }
+
+               object++;
+
+               size_t index = wordset->value(key);
+               void *target = (void *) ((uintptr_t) storage +
+                               (uintptr_t) fields[index].offset);
+
+               if (read_value(interp, *object,
+                               fields[index].type, target) != ERROR_OK) {
+                       goto error;
+               }
+
+               object++;
        }
 
        result = ERROR_OK;
 error:
+       if (key_trimmed) {
+               free(key_trimmed);
+       }
+
+       return result;
+}
+
+int serdes_print_struct(const struct serdes_field *fields, void *storage)
+{
+       int result = ERROR_FAIL;
+
+       if (fields == NULL) {
+               goto error;
+       }
+
+       const struct serdes_field *field = fields;
+
+       fprintf(stderr, "{\n");
+
+       for (; field->offset != -1; field++) {
+               void *target = (void *) ((uintptr_t) storage + (uintptr_t) 
field->offset);
+               print_value(field, target);
+       }
+
+       fprintf(stderr, "}\n");
+
+       result = ERROR_OK;
+error:
        return result;
 }
diff --git a/src/helper/serdes.h b/src/helper/serdes.h
index 9d615bd..e8e330c 100644
--- a/src/helper/serdes.h
+++ b/src/helper/serdes.h
@@ -33,9 +33,24 @@ enum serdes_type {
 struct serdes_field {
        enum serdes_type type;
        off_t offset;
+       const char * name;
 };
 
+typedef void * (* serdes_check_fn_t)(const char *text, size_t len);
+typedef int (* serdes_value_fn_t)(void *result);
+
+struct serdes_wordset {
+       serdes_check_fn_t check;
+       serdes_value_fn_t value;
+};
+
+#define SERDES_FIELD(type, base_type, name) \
+       { (type), offsetof(base_type, name), (#name) }
+
 int serdes_read_struct(Jim_Interp *interp, Jim_Obj **objects,
-               const struct serdes_field *fields, void *storage);
+               const struct serdes_field *fields, const struct serdes_wordset 
*wordset,
+               void *storage);
+
+int serdes_print_struct(const struct serdes_field *fields, void *storage);
 
 #endif /* OPENOCD_HELPER_SERDES_H */
diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c
index 33328b2..440ebff 100644
--- a/src/rtos/FreeRTOS.c
+++ b/src/rtos/FreeRTOS.c
@@ -21,6 +21,7 @@
 #endif
 
 #include <helper/time_support.h>
+#include <helper/list.h>
 #include <jtag/jtag.h>
 #include "target/target.h"
 #include "target/target_type.h"
@@ -35,9 +36,8 @@
 
 #define FREERTOS_MAX_PRIORITIES        63
 
-#define FreeRTOS_STRUCT(int_type, ptr_type, list_prev_offset)
-
 struct FreeRTOS_params {
+       struct list_head list;
        const char *target_name;
        const unsigned char thread_count_width;
        const unsigned char pointer_width;
@@ -52,52 +52,20 @@ struct FreeRTOS_params {
        const struct rtos_register_stacking *stacking_info_cm4f_fpu;
 };
 
-static const struct FreeRTOS_params FreeRTOS_params_list[] = {
-       {
-       "cortex_m",                     /* target_name */
-       4,                                              /* thread_count_width; 
*/
-       4,                                              /* pointer_width; */
-       16,                                             /* list_next_offset; */
-       20,                                             /* list_width; */
-       8,                                              /* 
list_elem_next_offset; */
-       12,                                             /* 
list_elem_content_offset */
-       0,                                              /* thread_stack_offset; 
*/
-       52,                                             /* thread_name_offset; 
*/
-       &rtos_standard_Cortex_M3_stacking,      /* stacking_info */
-       &rtos_standard_Cortex_M4F_stacking,
-       &rtos_standard_Cortex_M4F_FPU_stacking,
-       },
-       {
-       "hla_target",                   /* target_name */
-       4,                                              /* thread_count_width; 
*/
-       4,                                              /* pointer_width; */
-       16,                                             /* list_next_offset; */
-       20,                                             /* list_width; */
-       8,                                              /* 
list_elem_next_offset; */
-       12,                                             /* 
list_elem_content_offset */
-       0,                                              /* thread_stack_offset; 
*/
-       52,                                             /* thread_name_offset; 
*/
-       &rtos_standard_Cortex_M3_stacking,      /* stacking_info */
-       &rtos_standard_Cortex_M4F_stacking,
-       &rtos_standard_Cortex_M4F_FPU_stacking,
-       },
-       {
-       "nds32_v3",                     /* target_name */
-       4,                                              /* thread_count_width; 
*/
-       4,                                              /* pointer_width; */
-       16,                                             /* list_next_offset; */
-       20,                                             /* list_width; */
-       8,                                              /* 
list_elem_next_offset; */
-       12,                                             /* 
list_elem_content_offset */
-       0,                                              /* thread_stack_offset; 
*/
-       52,                                             /* thread_name_offset; 
*/
-       &rtos_standard_NDS32_N1068_stacking,    /* stacking_info */
-       &rtos_standard_Cortex_M4F_stacking,
-       &rtos_standard_Cortex_M4F_FPU_stacking,
-       },
+static const struct serdes_field freertos_params_fields[] = {
+       SERDES_FIELD(serdes_string, struct FreeRTOS_params, target_name),
+       SERDES_FIELD(serdes_uint8,  struct FreeRTOS_params, thread_count_width),
+       SERDES_FIELD(serdes_uint8,  struct FreeRTOS_params, pointer_width),
+       SERDES_FIELD(serdes_uint8,  struct FreeRTOS_params, list_next_offset),
+       SERDES_FIELD(serdes_uint8,  struct FreeRTOS_params, list_width),
+       SERDES_FIELD(serdes_uint8,  struct FreeRTOS_params, 
list_elem_next_offset),
+       SERDES_FIELD(serdes_uint8,  struct FreeRTOS_params, 
list_elem_content_offset),
+       SERDES_FIELD(serdes_uint8,  struct FreeRTOS_params, 
thread_stack_offset),
+       SERDES_FIELD(serdes_uint8,  struct FreeRTOS_params, thread_name_offset),
+       { 0, -1 }
 };
 
-#define FREERTOS_NUM_PARAMS ((int)(sizeof(FreeRTOS_params_list)/sizeof(struct 
FreeRTOS_params)))
+static LIST_HEAD(freertos_params_list);
 
 static bool FreeRTOS_detect_rtos(struct target *target);
 static int FreeRTOS_create(struct target *target);
@@ -105,6 +73,7 @@ static int FreeRTOS_update_threads(struct rtos *rtos);
 static int FreeRTOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, 
char **hex_reg_list);
 static int FreeRTOS_get_symbol_list_to_lookup(symbol_table_elem_t 
*symbol_list[]);
 static int FreeRTOS_conf_add(Jim_Interp *interp, Jim_Obj **elements, int 
count);
+static int FreeRTOS_conf_list(void);
 
 struct rtos_type FreeRTOS_rtos = {
        .name = "FreeRTOS",
@@ -115,6 +84,7 @@ struct rtos_type FreeRTOS_rtos = {
        .get_thread_reg_list = FreeRTOS_get_thread_reg_list,
        .get_symbol_list_to_lookup = FreeRTOS_get_symbol_list_to_lookup,
        .conf_add = FreeRTOS_conf_add,
+       .conf_list = FreeRTOS_conf_list,
 };
 
 enum FreeRTOS_symbol_values {
@@ -542,47 +512,65 @@ static bool FreeRTOS_detect_rtos(struct target *target)
 
 static int FreeRTOS_create(struct target *target)
 {
-       int i = 0;
-       while ((i < FREERTOS_NUM_PARAMS) &&
-                       (0 != strcmp(FreeRTOS_params_list[i].target_name, 
target->type->name))) {
-               i++;
+       struct FreeRTOS_params *param;
+       bool found = false;
+
+       list_for_each_entry(param, &freertos_params_list, list) {
+               if (strcmp(param->target_name, target->type->name) == 0) {
+                       found = true;
+                       break;
+               }
        }
-       if (i >= FREERTOS_NUM_PARAMS) {
+
+       if (!found) {
                LOG_ERROR("Could not find target in FreeRTOS compatibility 
list");
-               return -1;
+               return ERROR_FAIL;
        }
 
-       target->rtos->rtos_specific_params = (void *) &FreeRTOS_params_list[i];
-       return 0;
+       target->rtos->rtos_specific_params = param;
+
+       return ERROR_OK;
+}
+
+static int FreeRTOS_conf_list(void) {
+       struct FreeRTOS_params *param;
+
+       list_for_each_entry(param, &freertos_params_list, list) {
+               serdes_print_struct(freertos_params_fields, param);
+       }
+
+       return ERROR_OK;
+}
+
+static int FreeRTOS_wordset_value(struct freertos_lookup_entry *entry) {
+       return entry->option;
 }
 
 static int FreeRTOS_conf_add(Jim_Interp *interp, Jim_Obj **elements, int count)
 {
-       static const struct serdes_field fields[] = {
-               { serdes_string, offsetof(struct FreeRTOS_params, target_name) 
},
-               { serdes_uint8,  offsetof(struct FreeRTOS_params, 
thread_count_width) },
-               { serdes_uint8,  offsetof(struct FreeRTOS_params, 
pointer_width) },
-               { serdes_uint8,  offsetof(struct FreeRTOS_params, 
list_next_offset) },
-               { serdes_uint8,  offsetof(struct FreeRTOS_params, list_width) },
-               { serdes_uint8,  offsetof(struct FreeRTOS_params, 
list_elem_next_offset) },
-               { serdes_uint8,  offsetof(struct FreeRTOS_params, 
list_elem_content_offset) },
-               { serdes_uint8,  offsetof(struct FreeRTOS_params, 
thread_stack_offset) },
-               { serdes_uint8,  offsetof(struct FreeRTOS_params, 
thread_name_offset) },
-               { 0, -1 }
-       };
-
-       struct FreeRTOS_params params;
+       struct FreeRTOS_params *params;
        int result = ERROR_FAIL;
 
+       params = calloc(1, sizeof(struct FreeRTOS_params));
+
        if (count != freertos_option_count * 2) {
                LOG_ERROR("freertos: invalid number of elements in 
configuration");
+               goto error;
        }
 
-       if (serdes_read_struct(interp, elements, fields, &params) != ERROR_OK) {
+       struct serdes_wordset wordset = {
+               .check = (serdes_check_fn_t) freertos_in_word_set,
+               .value = (serdes_value_fn_t) FreeRTOS_wordset_value,
+       };
+
+       if (serdes_read_struct(interp, elements, freertos_params_fields,
+                       &wordset, params) != ERROR_OK) {
                LOG_ERROR("freertos: unable to read configuration");
                goto error;
        }
 
+       list_add(&params->list, &freertos_params_list);
+
        result = ERROR_OK;
 error:
        return result;
diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c
index 113349f..4371830 100644
--- a/src/rtos/rtos.c
+++ b/src/rtos/rtos.c
@@ -580,16 +580,11 @@ void rtos_free_threadlist(struct rtos *rtos)
        }
 }
 
-COMMAND_HANDLER(rtos_list) {
-
-       return ERROR_OK;
-}
-
-static int rtos_conf_add(Jim_Interp *interp, int argc, Jim_Obj *const *argv) {
-       const struct rtos_type * rtos_conf_add_map[] = {
-               [ rtos_freertos ] = &FreeRTOS_rtos,
-       };
+static const struct rtos_type * rtos_conf_map[] = {
+       [ rtos_freertos ] = &FreeRTOS_rtos,
+};
 
+static rtos_option_t get_rtos_type(Jim_GetOptInfo *goi) {
        enum rtos_add_options {
                ADD_OPT_TYPE = 0,
        };
@@ -599,22 +594,10 @@ static int rtos_conf_add(Jim_Interp *interp, int argc, 
Jim_Obj *const *argv) {
                { NULL, -1 },
        };
 
-       Jim_GetOptInfo goi;
-       Jim_Obj *dict;
-       Jim_Obj **pairs;
-       int pair_count;
        Jim_Nvp *nvp;
+       rtos_option_t result = rtos_invalid;
 
-       int result = ERROR_FAIL;
-       int rtos_type = rtos_invalid;
-
-       if (Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1) != JIM_OK) {
-               goto error;
-       }
-
-       Jim_GetOpt_Debug(&goi);
-
-       if (Jim_GetOpt_Nvp(&goi, options, &nvp) != JIM_OK) {
+       if (Jim_GetOpt_Nvp(goi, options, &nvp) != JIM_OK) {
                goto error;
        }
 
@@ -623,7 +606,7 @@ static int rtos_conf_add(Jim_Interp *interp, int argc, 
Jim_Obj *const *argv) {
                int value_len;
                struct rtos_lookup_entry *entry;
 
-               if (Jim_GetOpt_String(&goi, &value, &value_len) != JIM_OK) {
+               if (Jim_GetOpt_String(goi, &value, &value_len) != JIM_OK) {
                        goto error;
                }
 
@@ -634,9 +617,59 @@ static int rtos_conf_add(Jim_Interp *interp, int argc, 
Jim_Obj *const *argv) {
                        goto error;
                }
 
-               rtos_type = entry->option;
+               result = entry->option;
+       }
+
+error:
+       return result;
+}
+
+static int rtos_conf_list(Jim_Interp *interp, int argc, Jim_Obj *const *argv) {
+       Jim_GetOptInfo goi;
+
+       rtos_option_t rtos_type = rtos_invalid;
+       int result = ERROR_FAIL;
+
+       if (Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1) != JIM_OK) {
+               goto error;
+       }
+
+       rtos_type = get_rtos_type(&goi);
+
+       if (rtos_type == rtos_invalid) {
+               LOG_ERROR("invalid RTOS type provided");
+               goto error;
        }
 
+       if (!rtos_conf_map[rtos_type]->conf_list) {
+               LOG_ERROR("specified RTOS type does not support dynamic 
configurations");
+               goto error;
+       }
+
+       if (rtos_conf_map[rtos_type]->conf_list() != ERROR_OK) {
+               goto error;
+       }
+
+       result = ERROR_OK;
+error:
+       return result;
+}
+
+static int rtos_conf_add(Jim_Interp *interp, int argc, Jim_Obj *const *argv) {
+       Jim_GetOptInfo goi;
+       Jim_Obj *dict;
+       Jim_Obj **pairs;
+       int pair_count;
+
+       int result = ERROR_FAIL;
+       int rtos_type = rtos_invalid;
+
+       if (Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1) != JIM_OK) {
+               goto error;
+       }
+
+       rtos_type = get_rtos_type(&goi);
+
        if (rtos_type == rtos_invalid) {
                LOG_ERROR("invalid RTOS type provided");
                goto error;
@@ -652,12 +685,12 @@ static int rtos_conf_add(Jim_Interp *interp, int argc, 
Jim_Obj *const *argv) {
                goto error;
        }
 
-       if (!rtos_conf_add_map[rtos_type]->conf_add) {
+       if (!rtos_conf_map[rtos_type]->conf_add) {
                LOG_ERROR("specified RTOS type does not support dynamic 
configurations");
                goto error;
        }
 
-       if (rtos_conf_add_map[rtos_type]->conf_add(interp, pairs, pair_count) 
!= ERROR_OK) {
+       if (rtos_conf_map[rtos_type]->conf_add(interp, pairs, pair_count) != 
ERROR_OK) {
                goto error;
        }
 
@@ -669,17 +702,17 @@ error:
 static const struct command_registration rtos_exec_command_handlers[] = {
        {
                .name = "list",
-               .handler = rtos_list,
-               .mode = COMMAND_EXEC,
-               .help = "List available RTOS / targets",
-               .usage = "",
+               .mode = COMMAND_ANY,
+               .jim_handler = rtos_conf_list,
+               .help = "List available RTOS configurations",
+               .usage = "-type <RTOS type>",
        },
        {
                .name = "add",
                .mode = COMMAND_ANY,
                .jim_handler = rtos_conf_add,
                .help = "Add RTOS target",
-               .usage = "-type <RTOS type>",
+               .usage = "-type <RTOS type> <parameter dictionary>",
        },
        COMMAND_REGISTRATION_DONE
 };
diff --git a/src/rtos/rtos.h b/src/rtos/rtos.h
index 443c10f..e912406 100644
--- a/src/rtos/rtos.h
+++ b/src/rtos/rtos.h
@@ -71,6 +71,7 @@ struct rtos_type {
        int (*clean)(struct target *target);
        char * (*ps_command)(struct target *target);
        int (*conf_add)(Jim_Interp *, Jim_Obj **, int);
+       int (*conf_list)(void);
 };
 
 struct stack_register_offset {
diff --git a/src/target/target.c b/src/target/target.c
index 729a31b..c449872 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -1403,7 +1403,6 @@ int target_register_reset_callback(int (*callback)(struct 
target *target,
        entry->priv = priv;
        list_add(&entry->list, &target_reset_callback_list);
 
-
        return ERROR_OK;
 }
 

-- 

------------------------------------------------------------------------------
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
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to