* 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "helper/types.h"
#include "rtos_chibios_stackings.h"
-
/**
* @brief ChibiOS/RT memory signature record.
*
/**
* @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"
const struct rtos_register_stacking *stacking_info;
};
-struct ChibiOS_params ChibiOS_params_list[] = {
+static struct ChibiOS_params ChibiOS_params_list[] = {
{
- "cortex_m3", /* target_name */
+ "cortex_m", /* target_name */
0,
NULL, /* stacking_info */
},
{
- "stm32_stlink", /* target_name */
+ "hla_target", /* target_name */
0,
NULL, /* stacking_info */
}
.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
};
-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 */
+ { 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;
/* Sometimes the stacking can not be determined only by looking at the
* target name but only a runtime.
*
- * For example, this is the case for cortex-m4 targets and ChibiOS which
+ * For example, this is the case for Cortex-M4 targets and ChibiOS which
* only stack the FPU registers if it is enabled during ChibiOS build.
*
* Terminating which stacking is used is target depending.
struct ChibiOS_params *param;
param = (struct ChibiOS_params *) rtos->rtos_specific_params;
- /* Check for armv7m with *enabled* FPU, i.e. a Cortex M4 */
+ /* Check for armv7m with *enabled* FPU, i.e. a Cortex-M4 */
struct armv7m_common *armv7m_target = target_to_armv7m(rtos->target);
if (is_armv7m(armv7m_target)) {
if (armv7m_target->fp_feature == FPv4_SP) {
/* 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;
}
}
}
/* 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;
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);
}
/* 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");
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);
if (threadState < CHIBIOS_NUM_STATES)
state_desc = ChibiOS_thread_states[threadState];
else
- state_desc = "Unknown state";
+ state_desc = "Unknown";
- curr_thrd_details->extra_info_str = (char *)malloc(strlen(
- state_desc)+1);
- strcpy(curr_thrd_details->extra_info_str, state_desc);
+ curr_thrd_details->extra_info_str = malloc(strlen(
+ state_desc)+8);
+ sprintf(curr_thrd_details->extra_info_str, "State: %s", state_desc);
curr_thrd_details->exists = true;
- curr_thrd_details->display_str = NULL;
curr_thrd_details++;
}
uint32_t current_thrd;
/* NOTE: By design, cf_off_name equals readylist_current_offset */
retval = target_read_u32(rtos->target,
- current + signature->cf_off_name,
+ rlist + signature->cf_off_name,
¤t_thrd);
if (retval != ERROR_OK) {
LOG_ERROR("Could not read current Thread from ChibiOS target");
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_chSysInit].address != 0)) {
+ ((target->rtos->symbols[ChibiOS_VAL_rlist].address != 0) ||
+ (target->rtos->symbols[ChibiOS_VAL_ch].address != 0))) {
if (target->rtos->symbols[ChibiOS_VAL_ch_debug].address == 0) {
- LOG_INFO("It looks like the target is running ChibiOS without "
- "ch_debug.");
+ LOG_INFO("It looks like the target may be running ChibiOS "
+ "without ch_debug.");
return 0;
}