]> git.sur5r.net Git - openocd/blobdiff - src/rtos/ChibiOS.c
ChibiOS: fix crash on auto detection
[openocd] / src / rtos / ChibiOS.c
index 47e7fc5ddbb531a56faedac20b09bcb0c87e038f..84393860c1d758ae04c61ff2b21d004dbbceeeca 100644 (file)
@@ -36,7 +36,6 @@
 #include "helper/types.h"
 #include "rtos_chibios_stackings.h"
 
-
 /**
  * @brief   ChibiOS/RT memory signature record.
  *
@@ -72,7 +71,7 @@ struct ChibiOS_chdebug {
 /**
  * @brief ChibiOS thread states.
  */
-const char *ChibiOS_thread_states[] = {
+static const char * const ChibiOS_thread_states[] = {
        "READY", "CURRENT", "SUSPENDED", "WTSEM", "WTMTX", "WTCOND", "SLEEPING",
        "WTEXIT", "WTOREVT", "WTANDEVT", "SNDMSGQ", "SNDMSG", "WTMSG", "WTQUEUE",
        "FINAL"
@@ -92,7 +91,7 @@ struct ChibiOS_params {
        const struct rtos_register_stacking *stacking_info;
 };
 
-struct ChibiOS_params ChibiOS_params_list[] = {
+static struct ChibiOS_params ChibiOS_params_list[] = {
        {
        "cortex_m",                                                     /* target_name */
        0,
@@ -122,19 +121,30 @@ struct rtos_type ChibiOS_rtos = {
        .get_symbol_list_to_lookup = ChibiOS_get_symbol_list_to_lookup,
 };
 
+
+/* In ChibiOS/RT 3.0 the rlist structure has become part of a system
+ * data structure ch. We declare both symbols as optional and later
+ * use whatever is available.
+ */
+
 enum ChibiOS_symbol_values {
        ChibiOS_VAL_rlist = 0,
-       ChibiOS_VAL_ch_debug = 1,
-       ChibiOS_VAL_chSysInit = 2
+       ChibiOS_VAL_ch = 1,
+       ChibiOS_VAL_ch_debug = 2,
+       ChibiOS_VAL_chSysInit = 3
 };
 
-static char *ChibiOS_symbol_list[] = {
-       "rlist",                /* Thread ready list*/
-       "ch_debug",             /* Memory Signatur containing offsets of fields in rlist*/
-       "chSysInit",    /* Necessary part of API, used for ChibiOS detection*/
-       NULL
+static symbol_table_elem_t ChibiOS_symbol_list[] = {
+       { "rlist", 0, true},            /* Thread ready list */
+       { "ch", 0, true},                       /* System data structure */
+       { "ch_debug", 0, false},        /* Memory Signature containing offsets of fields in rlist */
+       { "chSysInit", 0, false},       /* Necessary part of API, used for ChibiOS detection */
+       { NULL, 0, false}
 };
 
+/* Offset of the rlist structure within the system data structure (ch) */
+#define CH_RLIST_OFFSET 0x00
+
 static int ChibiOS_update_memory_signature(struct rtos *rtos)
 {
        int retval;
@@ -254,11 +264,9 @@ static int ChibiOS_update_stacking(struct rtos *rtos)
                        /* Check if CP10 and CP11 are set to full access.
                         * In ChibiOS this is done in ResetHandler() in crt0.c */
                        if (cpacr & 0x00F00000) {
-                               /* Found target with enabled FPU */
-                               /* FIXME: Need to figure out how to specify the FPU registers */
-                               LOG_ERROR("ChibiOS ARM v7m targets with enabled FPU "
-                                                 " are NOT supported");
-                               return -1;
+                               LOG_DEBUG("Enabled FPU detected.");
+                               param->stacking_info = &rtos_chibios_arm_v7m_stacking_w_fpu;
+                               return 0;
                        }
                }
 
@@ -296,25 +304,14 @@ static int ChibiOS_update_threads(struct rtos *rtos)
        }
 
        /* wipe out previous thread details if any */
-       int j;
-       if (rtos->thread_details) {
-               for (j = 0; j < rtos->thread_count; j++) {
-                       struct thread_detail *current_thread = &rtos->thread_details[j];
-                       if (current_thread->display_str != NULL)
-                               free(current_thread->display_str);
-                       if (current_thread->thread_name_str != NULL)
-                               free(current_thread->thread_name_str);
-                       if (current_thread->extra_info_str != NULL)
-                               free(current_thread->extra_info_str);
-               }
-               free(rtos->thread_details);
-               rtos->thread_details = NULL;
-               rtos->thread_count = 0;
-       }
+       rtos_free_threadlist(rtos);
+
        /* ChibiOS does not save the current thread count. We have to first
         * parse the double linked thread list to check for errors and the number of
         * threads. */
-       const uint32_t rlist = rtos->symbols[ChibiOS_VAL_rlist].address;
+       const uint32_t rlist = rtos->symbols[ChibiOS_VAL_rlist].address ?
+               rtos->symbols[ChibiOS_VAL_rlist].address :
+               rtos->symbols[ChibiOS_VAL_ch].address + CH_RLIST_OFFSET /* ChibiOS3 */;
        const struct ChibiOS_chdebug *signature = param->signature;
        uint32_t current;
        uint32_t previous;
@@ -360,17 +357,17 @@ static int ChibiOS_update_threads(struct rtos *rtos)
                const char tmp_thread_name[] = "Current Execution";
                const char tmp_thread_extra_info[] = "No RTOS thread";
 
-               rtos->thread_details = (struct thread_detail *) malloc(
+               rtos->thread_details = malloc(
                                sizeof(struct thread_detail));
                rtos->thread_details->threadid = 1;
                rtos->thread_details->exists = true;
                rtos->thread_details->display_str = NULL;
 
-               rtos->thread_details->extra_info_str = (char *) malloc(
+               rtos->thread_details->extra_info_str = malloc(
                                sizeof(tmp_thread_extra_info));
                strcpy(rtos->thread_details->extra_info_str, tmp_thread_extra_info);
 
-               rtos->thread_details->thread_name_str = (char *) malloc(
+               rtos->thread_details->thread_name_str = malloc(
                                sizeof(tmp_thread_name));
                strcpy(rtos->thread_details->thread_name_str, tmp_thread_name);
 
@@ -380,7 +377,7 @@ static int ChibiOS_update_threads(struct rtos *rtos)
        }
 
        /* create space for new thread details */
-       rtos->thread_details = (struct thread_detail *) malloc(
+       rtos->thread_details = malloc(
                        sizeof(struct thread_detail) * tasks_found);
        if (!rtos->thread_details) {
                LOG_ERROR("Could not allocate space for thread details");
@@ -429,7 +426,7 @@ static int ChibiOS_update_threads(struct rtos *rtos)
                if (tmp_str[0] == '\x00')
                        strcpy(tmp_str, "No Name");
 
-               curr_thrd_details->thread_name_str = (char *)malloc(
+               curr_thrd_details->thread_name_str = malloc(
                                strlen(tmp_str) + 1);
                strcpy(curr_thrd_details->thread_name_str, tmp_str);
 
@@ -450,7 +447,7 @@ static int ChibiOS_update_threads(struct rtos *rtos)
                else
                        state_desc = "Unknown state";
 
-               curr_thrd_details->extra_info_str = (char *)malloc(strlen(
+               curr_thrd_details->extra_info_str = malloc(strlen(
                                        state_desc)+1);
                strcpy(curr_thrd_details->extra_info_str, state_desc);
 
@@ -510,20 +507,20 @@ static int ChibiOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, cha
 
 static int ChibiOS_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[])
 {
-       unsigned int i;
-       *symbol_list = (symbol_table_elem_t *) malloc(
-                       sizeof(symbol_table_elem_t) * ARRAY_SIZE(ChibiOS_symbol_list));
+       *symbol_list = malloc(sizeof(ChibiOS_symbol_list));
 
-       for (i = 0; i < ARRAY_SIZE(ChibiOS_symbol_list); i++)
-               (*symbol_list)[i].symbol_name = ChibiOS_symbol_list[i];
+       if (*symbol_list == NULL)
+               return ERROR_FAIL;
 
+       memcpy(*symbol_list, ChibiOS_symbol_list, sizeof(ChibiOS_symbol_list));
        return 0;
 }
 
 static int ChibiOS_detect_rtos(struct target *target)
 {
        if ((target->rtos->symbols != NULL) &&
-                       (target->rtos->symbols[ChibiOS_VAL_rlist].address != 0) &&
+                       ((target->rtos->symbols[ChibiOS_VAL_rlist].address != 0) ||
+                        (target->rtos->symbols[ChibiOS_VAL_ch].address != 0)) &&
                        (target->rtos->symbols[ChibiOS_VAL_chSysInit].address != 0)) {
 
                if (target->rtos->symbols[ChibiOS_VAL_ch_debug].address == 0) {