build: cleanup src/rtos directory

Change-Id: I24bc62d12409dbfc20a0a986acf6b3f2c913e36d
Signed-off-by: Spencer Oliver <spen@spen-soft.co.uk>
Reviewed-on: http://openocd.zylin.com/416
Tested-by: jenkins
This commit is contained in:
Spencer Oliver 2012-01-30 15:32:53 +00:00
parent 8b00e56e64
commit 7b032df3aa
10 changed files with 1116 additions and 1346 deletions

View File

@ -18,7 +18,6 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -33,9 +32,7 @@
#define FreeRTOS_STRUCT(int_type, ptr_type, list_prev_offset) #define FreeRTOS_STRUCT(int_type, ptr_type, list_prev_offset)
struct FreeRTOS_params {
struct FreeRTOS_params
{
const char *target_name; const char *target_name;
const unsigned char thread_count_width; const unsigned char thread_count_width;
const unsigned char pointer_width; const unsigned char pointer_width;
@ -48,26 +45,21 @@ struct FreeRTOS_params
const struct rtos_register_stacking *stacking_info; const struct rtos_register_stacking *stacking_info;
}; };
const struct FreeRTOS_params FreeRTOS_params_list[] = {
const struct FreeRTOS_params FreeRTOS_params_list[] =
{ {
{ "cortex_m3", // target_name "cortex_m3", /* target_name */
4, // thread_count_width; 4, /* thread_count_width; */
4, // pointer_width; 4, /* pointer_width; */
16, // list_next_offset; 16, /* list_next_offset; */
20, // list_width; 20, /* list_width; */
8, // list_elem_next_offset; 8, /* list_elem_next_offset; */
12, // list_elem_content_offset 12, /* list_elem_content_offset */
0, // thread_stack_offset; 0, /* thread_stack_offset; */
52, // thread_name_offset; 52, /* thread_name_offset; */
&rtos_standard_Cortex_M3_stacking, // stacking_info &rtos_standard_Cortex_M3_stacking, /* stacking_info */
} }
}; };
#define FREERTOS_NUM_PARAMS ((int)(sizeof(FreeRTOS_params_list)/sizeof(struct FreeRTOS_params))) #define FREERTOS_NUM_PARAMS ((int)(sizeof(FreeRTOS_params_list)/sizeof(struct FreeRTOS_params)))
static int FreeRTOS_detect_rtos(struct target *target); static int FreeRTOS_detect_rtos(struct target *target);
@ -76,11 +68,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_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_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]);
struct rtos_type FreeRTOS_rtos = {
struct rtos_type FreeRTOS_rtos =
{
.name = "FreeRTOS", .name = "FreeRTOS",
.detect_rtos = FreeRTOS_detect_rtos, .detect_rtos = FreeRTOS_detect_rtos,
@ -90,8 +78,7 @@ struct rtos_type FreeRTOS_rtos =
.get_symbol_list_to_lookup = FreeRTOS_get_symbol_list_to_lookup, .get_symbol_list_to_lookup = FreeRTOS_get_symbol_list_to_lookup,
}; };
enum FreeRTOS_symbol_values enum FreeRTOS_symbol_values {
{
FreeRTOS_VAL_pxCurrentTCB = 0, FreeRTOS_VAL_pxCurrentTCB = 0,
FreeRTOS_VAL_pxReadyTasksLists = 1, FreeRTOS_VAL_pxReadyTasksLists = 1,
FreeRTOS_VAL_xDelayedTaskList1 = 2, FreeRTOS_VAL_xDelayedTaskList1 = 2,
@ -105,8 +92,7 @@ enum FreeRTOS_symbol_values
FreeRTOS_VAL_uxTopUsedPriority = 10, FreeRTOS_VAL_uxTopUsedPriority = 10,
}; };
static char* FreeRTOS_symbol_list[] = static char *FreeRTOS_symbol_list[] = {
{
"pxCurrentTCB", "pxCurrentTCB",
"pxReadyTasksLists", "pxReadyTasksLists",
"xDelayedTaskList1", "xDelayedTaskList1",
@ -123,10 +109,10 @@ static char* FreeRTOS_symbol_list[] =
#define FREERTOS_NUM_SYMBOLS (sizeof(FreeRTOS_symbol_list)/sizeof(char *)) #define FREERTOS_NUM_SYMBOLS (sizeof(FreeRTOS_symbol_list)/sizeof(char *))
// TODO: /* TODO: */
// this is not safe for little endian yet /* this is not safe for little endian yet */
// may be problems reading if sizes are not 32 bit long integers. /* may be problems reading if sizes are not 32 bit long integers. */
// test mallocs for failure /* test mallocs for failure */
static int FreeRTOS_update_threads(struct rtos *rtos) static int FreeRTOS_update_threads(struct rtos *rtos)
{ {
@ -136,52 +122,44 @@ static int FreeRTOS_update_threads( struct rtos *rtos )
const struct FreeRTOS_params *param; const struct FreeRTOS_params *param;
if (rtos->rtos_specific_params == NULL) if (rtos->rtos_specific_params == NULL)
{
return -1; return -1;
}
param = (const struct FreeRTOS_params *) rtos->rtos_specific_params; param = (const struct FreeRTOS_params *) rtos->rtos_specific_params;
if ( rtos->symbols == NULL ) if (rtos->symbols == NULL) {
{
LOG_OUTPUT("No symbols for FreeRTOS\r\n"); LOG_OUTPUT("No symbols for FreeRTOS\r\n");
return -3; return -3;
} }
if ( rtos->symbols[FreeRTOS_VAL_uxCurrentNumberOfTasks].address == 0 ) if (rtos->symbols[FreeRTOS_VAL_uxCurrentNumberOfTasks].address == 0) {
{
LOG_OUTPUT("Don't have the number of threads in FreeRTOS \r\n"); LOG_OUTPUT("Don't have the number of threads in FreeRTOS \r\n");
return -2; return -2;
} }
int thread_list_size = 0; int thread_list_size = 0;
retval = target_read_buffer( rtos->target, rtos->symbols[FreeRTOS_VAL_uxCurrentNumberOfTasks].address, param->thread_count_width, (uint8_t *)&thread_list_size); retval = target_read_buffer(rtos->target,
rtos->symbols[FreeRTOS_VAL_uxCurrentNumberOfTasks].address,
param->thread_count_width,
(uint8_t *)&thread_list_size);
if ( retval != ERROR_OK ) if (retval != ERROR_OK) {
{
LOG_OUTPUT("Could not read FreeRTOS thread count from target\r\n"); LOG_OUTPUT("Could not read FreeRTOS thread count from target\r\n");
return retval; return retval;
} }
/* wipe out previous thread details if any */
// wipe out previous thread details if any if (rtos->thread_details != NULL) {
if ( rtos->thread_details != NULL )
{
int j; int j;
for( j = 0; j < rtos->thread_count; j++ ) for (j = 0; j < rtos->thread_count; j++) {
{ if (rtos->thread_details[j].display_str != NULL) {
if ( rtos->thread_details[j].display_str != NULL )
{
free(rtos->thread_details[j].display_str); free(rtos->thread_details[j].display_str);
rtos->thread_details[j].display_str = NULL; rtos->thread_details[j].display_str = NULL;
} }
if ( rtos->thread_details[j].thread_name_str != NULL ) if (rtos->thread_details[j].thread_name_str != NULL) {
{
free(rtos->thread_details[j].thread_name_str); free(rtos->thread_details[j].thread_name_str);
rtos->thread_details[j].thread_name_str = NULL; rtos->thread_details[j].thread_name_str = NULL;
} }
if ( rtos->thread_details[j].extra_info_str != NULL ) if (rtos->thread_details[j].extra_info_str != NULL) {
{
free(rtos->thread_details[j].extra_info_str); free(rtos->thread_details[j].extra_info_str);
rtos->thread_details[j].extra_info_str = NULL; rtos->thread_details[j].extra_info_str = NULL;
} }
@ -190,23 +168,25 @@ static int FreeRTOS_update_threads( struct rtos *rtos )
rtos->thread_details = NULL; rtos->thread_details = NULL;
} }
/* read the current thread */
// read the current thread retval = target_read_buffer(rtos->target,
retval = target_read_buffer( rtos->target, rtos->symbols[FreeRTOS_VAL_pxCurrentTCB].address, param->pointer_width, (uint8_t *)&rtos->current_thread ); rtos->symbols[FreeRTOS_VAL_pxCurrentTCB].address,
if ( retval != ERROR_OK ) param->pointer_width,
{ (uint8_t *)&rtos->current_thread);
if (retval != ERROR_OK) {
LOG_OUTPUT("Error reading current thread in FreeRTOS thread list\r\n"); LOG_OUTPUT("Error reading current thread in FreeRTOS thread list\r\n");
return retval; return retval;
} }
if ( ( thread_list_size == 0 ) || ( rtos->current_thread == 0 ) ) if ((thread_list_size == 0) || (rtos->current_thread == 0)) {
{ /* Either : No RTOS threads - there is always at least the current execution though */
// Either : No RTOS threads - there is always at least the current execution though /* OR : No current thread - all threads suspended - show the current execution
// OR : No current thread - all threads suspended - show the current execution of idling * of idling */
char tmp_str[] = "Current Execution"; char tmp_str[] = "Current Execution";
thread_list_size++; thread_list_size++;
tasks_found++; tasks_found++;
rtos->thread_details = (struct thread_detail*) malloc( sizeof( struct thread_detail ) * thread_list_size ); rtos->thread_details = (struct thread_detail *) malloc(
sizeof(struct thread_detail) * thread_list_size);
rtos->thread_details->threadid = 1; rtos->thread_details->threadid = 1;
rtos->thread_details->exists = true; rtos->thread_details->exists = true;
rtos->thread_details->display_str = NULL; rtos->thread_details->display_str = NULL;
@ -214,33 +194,33 @@ static int FreeRTOS_update_threads( struct rtos *rtos )
rtos->thread_details->thread_name_str = (char *) malloc(sizeof(tmp_str)); rtos->thread_details->thread_name_str = (char *) malloc(sizeof(tmp_str));
strcpy(rtos->thread_details->thread_name_str, tmp_str); strcpy(rtos->thread_details->thread_name_str, tmp_str);
if (thread_list_size == 1) {
if ( thread_list_size == 1 )
{
rtos->thread_count = 1; rtos->thread_count = 1;
return ERROR_OK; return ERROR_OK;
} }
} } else {
else /* create space for new thread details */
{ rtos->thread_details = (struct thread_detail *) malloc(
// create space for new thread details sizeof(struct thread_detail) * thread_list_size);
rtos->thread_details = (struct thread_detail*) malloc( sizeof( struct thread_detail ) * thread_list_size );
} }
/* Find out how many lists are needed to be read from pxReadyTasksLists, */
// Find out how many lists are needed to be read from pxReadyTasksLists,
int64_t max_used_priority = 0; int64_t max_used_priority = 0;
retval = target_read_buffer( rtos->target, rtos->symbols[FreeRTOS_VAL_uxTopUsedPriority].address, param->pointer_width, (uint8_t *)&max_used_priority ); retval = target_read_buffer(rtos->target,
rtos->symbols[FreeRTOS_VAL_uxTopUsedPriority].address,
param->pointer_width,
(uint8_t *)&max_used_priority);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
symbol_address_t* list_of_lists = (symbol_address_t *)malloc( sizeof( symbol_address_t ) * ( max_used_priority+1 + 5 ) ); symbol_address_t *list_of_lists =
(symbol_address_t *)malloc(sizeof(symbol_address_t) *
(max_used_priority+1 + 5));
int num_lists; int num_lists;
for (num_lists = 0; num_lists <= max_used_priority; num_lists++) for (num_lists = 0; num_lists <= max_used_priority; num_lists++)
{ list_of_lists[num_lists] = rtos->symbols[FreeRTOS_VAL_pxReadyTasksLists].address +
list_of_lists[num_lists] = rtos->symbols[FreeRTOS_VAL_pxReadyTasksLists].address + num_lists * param->list_width; num_lists * param->list_width;
}
list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xDelayedTaskList1].address; list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xDelayedTaskList1].address;
list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xDelayedTaskList2].address; list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xDelayedTaskList2].address;
@ -248,101 +228,102 @@ static int FreeRTOS_update_threads( struct rtos *rtos )
list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xSuspendedTaskList].address; list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xSuspendedTaskList].address;
list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xTasksWaitingTermination].address; list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xTasksWaitingTermination].address;
for (i = 0; i < num_lists; i++) {
for( i = 0; i < num_lists; i++ )
{
if (list_of_lists[i] == 0) if (list_of_lists[i] == 0)
{
continue; continue;
}
// Read the number of threads in this list /* Read the number of threads in this list */
int64_t list_thread_count = 0; int64_t list_thread_count = 0;
retval = target_read_buffer( rtos->target, list_of_lists[i], param->thread_count_width, (uint8_t *)&list_thread_count); retval = target_read_buffer(rtos->target,
if ( retval != ERROR_OK ) list_of_lists[i],
{ param->thread_count_width,
(uint8_t *)&list_thread_count);
if (retval != ERROR_OK) {
LOG_OUTPUT("Error reading number of threads in FreeRTOS thread list\r\n"); LOG_OUTPUT("Error reading number of threads in FreeRTOS thread list\r\n");
return retval; return retval;
} }
if (list_thread_count == 0) if (list_thread_count == 0)
{
continue; continue;
}
// Read the location of first list item /* Read the location of first list item */
uint64_t prev_list_elem_ptr = -1; uint64_t prev_list_elem_ptr = -1;
uint64_t list_elem_ptr = 0; uint64_t list_elem_ptr = 0;
retval = target_read_buffer( rtos->target, list_of_lists[i] + param->list_next_offset, param->pointer_width, (uint8_t *)&list_elem_ptr); retval = target_read_buffer(rtos->target,
if ( retval != ERROR_OK ) list_of_lists[i] + param->list_next_offset,
{ param->pointer_width,
LOG_OUTPUT("Error reading first thread item location in FreeRTOS thread list\r\n"); (uint8_t *)&list_elem_ptr);
if (retval != ERROR_OK) {
LOG_OUTPUT(
"Error reading first thread item location in FreeRTOS thread list\r\n");
return retval; return retval;
} }
while ((list_thread_count > 0) && (list_elem_ptr != 0) &&
while ( (list_thread_count > 0) && ( list_elem_ptr != 0) && ( list_elem_ptr != prev_list_elem_ptr ) && ( tasks_found < thread_list_size ) ) (list_elem_ptr != prev_list_elem_ptr) &&
{ (tasks_found < thread_list_size)) {
// Get the location of the thread structure. /* Get the location of the thread structure. */
rtos->thread_details[tasks_found].threadid = 0; rtos->thread_details[tasks_found].threadid = 0;
retval = target_read_buffer( rtos->target, list_elem_ptr + param->list_elem_content_offset, param->pointer_width, (uint8_t *)&(rtos->thread_details[tasks_found].threadid)); retval = target_read_buffer(rtos->target,
if ( retval != ERROR_OK ) list_elem_ptr + param->list_elem_content_offset,
{ param->pointer_width,
LOG_OUTPUT("Error reading thread list item object in FreeRTOS thread list\r\n"); (uint8_t *)&(rtos->thread_details[tasks_found].threadid));
if (retval != ERROR_OK) {
LOG_OUTPUT(
"Error reading thread list item object in FreeRTOS thread list\r\n");
return retval; return retval;
} }
/* get thread name */
// get thread name
#define FREERTOS_THREAD_NAME_STR_SIZE (200) #define FREERTOS_THREAD_NAME_STR_SIZE (200)
char tmp_str[FREERTOS_THREAD_NAME_STR_SIZE]; char tmp_str[FREERTOS_THREAD_NAME_STR_SIZE];
// Read the thread name /* Read the thread name */
retval = target_read_buffer( rtos->target, rtos->thread_details[tasks_found].threadid + param->thread_name_offset, FREERTOS_THREAD_NAME_STR_SIZE, (uint8_t *)&tmp_str); retval = target_read_buffer(rtos->target,
if ( retval != ERROR_OK ) rtos->thread_details[tasks_found].threadid + param->thread_name_offset,
{ FREERTOS_THREAD_NAME_STR_SIZE,
LOG_OUTPUT("Error reading first thread item location in FreeRTOS thread list\r\n"); (uint8_t *)&tmp_str);
if (retval != ERROR_OK) {
LOG_OUTPUT(
"Error reading first thread item location in FreeRTOS thread list\r\n");
return retval; return retval;
} }
tmp_str[FREERTOS_THREAD_NAME_STR_SIZE-1] = '\x00'; tmp_str[FREERTOS_THREAD_NAME_STR_SIZE-1] = '\x00';
if (tmp_str[0] == '\x00') if (tmp_str[0] == '\x00')
{
strcpy(tmp_str, "No Name"); strcpy(tmp_str, "No Name");
}
rtos->thread_details[tasks_found].thread_name_str = (char*)malloc( strlen(tmp_str)+1 ); rtos->thread_details[tasks_found].thread_name_str =
(char *)malloc(strlen(tmp_str)+1);
strcpy(rtos->thread_details[tasks_found].thread_name_str, tmp_str); strcpy(rtos->thread_details[tasks_found].thread_name_str, tmp_str);
rtos->thread_details[tasks_found].display_str = NULL; rtos->thread_details[tasks_found].display_str = NULL;
rtos->thread_details[tasks_found].exists = true; rtos->thread_details[tasks_found].exists = true;
if ( rtos->thread_details[tasks_found].threadid == rtos->current_thread ) if (rtos->thread_details[tasks_found].threadid == rtos->current_thread) {
{
char running_str[] = "Running"; char running_str[] = "Running";
rtos->thread_details[tasks_found].extra_info_str = (char*) malloc( sizeof(running_str) ); rtos->thread_details[tasks_found].extra_info_str = (char *) malloc(
strcpy( rtos->thread_details[tasks_found].extra_info_str, running_str ); sizeof(running_str));
} strcpy(rtos->thread_details[tasks_found].extra_info_str,
else running_str);
{ } else
rtos->thread_details[tasks_found].extra_info_str = NULL; rtos->thread_details[tasks_found].extra_info_str = NULL;
}
tasks_found++; tasks_found++;
list_thread_count--; list_thread_count--;
prev_list_elem_ptr = list_elem_ptr; prev_list_elem_ptr = list_elem_ptr;
list_elem_ptr = 0; list_elem_ptr = 0;
retval = target_read_buffer( rtos->target, prev_list_elem_ptr + param->list_elem_next_offset, param->pointer_width, (uint8_t *)&list_elem_ptr); retval = target_read_buffer(rtos->target,
if ( retval != ERROR_OK ) prev_list_elem_ptr + param->list_elem_next_offset,
{ param->pointer_width,
LOG_OUTPUT("Error reading next thread item location in FreeRTOS thread list\r\n"); (uint8_t *)&list_elem_ptr);
if (retval != ERROR_OK) {
LOG_OUTPUT(
"Error reading next thread item location in FreeRTOS thread list\r\n");
return retval; return retval;
} }
} }
} }
free(list_of_lists); free(list_of_lists);
rtos->thread_count = tasks_found; rtos->thread_count = tasks_found;
@ -355,29 +336,24 @@ static int FreeRTOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, ch
const struct FreeRTOS_params *param; const struct FreeRTOS_params *param;
int64_t stack_ptr = 0; int64_t stack_ptr = 0;
*hex_reg_list = NULL; *hex_reg_list = NULL;
if (rtos == NULL) if (rtos == NULL)
{
return -1; return -1;
}
if (thread_id == 0) if (thread_id == 0)
{
return -2; return -2;
}
if (rtos->rtos_specific_params == NULL) if (rtos->rtos_specific_params == NULL)
{
return -1; return -1;
}
param = (const struct FreeRTOS_params *) rtos->rtos_specific_params; param = (const struct FreeRTOS_params *) rtos->rtos_specific_params;
// Read the stack pointer /* Read the stack pointer */
retval = target_read_buffer( rtos->target, thread_id + param->thread_stack_offset, param->pointer_width, (uint8_t*)&stack_ptr); retval = target_read_buffer(rtos->target,
if ( retval != ERROR_OK ) thread_id + param->thread_stack_offset,
{ param->pointer_width,
(uint8_t *)&stack_ptr);
if (retval != ERROR_OK) {
LOG_OUTPUT("Error reading stack frame from FreeRTOS thread\r\n"); LOG_OUTPUT("Error reading stack frame from FreeRTOS thread\r\n");
return retval; return retval;
} }
@ -389,12 +365,11 @@ static int FreeRTOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, ch
static int FreeRTOS_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) static int FreeRTOS_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[])
{ {
unsigned int i; unsigned int i;
*symbol_list = (symbol_table_elem_t *) malloc( sizeof( symbol_table_elem_t ) * FREERTOS_NUM_SYMBOLS ); *symbol_list = (symbol_table_elem_t *) malloc(
sizeof(symbol_table_elem_t) * FREERTOS_NUM_SYMBOLS);
for (i = 0; i < FREERTOS_NUM_SYMBOLS; i++) for (i = 0; i < FREERTOS_NUM_SYMBOLS; i++)
{
(*symbol_list)[i].symbol_name = FreeRTOS_symbol_list[i]; (*symbol_list)[i].symbol_name = FreeRTOS_symbol_list[i];
}
return 0; return 0;
} }
@ -406,46 +381,38 @@ static int FreeRTOS_set_current_thread(struct rtos *rtos, threadid_t thread_id)
return 0; return 0;
} }
static int FreeRTOS_get_thread_ascii_info(struct rtos *rtos, threadid_t thread_id, char **info) static int FreeRTOS_get_thread_ascii_info(struct rtos *rtos, threadid_t thread_id, char **info)
{ {
int retval; int retval;
const struct FreeRTOS_params *param; const struct FreeRTOS_params *param;
if (rtos == NULL) if (rtos == NULL)
{
return -1; return -1;
}
if (thread_id == 0) if (thread_id == 0)
{
return -2; return -2;
}
if (rtos->rtos_specific_params == NULL) if (rtos->rtos_specific_params == NULL)
{
return -3; return -3;
}
param = (const struct FreeRTOS_params *) rtos->rtos_specific_params; param = (const struct FreeRTOS_params *) rtos->rtos_specific_params;
#define FREERTOS_THREAD_NAME_STR_SIZE (200) #define FREERTOS_THREAD_NAME_STR_SIZE (200)
char tmp_str[FREERTOS_THREAD_NAME_STR_SIZE]; char tmp_str[FREERTOS_THREAD_NAME_STR_SIZE];
// Read the thread name /* Read the thread name */
retval = target_read_buffer( rtos->target, thread_id + param->thread_name_offset, FREERTOS_THREAD_NAME_STR_SIZE, (uint8_t *)&tmp_str); retval = target_read_buffer(rtos->target,
if ( retval != ERROR_OK ) thread_id + param->thread_name_offset,
{ FREERTOS_THREAD_NAME_STR_SIZE,
(uint8_t *)&tmp_str);
if (retval != ERROR_OK) {
LOG_OUTPUT("Error reading first thread item location in FreeRTOS thread list\r\n"); LOG_OUTPUT("Error reading first thread item location in FreeRTOS thread list\r\n");
return retval; return retval;
} }
tmp_str[FREERTOS_THREAD_NAME_STR_SIZE-1] = '\x00'; tmp_str[FREERTOS_THREAD_NAME_STR_SIZE-1] = '\x00';
if (tmp_str[0] == '\x00') if (tmp_str[0] == '\x00')
{
strcpy(tmp_str, "No Name"); strcpy(tmp_str, "No Name");
}
*info = (char *)malloc(strlen(tmp_str)+1); *info = (char *)malloc(strlen(tmp_str)+1);
strcpy(*info, tmp_str); strcpy(*info, tmp_str);
@ -457,25 +424,21 @@ static int FreeRTOS_get_thread_ascii_info( struct rtos* rtos, threadid_t thr
static int FreeRTOS_detect_rtos(struct target *target) static int FreeRTOS_detect_rtos(struct target *target)
{ {
if ((target->rtos->symbols != NULL) && if ((target->rtos->symbols != NULL) &&
( target->rtos->symbols[FreeRTOS_VAL_pxReadyTasksLists].address != 0 ) ) (target->rtos->symbols[FreeRTOS_VAL_pxReadyTasksLists].address != 0)) {
{ /* looks like FreeRTOS */
// looks like FreeRTOS
return 1; return 1;
} }
return 0; return 0;
return 0;
} }
static int FreeRTOS_create(struct target *target) static int FreeRTOS_create(struct target *target)
{ {
int i = 0; int i = 0;
while ( ( i < FREERTOS_NUM_PARAMS ) && ( 0 != strcmp( FreeRTOS_params_list[i].target_name, target->type->name ) ) ) while ((i < FREERTOS_NUM_PARAMS) &&
{ (0 != strcmp(FreeRTOS_params_list[i].target_name, target->type->name))) {
i++; i++;
} }
if ( i >= FREERTOS_NUM_PARAMS ) if (i >= FREERTOS_NUM_PARAMS) {
{
LOG_OUTPUT("Could not find target in FreeRTOS compatibility list\r\n"); LOG_OUTPUT("Could not find target in FreeRTOS compatibility list\r\n");
return -1; return -1;
} }
@ -483,4 +446,3 @@ static int FreeRTOS_create( struct target* target )
target->rtos->rtos_specific_params = (void *) &FreeRTOS_params_list[i]; target->rtos->rtos_specific_params = (void *) &FreeRTOS_params_list[i];
return 0; return 0;
} }

View File

@ -30,24 +30,18 @@
#include "helper/log.h" #include "helper/log.h"
#include "rtos_standard_stackings.h" #include "rtos_standard_stackings.h"
static int ThreadX_detect_rtos(struct target *target); static int ThreadX_detect_rtos(struct target *target);
static int ThreadX_create(struct target *target); static int ThreadX_create(struct target *target);
static int ThreadX_update_threads(struct rtos *rtos); static int ThreadX_update_threads(struct rtos *rtos);
static int ThreadX_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list); static int ThreadX_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list);
static int ThreadX_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]); static int ThreadX_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]);
struct ThreadX_thread_state {
struct ThreadX_thread_state
{
int value; int value;
char *desc; char *desc;
}; };
struct ThreadX_thread_state ThreadX_thread_states[] = {
struct ThreadX_thread_state ThreadX_thread_states[] =
{
{ 0, "Ready" }, { 0, "Ready" },
{ 1, "Completed" }, { 1, "Completed" },
{ 2, "Terminated" }, { 2, "Terminated" },
@ -64,12 +58,9 @@ struct ThreadX_thread_state ThreadX_thread_states[] =
{ 13, "Waiting - Mutex" }, { 13, "Waiting - Mutex" },
}; };
#define THREADX_NUM_STATES (sizeof(ThreadX_thread_states)/sizeof(struct ThreadX_thread_state)) #define THREADX_NUM_STATES (sizeof(ThreadX_thread_states)/sizeof(struct ThreadX_thread_state))
struct ThreadX_params {
struct ThreadX_params
{
char *target_name; char *target_name;
unsigned char pointer_width; unsigned char pointer_width;
unsigned char thread_stack_offset; unsigned char thread_stack_offset;
@ -79,43 +70,36 @@ struct ThreadX_params
const struct rtos_register_stacking *stacking_info; const struct rtos_register_stacking *stacking_info;
}; };
const struct ThreadX_params ThreadX_params_list[] = const struct ThreadX_params ThreadX_params_list[] = {
{ {
{ "cortex_m3", // target_name "cortex_m3", /* target_name */
4, // pointer_width; 4, /* pointer_width; */
8, // thread_stack_offset; 8, /* thread_stack_offset; */
40, // thread_name_offset; 40, /* thread_name_offset; */
48, // thread_state_offset; 48, /* thread_state_offset; */
136, // thread_next_offset 136, /* thread_next_offset */
&rtos_standard_Cortex_M3_stacking, // stacking_info &rtos_standard_Cortex_M3_stacking, /* stacking_info */
} }
}; };
#define THREADX_NUM_PARAMS ((int)(sizeof(ThreadX_params_list)/sizeof(struct ThreadX_params))) #define THREADX_NUM_PARAMS ((int)(sizeof(ThreadX_params_list)/sizeof(struct ThreadX_params)))
enum ThreadX_symbol_values enum ThreadX_symbol_values {
{
ThreadX_VAL_tx_thread_current_ptr = 0, ThreadX_VAL_tx_thread_current_ptr = 0,
ThreadX_VAL_tx_thread_created_ptr = 1, ThreadX_VAL_tx_thread_created_ptr = 1,
ThreadX_VAL_tx_thread_created_count = 2, ThreadX_VAL_tx_thread_created_count = 2,
}; };
static char* ThreadX_symbol_list[] = static char *ThreadX_symbol_list[] = {
{
"_tx_thread_current_ptr", "_tx_thread_current_ptr",
"_tx_thread_created_ptr", "_tx_thread_created_ptr",
"_tx_thread_created_count", "_tx_thread_created_count",
NULL NULL
}; };
#define THREADX_NUM_SYMBOLS (sizeof(ThreadX_symbol_list)/sizeof(char *)) #define THREADX_NUM_SYMBOLS (sizeof(ThreadX_symbol_list)/sizeof(char *))
const struct rtos_type ThreadX_rtos = {
const struct rtos_type ThreadX_rtos =
{
.name = "ThreadX", .name = "ThreadX",
.detect_rtos = ThreadX_detect_rtos, .detect_rtos = ThreadX_detect_rtos,
@ -134,61 +118,47 @@ static int ThreadX_update_threads( struct rtos* rtos)
const struct ThreadX_params *param; const struct ThreadX_params *param;
if (rtos == NULL) if (rtos == NULL)
{
return -1; return -1;
}
if (rtos->rtos_specific_params == NULL) if (rtos->rtos_specific_params == NULL)
{
return -3; return -3;
}
param = (const struct ThreadX_params *) rtos->rtos_specific_params; param = (const struct ThreadX_params *) rtos->rtos_specific_params;
if ( rtos->symbols == NULL ) if (rtos->symbols == NULL) {
{
LOG_OUTPUT("No symbols for ThreadX\r\n"); LOG_OUTPUT("No symbols for ThreadX\r\n");
return -4; return -4;
} }
if ( rtos->symbols[ThreadX_VAL_tx_thread_created_count].address == 0 ) if (rtos->symbols[ThreadX_VAL_tx_thread_created_count].address == 0) {
{
LOG_OUTPUT("Don't have the number of threads in ThreadX \r\n"); LOG_OUTPUT("Don't have the number of threads in ThreadX \r\n");
return -2; return -2;
} }
/* read the number of threads */
retval = target_read_buffer(rtos->target,
rtos->symbols[ThreadX_VAL_tx_thread_created_count].address,
4,
(uint8_t *)&thread_list_size);
if (retval != ERROR_OK) {
// read the number of threads
retval = target_read_buffer( rtos->target, rtos->symbols[ThreadX_VAL_tx_thread_created_count].address, 4, (uint8_t *)&thread_list_size);
if ( retval != ERROR_OK )
{
LOG_OUTPUT("Could not read ThreadX thread count from target\r\n"); LOG_OUTPUT("Could not read ThreadX thread count from target\r\n");
return retval; return retval;
} }
/* wipe out previous thread details if any */
// wipe out previous thread details if any if (rtos->thread_details != NULL) {
if ( rtos->thread_details != NULL )
{
int j; int j;
for( j = 0; j < rtos->thread_count; j++ ) for (j = 0; j < rtos->thread_count; j++) {
{ if (rtos->thread_details[j].display_str != NULL) {
if ( rtos->thread_details[j].display_str != NULL )
{
free(rtos->thread_details[j].display_str); free(rtos->thread_details[j].display_str);
rtos->thread_details[j].display_str = NULL; rtos->thread_details[j].display_str = NULL;
} }
if ( rtos->thread_details[j].thread_name_str != NULL ) if (rtos->thread_details[j].thread_name_str != NULL) {
{
free(rtos->thread_details[j].thread_name_str); free(rtos->thread_details[j].thread_name_str);
rtos->thread_details[j].thread_name_str = NULL; rtos->thread_details[j].thread_name_str = NULL;
} }
if ( rtos->thread_details[j].extra_info_str != NULL ) if (rtos->thread_details[j].extra_info_str != NULL) {
{
free(rtos->thread_details[j].extra_info_str); free(rtos->thread_details[j].extra_info_str);
rtos->thread_details[j].extra_info_str = NULL; rtos->thread_details[j].extra_info_str = NULL;
} }
@ -197,24 +167,26 @@ static int ThreadX_update_threads( struct rtos* rtos)
rtos->thread_details = NULL; rtos->thread_details = NULL;
} }
/* read the current thread id */
retval = target_read_buffer(rtos->target,
rtos->symbols[ThreadX_VAL_tx_thread_current_ptr].address,
4,
(uint8_t *)&rtos->current_thread);
// read the current thread id if (retval != ERROR_OK) {
retval = target_read_buffer( rtos->target, rtos->symbols[ThreadX_VAL_tx_thread_current_ptr].address, 4, (uint8_t *)&rtos->current_thread);
if ( retval != ERROR_OK )
{
LOG_OUTPUT("Could not read ThreadX current thread from target\r\n"); LOG_OUTPUT("Could not read ThreadX current thread from target\r\n");
return retval; return retval;
} }
if ( ( thread_list_size == 0 ) || ( rtos->current_thread == 0 ) ) if ((thread_list_size == 0) || (rtos->current_thread == 0)) {
{ /* Either : No RTOS threads - there is always at least the current execution though */
// Either : No RTOS threads - there is always at least the current execution though /* OR : No current thread - all threads suspended - show the current execution
// OR : No current thread - all threads suspended - show the current execution of idling * of idling */
char tmp_str[] = "Current Execution"; char tmp_str[] = "Current Execution";
thread_list_size++; thread_list_size++;
tasks_found++; tasks_found++;
rtos->thread_details = (struct thread_detail*) malloc( sizeof( struct thread_detail ) * thread_list_size ); rtos->thread_details = (struct thread_detail *) malloc(
sizeof(struct thread_detail) * thread_list_size);
rtos->thread_details->threadid = 1; rtos->thread_details->threadid = 1;
rtos->thread_details->exists = true; rtos->thread_details->exists = true;
rtos->thread_details->display_str = NULL; rtos->thread_details->display_str = NULL;
@ -222,120 +194,111 @@ static int ThreadX_update_threads( struct rtos* rtos)
rtos->thread_details->thread_name_str = (char *) malloc(sizeof(tmp_str)); rtos->thread_details->thread_name_str = (char *) malloc(sizeof(tmp_str));
strcpy(rtos->thread_details->thread_name_str, tmp_str); strcpy(rtos->thread_details->thread_name_str, tmp_str);
if (thread_list_size == 0) {
if ( thread_list_size == 0 )
{
rtos->thread_count = 1; rtos->thread_count = 1;
return ERROR_OK; return ERROR_OK;
} }
} } else {
else /* create space for new thread details */
{ rtos->thread_details = (struct thread_detail *) malloc(
// create space for new thread details sizeof(struct thread_detail) * thread_list_size);
rtos->thread_details = (struct thread_detail*) malloc( sizeof( struct thread_detail ) * thread_list_size );
} }
/* Read the pointer to the first thread */
// Read the pointer to the first thread
int64_t thread_ptr = 0; int64_t thread_ptr = 0;
retval = target_read_buffer( rtos->target, rtos->symbols[ThreadX_VAL_tx_thread_created_ptr].address, param->pointer_width, (uint8_t *)&thread_ptr); retval = target_read_buffer(rtos->target,
if ( retval != ERROR_OK ) rtos->symbols[ThreadX_VAL_tx_thread_created_ptr].address,
{ param->pointer_width,
(uint8_t *)&thread_ptr);
if (retval != ERROR_OK) {
LOG_OUTPUT("Could not read ThreadX thread location from target\r\n"); LOG_OUTPUT("Could not read ThreadX thread location from target\r\n");
return retval; return retval;
} }
/* loop over all threads */
// loop over all threads
int64_t prev_thread_ptr = 0; int64_t prev_thread_ptr = 0;
while ( ( thread_ptr != prev_thread_ptr ) && ( tasks_found < thread_list_size ) ) while ((thread_ptr != prev_thread_ptr) && (tasks_found < thread_list_size)) {
{
#define THREADX_THREAD_NAME_STR_SIZE (200) #define THREADX_THREAD_NAME_STR_SIZE (200)
char tmp_str[THREADX_THREAD_NAME_STR_SIZE]; char tmp_str[THREADX_THREAD_NAME_STR_SIZE];
unsigned int i = 0; unsigned int i = 0;
int64_t name_ptr = 0; int64_t name_ptr = 0;
// Save the thread pointer /* Save the thread pointer */
rtos->thread_details[tasks_found].threadid = thread_ptr; rtos->thread_details[tasks_found].threadid = thread_ptr;
/* read the name pointer */
// read the name pointer retval = target_read_buffer(rtos->target,
retval = target_read_buffer( rtos->target, thread_ptr + param->thread_name_offset, param->pointer_width, (uint8_t *)&name_ptr); thread_ptr + param->thread_name_offset,
if ( retval != ERROR_OK ) param->pointer_width,
{ (uint8_t *)&name_ptr);
if (retval != ERROR_OK) {
LOG_OUTPUT("Could not read ThreadX thread name pointer from target\r\n"); LOG_OUTPUT("Could not read ThreadX thread name pointer from target\r\n");
return retval; return retval;
} }
// Read the thread name /* Read the thread name */
retval = target_read_buffer( rtos->target, name_ptr, THREADX_THREAD_NAME_STR_SIZE, (uint8_t *)&tmp_str); retval =
if ( retval != ERROR_OK ) target_read_buffer(rtos->target,
{ name_ptr,
THREADX_THREAD_NAME_STR_SIZE,
(uint8_t *)&tmp_str);
if (retval != ERROR_OK) {
LOG_OUTPUT("Error reading thread name from ThreadX target\r\n"); LOG_OUTPUT("Error reading thread name from ThreadX target\r\n");
return retval; return retval;
} }
tmp_str[THREADX_THREAD_NAME_STR_SIZE-1] = '\x00'; tmp_str[THREADX_THREAD_NAME_STR_SIZE-1] = '\x00';
if (tmp_str[0] == '\x00') if (tmp_str[0] == '\x00')
{
strcpy(tmp_str, "No Name"); strcpy(tmp_str, "No Name");
}
rtos->thread_details[tasks_found].thread_name_str =
rtos->thread_details[tasks_found].thread_name_str = (char*)malloc( strlen(tmp_str)+1 ); (char *)malloc(strlen(tmp_str)+1);
strcpy(rtos->thread_details[tasks_found].thread_name_str, tmp_str); strcpy(rtos->thread_details[tasks_found].thread_name_str, tmp_str);
/* Read the thread status */
// Read the thread status
int64_t thread_status = 0; int64_t thread_status = 0;
retval = target_read_buffer( rtos->target, thread_ptr + param->thread_state_offset, 4, (uint8_t *)&thread_status); retval = target_read_buffer(rtos->target,
if ( retval != ERROR_OK ) thread_ptr + param->thread_state_offset,
{ 4,
(uint8_t *)&thread_status);
if (retval != ERROR_OK) {
LOG_OUTPUT("Error reading thread state from ThreadX target\r\n"); LOG_OUTPUT("Error reading thread state from ThreadX target\r\n");
return retval; return retval;
} }
for( i = 0; (i < THREADX_NUM_STATES) && (ThreadX_thread_states[i].value!=thread_status); i++ ) for (i = 0; (i < THREADX_NUM_STATES) &&
{ (ThreadX_thread_states[i].value != thread_status); i++) {
/* empty */
} }
char *state_desc; char *state_desc;
if (i < THREADX_NUM_STATES) if (i < THREADX_NUM_STATES)
{
state_desc = ThreadX_thread_states[i].desc; state_desc = ThreadX_thread_states[i].desc;
}
else else
{
state_desc = "Unknown state"; state_desc = "Unknown state";
}
rtos->thread_details[tasks_found].extra_info_str = (char*)malloc( strlen(state_desc)+1 ); rtos->thread_details[tasks_found].extra_info_str = (char *)malloc(strlen(
state_desc)+1);
strcpy(rtos->thread_details[tasks_found].extra_info_str, state_desc); strcpy(rtos->thread_details[tasks_found].extra_info_str, state_desc);
rtos->thread_details[tasks_found].exists = true; rtos->thread_details[tasks_found].exists = true;
rtos->thread_details[tasks_found].display_str = NULL; rtos->thread_details[tasks_found].display_str = NULL;
tasks_found++; tasks_found++;
prev_thread_ptr = thread_ptr; prev_thread_ptr = thread_ptr;
// Get the location of the next thread structure. /* Get the location of the next thread structure. */
thread_ptr = 0; thread_ptr = 0;
retval = target_read_buffer( rtos->target, prev_thread_ptr + param->thread_next_offset, param->pointer_width, (uint8_t *) &thread_ptr ); retval = target_read_buffer(rtos->target,
if ( retval != ERROR_OK ) prev_thread_ptr + param->thread_next_offset,
{ param->pointer_width,
(uint8_t *) &thread_ptr);
if (retval != ERROR_OK) {
LOG_OUTPUT("Error reading next thread pointer in ThreadX thread list\r\n"); LOG_OUTPUT("Error reading next thread pointer in ThreadX thread list\r\n");
return retval; return retval;
} }
} }
rtos->thread_count = tasks_found; rtos->thread_count = tasks_found;
@ -345,34 +308,29 @@ static int ThreadX_update_threads( struct rtos* rtos)
static int ThreadX_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list) static int ThreadX_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list)
{ {
int retval; int retval;
const struct ThreadX_params *param; const struct ThreadX_params *param;
*hex_reg_list = NULL; *hex_reg_list = NULL;
if (rtos == NULL) if (rtos == NULL)
{
return -1; return -1;
}
if (thread_id == 0) if (thread_id == 0)
{
return -2; return -2;
}
if (rtos->rtos_specific_params == NULL) if (rtos->rtos_specific_params == NULL)
{
return -3; return -3;
}
param = (const struct ThreadX_params *) rtos->rtos_specific_params; param = (const struct ThreadX_params *) rtos->rtos_specific_params;
// Read the stack pointer /* Read the stack pointer */
int64_t stack_ptr = 0; int64_t stack_ptr = 0;
retval = target_read_buffer( rtos->target, thread_id + param->thread_stack_offset, param->pointer_width, (uint8_t*)&stack_ptr); retval = target_read_buffer(rtos->target,
if ( retval != ERROR_OK ) thread_id + param->thread_stack_offset,
{ param->pointer_width,
(uint8_t *)&stack_ptr);
if (retval != ERROR_OK) {
LOG_OUTPUT("Error reading stack frame from ThreadX thread\r\n"); LOG_OUTPUT("Error reading stack frame from ThreadX thread\r\n");
return retval; return retval;
} }
@ -380,17 +338,14 @@ static int ThreadX_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, cha
return rtos_generic_stack_read(rtos->target, param->stacking_info, stack_ptr, hex_reg_list); return rtos_generic_stack_read(rtos->target, param->stacking_info, stack_ptr, hex_reg_list);
} }
static int ThreadX_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) static int ThreadX_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[])
{ {
unsigned int i; unsigned int i;
*symbol_list = (symbol_table_elem_t *) malloc( sizeof( symbol_table_elem_t ) * THREADX_NUM_SYMBOLS ); *symbol_list = (symbol_table_elem_t *) malloc(
sizeof(symbol_table_elem_t) * THREADX_NUM_SYMBOLS);
for (i = 0; i < THREADX_NUM_SYMBOLS; i++) for (i = 0; i < THREADX_NUM_SYMBOLS; i++)
{
(*symbol_list)[i].symbol_name = ThreadX_symbol_list[i]; (*symbol_list)[i].symbol_name = ThreadX_symbol_list[i];
}
return 0; return 0;
} }
@ -398,16 +353,13 @@ static int ThreadX_get_symbol_list_to_lookup(symbol_table_elem_t * symbol_list[]
static int ThreadX_detect_rtos(struct target *target) static int ThreadX_detect_rtos(struct target *target)
{ {
if ((target->rtos->symbols != NULL) && if ((target->rtos->symbols != NULL) &&
( target->rtos->symbols[ThreadX_VAL_tx_thread_created_ptr].address != 0 ) ) (target->rtos->symbols[ThreadX_VAL_tx_thread_created_ptr].address != 0)) {
{ /* looks like ThreadX */
// looks like ThreadX
return 1; return 1;
} }
return 0; return 0;
} }
#if 0 #if 0
static int ThreadX_set_current_thread(struct rtos *rtos, threadid_t thread_id) static int ThreadX_set_current_thread(struct rtos *rtos, threadid_t thread_id)
@ -415,9 +367,9 @@ static int ThreadX_set_current_thread(struct rtos *rtos, threadid_t thread_id)
return 0; return 0;
} }
static int ThreadX_get_thread_detail(struct rtos *rtos,
threadid_t thread_id,
static int ThreadX_get_thread_detail( struct rtos* rtos, threadid_t thread_id, struct thread_detail* detail ) struct thread_detail *detail)
{ {
unsigned int i = 0; unsigned int i = 0;
int retval; int retval;
@ -428,24 +380,17 @@ static int ThreadX_get_thread_detail( struct rtos* rtos, threadid_t thread_i
const struct ThreadX_params *param; const struct ThreadX_params *param;
if (rtos == NULL) if (rtos == NULL)
{
return -1; return -1;
}
if (thread_id == 0) if (thread_id == 0)
{
return -2; return -2;
}
if (rtos->rtos_specific_params == NULL) if (rtos->rtos_specific_params == NULL)
{
return -3; return -3;
}
param = (const struct ThreadX_params *) rtos->rtos_specific_params; param = (const struct ThreadX_params *) rtos->rtos_specific_params;
if ( rtos->symbols == NULL ) if (rtos->symbols == NULL) {
{
LOG_OUTPUT("No symbols for ThreadX\r\n"); LOG_OUTPUT("No symbols for ThreadX\r\n");
return -3; return -3;
} }
@ -453,54 +398,54 @@ static int ThreadX_get_thread_detail( struct rtos* rtos, threadid_t thread_i
detail->threadid = thread_id; detail->threadid = thread_id;
int64_t name_ptr = 0; int64_t name_ptr = 0;
// read the name pointer /* read the name pointer */
retval = target_read_buffer( rtos->target, thread_id + param->thread_name_offset, param->pointer_width, (uint8_t *)&name_ptr); retval = target_read_buffer(rtos->target,
if ( retval != ERROR_OK ) thread_id + param->thread_name_offset,
{ param->pointer_width,
(uint8_t *)&name_ptr);
if (retval != ERROR_OK) {
LOG_OUTPUT("Could not read ThreadX thread name pointer from target\r\n"); LOG_OUTPUT("Could not read ThreadX thread name pointer from target\r\n");
return retval; return retval;
} }
// Read the thread name /* Read the thread name */
retval = target_read_buffer( rtos->target, name_ptr, THREADX_THREAD_NAME_STR_SIZE, (uint8_t *)&tmp_str); retval = target_read_buffer(rtos->target,
if ( retval != ERROR_OK ) name_ptr,
{ THREADX_THREAD_NAME_STR_SIZE,
(uint8_t *)&tmp_str);
if (retval != ERROR_OK) {
LOG_OUTPUT("Error reading thread name from ThreadX target\r\n"); LOG_OUTPUT("Error reading thread name from ThreadX target\r\n");
return retval; return retval;
} }
tmp_str[THREADX_THREAD_NAME_STR_SIZE-1] = '\x00'; tmp_str[THREADX_THREAD_NAME_STR_SIZE-1] = '\x00';
if (tmp_str[0] == '\x00') if (tmp_str[0] == '\x00')
{
strcpy(tmp_str, "No Name"); strcpy(tmp_str, "No Name");
}
detail->thread_name_str = (char *)malloc(strlen(tmp_str)+1); detail->thread_name_str = (char *)malloc(strlen(tmp_str)+1);
/* Read the thread status */
// Read the thread status
int64_t thread_status = 0; int64_t thread_status = 0;
retval = target_read_buffer( rtos->target, thread_id + param->thread_state_offset, 4, (uint8_t *)&thread_status); retval =
if ( retval != ERROR_OK ) target_read_buffer(rtos->target,
{ thread_id + param->thread_state_offset,
4,
(uint8_t *)&thread_status);
if (retval != ERROR_OK) {
LOG_OUTPUT("Error reading thread state from ThreadX target\r\n"); LOG_OUTPUT("Error reading thread state from ThreadX target\r\n");
return retval; return retval;
} }
for( i = 0; (i < THREADX_NUM_STATES) && (ThreadX_thread_states[i].value!=thread_status); i++ ) for (i = 0; (i < THREADX_NUM_STATES) &&
{ (ThreadX_thread_states[i].value != thread_status); i++) {
/* empty */
} }
char *state_desc; char *state_desc;
if (i < THREADX_NUM_STATES) if (i < THREADX_NUM_STATES)
{
state_desc = ThreadX_thread_states[i].desc; state_desc = ThreadX_thread_states[i].desc;
}
else else
{
state_desc = "Unknown state"; state_desc = "Unknown state";
}
detail->extra_info_str = (char *)malloc(strlen(state_desc)+1); detail->extra_info_str = (char *)malloc(strlen(state_desc)+1);
@ -508,9 +453,6 @@ static int ThreadX_get_thread_detail( struct rtos* rtos, threadid_t thread_i
detail->display_str = NULL; detail->display_str = NULL;
return 0; return 0;
} }
@ -519,12 +461,11 @@ static int ThreadX_get_thread_detail( struct rtos* rtos, threadid_t thread_i
static int ThreadX_create(struct target *target) static int ThreadX_create(struct target *target)
{ {
int i = 0; int i = 0;
while ( ( i < THREADX_NUM_PARAMS ) && ( 0 != strcmp( ThreadX_params_list[i].target_name, target->type->name ) ) ) while ((i < THREADX_NUM_PARAMS) &&
{ (0 != strcmp(ThreadX_params_list[i].target_name, target->type->name))) {
i++; i++;
} }
if ( i >= THREADX_NUM_PARAMS ) if (i >= THREADX_NUM_PARAMS) {
{
LOG_OUTPUT("Could not find target in ThreadX compatibility list\r\n"); LOG_OUTPUT("Could not find target in ThreadX compatibility list\r\n");
return -1; return -1;
} }

View File

@ -34,15 +34,12 @@ static int eCos_update_threads( struct rtos* rtos);
static int eCos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list); static int eCos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list);
static int eCos_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]); static int eCos_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]);
struct eCos_thread_state struct eCos_thread_state {
{
int value; int value;
char *desc; char *desc;
}; };
struct eCos_thread_state eCos_thread_states[] = {
struct eCos_thread_state eCos_thread_states[] =
{
{ 0, "Ready" }, { 0, "Ready" },
{ 1, "Sleeping" }, { 1, "Sleeping" },
{ 2, "Countsleep" }, { 2, "Countsleep" },
@ -53,8 +50,7 @@ struct eCos_thread_state eCos_thread_states[] =
#define ECOS_NUM_STATES (sizeof(eCos_thread_states)/sizeof(struct eCos_thread_state)) #define ECOS_NUM_STATES (sizeof(eCos_thread_states)/sizeof(struct eCos_thread_state))
struct eCos_params struct eCos_params {
{
char *target_name; char *target_name;
unsigned char pointer_width; unsigned char pointer_width;
unsigned char thread_stack_offset; unsigned char thread_stack_offset;
@ -65,42 +61,35 @@ struct eCos_params
const struct rtos_register_stacking *stacking_info; const struct rtos_register_stacking *stacking_info;
}; };
const struct eCos_params eCos_params_list[] = const struct eCos_params eCos_params_list[] = {
{ {
{ "cortex_m3", // target_name "cortex_m3", /* target_name */
4, // pointer_width; 4, /* pointer_width; */
0x0c, // thread_stack_offset; 0x0c, /* thread_stack_offset; */
0x9c, // thread_name_offset; 0x9c, /* thread_name_offset; */
0x3c, // thread_state_offset; 0x3c, /* thread_state_offset; */
0xa0, // thread_next_offset 0xa0, /* thread_next_offset */
0x4c, // thread_uniqueid_offset 0x4c, /* thread_uniqueid_offset */
&rtos_eCos_Cortex_M3_stacking // stacking_info &rtos_eCos_Cortex_M3_stacking /* stacking_info */
} }
}; };
#define ECOS_NUM_PARAMS ((int)(sizeof(eCos_params_list)/sizeof(struct eCos_params))) #define ECOS_NUM_PARAMS ((int)(sizeof(eCos_params_list)/sizeof(struct eCos_params)))
enum eCos_symbol_values enum eCos_symbol_values {
{
eCos_VAL_thread_list = 0, eCos_VAL_thread_list = 0,
eCos_VAL_current_thread_ptr = 1 eCos_VAL_current_thread_ptr = 1
}; };
static char* eCos_symbol_list[] = static char *eCos_symbol_list[] = {
{
"Cyg_Thread::thread_list", "Cyg_Thread::thread_list",
"Cyg_Scheduler_Base::current_thread", "Cyg_Scheduler_Base::current_thread",
NULL NULL
}; };
#define ECOS_NUM_SYMBOLS (sizeof(eCos_symbol_list)/sizeof(char *)) #define ECOS_NUM_SYMBOLS (sizeof(eCos_symbol_list)/sizeof(char *))
const struct rtos_type eCos_rtos = {
const struct rtos_type eCos_rtos =
{
.name = "eCos", .name = "eCos",
.detect_rtos = eCos_detect_rtos, .detect_rtos = eCos_detect_rtos,
@ -119,48 +108,36 @@ static int eCos_update_threads( struct rtos* rtos)
const struct eCos_params *param; const struct eCos_params *param;
if (rtos == NULL) if (rtos == NULL)
{
return -1; return -1;
}
if (rtos->rtos_specific_params == NULL) if (rtos->rtos_specific_params == NULL)
{
return -3; return -3;
}
param = (const struct eCos_params *) rtos->rtos_specific_params; param = (const struct eCos_params *) rtos->rtos_specific_params;
if ( rtos->symbols == NULL ) if (rtos->symbols == NULL) {
{
LOG_OUTPUT("No symbols for eCos\r\n"); LOG_OUTPUT("No symbols for eCos\r\n");
return -4; return -4;
} }
if ( rtos->symbols[eCos_VAL_thread_list].address == 0 ) if (rtos->symbols[eCos_VAL_thread_list].address == 0) {
{
LOG_OUTPUT("Don't have the thread list head\r\n"); LOG_OUTPUT("Don't have the thread list head\r\n");
return -2; return -2;
} }
/* wipe out previous thread details if any */
// wipe out previous thread details if any if (rtos->thread_details != NULL) {
if ( rtos->thread_details != NULL )
{
int j; int j;
for( j = 0; j < rtos->thread_count; j++ ) for (j = 0; j < rtos->thread_count; j++) {
{ if (rtos->thread_details[j].display_str != NULL) {
if ( rtos->thread_details[j].display_str != NULL )
{
free(rtos->thread_details[j].display_str); free(rtos->thread_details[j].display_str);
rtos->thread_details[j].display_str = NULL; rtos->thread_details[j].display_str = NULL;
} }
if ( rtos->thread_details[j].thread_name_str != NULL ) if (rtos->thread_details[j].thread_name_str != NULL) {
{
free(rtos->thread_details[j].thread_name_str); free(rtos->thread_details[j].thread_name_str);
rtos->thread_details[j].thread_name_str = NULL; rtos->thread_details[j].thread_name_str = NULL;
} }
if ( rtos->thread_details[j].extra_info_str != NULL ) if (rtos->thread_details[j].extra_info_str != NULL) {
{
free(rtos->thread_details[j].extra_info_str); free(rtos->thread_details[j].extra_info_str);
rtos->thread_details[j].extra_info_str = NULL; rtos->thread_details[j].extra_info_str = NULL;
} }
@ -169,41 +146,51 @@ static int eCos_update_threads( struct rtos* rtos)
rtos->thread_details = NULL; rtos->thread_details = NULL;
} }
/* determine the number of current threads */
// determine the number of current threads
uint32_t thread_list_head = rtos->symbols[eCos_VAL_thread_list].address; uint32_t thread_list_head = rtos->symbols[eCos_VAL_thread_list].address;
uint32_t thread_index; uint32_t thread_index;
target_read_buffer( rtos->target, thread_list_head, param->pointer_width, (uint8_t *) &thread_index ); target_read_buffer(rtos->target,
thread_list_head,
param->pointer_width,
(uint8_t *) &thread_index);
uint32_t first_thread = thread_index; uint32_t first_thread = thread_index;
do do {
{
thread_list_size++; thread_list_size++;
retval = target_read_buffer( rtos->target, thread_index + param->thread_next_offset, param->pointer_width, (uint8_t *) &thread_index ); retval = target_read_buffer(rtos->target,
thread_index + param->thread_next_offset,
param->pointer_width,
(uint8_t *) &thread_index);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
} while (thread_index != first_thread); } while (thread_index != first_thread);
// read the current thread id /* read the current thread id */
uint32_t current_thread_addr; uint32_t current_thread_addr;
retval = target_read_buffer( rtos->target, rtos->symbols[eCos_VAL_current_thread_ptr].address, 4, (uint8_t *)&current_thread_addr); retval = target_read_buffer(rtos->target,
rtos->symbols[eCos_VAL_current_thread_ptr].address,
4,
(uint8_t *)&current_thread_addr);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
rtos->current_thread = 0; rtos->current_thread = 0;
retval = target_read_buffer( rtos->target, current_thread_addr + param->thread_uniqueid_offset, 2, (uint8_t *)&rtos->current_thread); retval = target_read_buffer(rtos->target,
if ( retval != ERROR_OK ) current_thread_addr + param->thread_uniqueid_offset,
{ 2,
(uint8_t *)&rtos->current_thread);
if (retval != ERROR_OK) {
LOG_OUTPUT("Could not read eCos current thread from target\r\n"); LOG_OUTPUT("Could not read eCos current thread from target\r\n");
return retval; return retval;
} }
if ( ( thread_list_size == 0 ) || ( rtos->current_thread == 0 ) ) if ((thread_list_size == 0) || (rtos->current_thread == 0)) {
{ /* Either : No RTOS threads - there is always at least the current execution though */
// Either : No RTOS threads - there is always at least the current execution though /* OR : No current thread - all threads suspended - show the current execution
// OR : No current thread - all threads suspended - show the current execution of idling * of idling */
char tmp_str[] = "Current Execution"; char tmp_str[] = "Current Execution";
thread_list_size++; thread_list_size++;
tasks_found++; tasks_found++;
rtos->thread_details = (struct thread_detail*) malloc( sizeof( struct thread_detail ) * thread_list_size ); rtos->thread_details = (struct thread_detail *) malloc(
sizeof(struct thread_detail) * thread_list_size);
rtos->thread_details->threadid = 1; rtos->thread_details->threadid = 1;
rtos->thread_details->exists = true; rtos->thread_details->exists = true;
rtos->thread_details->display_str = NULL; rtos->thread_details->display_str = NULL;
@ -211,23 +198,19 @@ static int eCos_update_threads( struct rtos* rtos)
rtos->thread_details->thread_name_str = (char *) malloc(sizeof(tmp_str)); rtos->thread_details->thread_name_str = (char *) malloc(sizeof(tmp_str));
strcpy(rtos->thread_details->thread_name_str, tmp_str); strcpy(rtos->thread_details->thread_name_str, tmp_str);
if (thread_list_size == 0) {
if ( thread_list_size == 0 )
{
rtos->thread_count = 1; rtos->thread_count = 1;
return ERROR_OK; return ERROR_OK;
} }
} } else {
else /* create space for new thread details */
{ rtos->thread_details = (struct thread_detail *) malloc(
// create space for new thread details sizeof(struct thread_detail) * thread_list_size);
rtos->thread_details = (struct thread_detail*) malloc( sizeof( struct thread_detail ) * thread_list_size );
} }
// loop over all threads /* loop over all threads */
thread_index = first_thread; thread_index = first_thread;
do do {
{
#define ECOS_THREAD_NAME_STR_SIZE (200) #define ECOS_THREAD_NAME_STR_SIZE (200)
char tmp_str[ECOS_THREAD_NAME_STR_SIZE]; char tmp_str[ECOS_THREAD_NAME_STR_SIZE];
@ -235,85 +218,92 @@ static int eCos_update_threads( struct rtos* rtos)
uint32_t name_ptr = 0; uint32_t name_ptr = 0;
uint32_t prev_thread_ptr; uint32_t prev_thread_ptr;
// Save the thread pointer /* Save the thread pointer */
uint16_t thread_id; uint16_t thread_id;
retval = target_read_buffer( rtos->target, thread_index + param->thread_uniqueid_offset, 2, (uint8_t *)&thread_id); retval = target_read_buffer(rtos->target,
if ( retval != ERROR_OK ) thread_index + param->thread_uniqueid_offset,
{ 2,
(uint8_t *)&thread_id);
if (retval != ERROR_OK) {
LOG_OUTPUT("Could not read eCos thread id from target\r\n"); LOG_OUTPUT("Could not read eCos thread id from target\r\n");
return retval; return retval;
} }
rtos->thread_details[tasks_found].threadid = thread_id; rtos->thread_details[tasks_found].threadid = thread_id;
// read the name pointer /* read the name pointer */
retval = target_read_buffer( rtos->target, thread_index + param->thread_name_offset, param->pointer_width, (uint8_t *)&name_ptr); retval = target_read_buffer(rtos->target,
if ( retval != ERROR_OK ) thread_index + param->thread_name_offset,
{ param->pointer_width,
(uint8_t *)&name_ptr);
if (retval != ERROR_OK) {
LOG_OUTPUT("Could not read eCos thread name pointer from target\r\n"); LOG_OUTPUT("Could not read eCos thread name pointer from target\r\n");
return retval; return retval;
} }
// Read the thread name /* Read the thread name */
retval = target_read_buffer( rtos->target, name_ptr, ECOS_THREAD_NAME_STR_SIZE, (uint8_t *)&tmp_str); retval =
if ( retval != ERROR_OK ) target_read_buffer(rtos->target,
{ name_ptr,
ECOS_THREAD_NAME_STR_SIZE,
(uint8_t *)&tmp_str);
if (retval != ERROR_OK) {
LOG_OUTPUT("Error reading thread name from eCos target\r\n"); LOG_OUTPUT("Error reading thread name from eCos target\r\n");
return retval; return retval;
} }
tmp_str[ECOS_THREAD_NAME_STR_SIZE-1] = '\x00'; tmp_str[ECOS_THREAD_NAME_STR_SIZE-1] = '\x00';
if (tmp_str[0] == '\x00') if (tmp_str[0] == '\x00')
{
strcpy(tmp_str, "No Name"); strcpy(tmp_str, "No Name");
}
rtos->thread_details[tasks_found].thread_name_str = (char*)malloc( strlen(tmp_str)+1 ); rtos->thread_details[tasks_found].thread_name_str =
(char *)malloc(strlen(tmp_str)+1);
strcpy(rtos->thread_details[tasks_found].thread_name_str, tmp_str); strcpy(rtos->thread_details[tasks_found].thread_name_str, tmp_str);
// Read the thread status /* Read the thread status */
int64_t thread_status = 0; int64_t thread_status = 0;
retval = target_read_buffer( rtos->target, thread_index + param->thread_state_offset, 4, (uint8_t *)&thread_status); retval = target_read_buffer(rtos->target,
if ( retval != ERROR_OK ) thread_index + param->thread_state_offset,
{ 4,
(uint8_t *)&thread_status);
if (retval != ERROR_OK) {
LOG_OUTPUT("Error reading thread state from eCos target\r\n"); LOG_OUTPUT("Error reading thread state from eCos target\r\n");
return retval; return retval;
} }
for( i = 0; (i < ECOS_NUM_STATES) && (eCos_thread_states[i].value!=thread_status); i++ ) for (i = 0; (i < ECOS_NUM_STATES) && (eCos_thread_states[i].value != thread_status); i++) {
{ /*
* empty
*/
} }
char *state_desc; char *state_desc;
if (i < ECOS_NUM_STATES) if (i < ECOS_NUM_STATES)
{
state_desc = eCos_thread_states[i].desc; state_desc = eCos_thread_states[i].desc;
}
else else
{
state_desc = "Unknown state"; state_desc = "Unknown state";
}
rtos->thread_details[tasks_found].extra_info_str = (char*)malloc( strlen(state_desc)+1 ); rtos->thread_details[tasks_found].extra_info_str = (char *)malloc(strlen(
state_desc)+1);
strcpy(rtos->thread_details[tasks_found].extra_info_str, state_desc); strcpy(rtos->thread_details[tasks_found].extra_info_str, state_desc);
rtos->thread_details[tasks_found].exists = true; rtos->thread_details[tasks_found].exists = true;
rtos->thread_details[tasks_found].display_str = NULL; rtos->thread_details[tasks_found].display_str = NULL;
tasks_found++; tasks_found++;
prev_thread_ptr = thread_index; prev_thread_ptr = thread_index;
// Get the location of the next thread structure. /* Get the location of the next thread structure. */
thread_index = rtos->symbols[eCos_VAL_thread_list].address; thread_index = rtos->symbols[eCos_VAL_thread_list].address;
retval = target_read_buffer( rtos->target, prev_thread_ptr + param->thread_next_offset, param->pointer_width, (uint8_t *) &thread_index ); retval = target_read_buffer(rtos->target,
if ( retval != ERROR_OK ) prev_thread_ptr + param->thread_next_offset,
{ param->pointer_width,
(uint8_t *) &thread_index);
if (retval != ERROR_OK) {
LOG_OUTPUT("Error reading next thread pointer in eCos thread list\r\n"); LOG_OUTPUT("Error reading next thread pointer in eCos thread list\r\n");
return retval; return retval;
} }
} } while (thread_index != first_thread);
while( thread_index!=first_thread );
rtos->thread_count = tasks_found; rtos->thread_count = tasks_found;
return 0; return 0;
@ -321,81 +311,78 @@ static int eCos_update_threads( struct rtos* rtos)
static int eCos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list) static int eCos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list)
{ {
int retval; int retval;
const struct eCos_params *param; const struct eCos_params *param;
*hex_reg_list = NULL; *hex_reg_list = NULL;
if (rtos == NULL) if (rtos == NULL)
{
return -1; return -1;
}
if (thread_id == 0) if (thread_id == 0)
{
return -2; return -2;
}
if (rtos->rtos_specific_params == NULL) if (rtos->rtos_specific_params == NULL)
{
return -3; return -3;
}
param = (const struct eCos_params *) rtos->rtos_specific_params; param = (const struct eCos_params *) rtos->rtos_specific_params;
/* Find the thread with that thread id */
// Find the thread with that thread id
uint16_t id = 0; uint16_t id = 0;
uint32_t thread_list_head = rtos->symbols[eCos_VAL_thread_list].address; uint32_t thread_list_head = rtos->symbols[eCos_VAL_thread_list].address;
uint32_t thread_index; uint32_t thread_index;
target_read_buffer( rtos->target, thread_list_head, param->pointer_width, (uint8_t *) &thread_index ); target_read_buffer(rtos->target, thread_list_head, param->pointer_width,
(uint8_t *)&thread_index);
bool done = false; bool done = false;
while(!done) while (!done) {
{ retval = target_read_buffer(rtos->target,
retval = target_read_buffer( rtos->target, thread_index + param->thread_uniqueid_offset, 2, (uint8_t*)&id); thread_index + param->thread_uniqueid_offset,
if ( retval != ERROR_OK ) 2,
{ (uint8_t *)&id);
if (retval != ERROR_OK) {
LOG_OUTPUT("Error reading unique id from eCos thread\r\n"); LOG_OUTPUT("Error reading unique id from eCos thread\r\n");
return retval; return retval;
} }
if( id==thread_id ) if (id == thread_id) {
{
done = true; done = true;
break; break;
} }
target_read_buffer( rtos->target, thread_index + param->thread_next_offset, param->pointer_width, (uint8_t *) &thread_index ); target_read_buffer(rtos->target,
thread_index + param->thread_next_offset,
param->pointer_width,
(uint8_t *) &thread_index);
} }
if(done) if (done) {
{ /* Read the stack pointer */
// Read the stack pointer
int64_t stack_ptr = 0; int64_t stack_ptr = 0;
retval = target_read_buffer( rtos->target, thread_index + param->thread_stack_offset, param->pointer_width, (uint8_t*)&stack_ptr); retval = target_read_buffer(rtos->target,
if ( retval != ERROR_OK ) thread_index + param->thread_stack_offset,
{ param->pointer_width,
(uint8_t *)&stack_ptr);
if (retval != ERROR_OK) {
LOG_OUTPUT("Error reading stack frame from eCos thread\r\n"); LOG_OUTPUT("Error reading stack frame from eCos thread\r\n");
return retval; return retval;
} }
return rtos_generic_stack_read( rtos->target, param->stacking_info, stack_ptr, hex_reg_list ); return rtos_generic_stack_read(rtos->target,
param->stacking_info,
stack_ptr,
hex_reg_list);
} }
return -1; return -1;
} }
static int eCos_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) static int eCos_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[])
{ {
unsigned int i; unsigned int i;
*symbol_list = (symbol_table_elem_t *) malloc( sizeof( symbol_table_elem_t ) * ECOS_NUM_SYMBOLS ); *symbol_list = (symbol_table_elem_t *) malloc(
sizeof(symbol_table_elem_t) * ECOS_NUM_SYMBOLS);
for (i = 0; i < ECOS_NUM_SYMBOLS; i++) for (i = 0; i < ECOS_NUM_SYMBOLS; i++)
{
(*symbol_list)[i].symbol_name = eCos_symbol_list[i]; (*symbol_list)[i].symbol_name = eCos_symbol_list[i];
}
return 0; return 0;
} }
@ -403,9 +390,8 @@ static int eCos_get_symbol_list_to_lookup(symbol_table_elem_t * symbol_list[])
static int eCos_detect_rtos(struct target *target) static int eCos_detect_rtos(struct target *target)
{ {
if ((target->rtos->symbols != NULL) && if ((target->rtos->symbols != NULL) &&
( target->rtos->symbols[eCos_VAL_thread_list].address != 0 ) ) (target->rtos->symbols[eCos_VAL_thread_list].address != 0)) {
{ /* looks like eCos */
// looks like eCos
return 1; return 1;
} }
return 0; return 0;
@ -414,12 +400,11 @@ static int eCos_detect_rtos( struct target* target )
static int eCos_create(struct target *target) static int eCos_create(struct target *target)
{ {
int i = 0; int i = 0;
while ( ( i < ECOS_NUM_PARAMS ) && ( 0 != strcmp( eCos_params_list[i].target_name, target->type->name ) ) ) while ((i < ECOS_NUM_PARAMS) &&
{ (0 != strcmp(eCos_params_list[i].target_name, target->type->name))) {
i++; i++;
} }
if ( i >= ECOS_NUM_PARAMS ) if (i >= ECOS_NUM_PARAMS) {
{
LOG_OUTPUT("Could not find target in eCos compatibility list\r\n"); LOG_OUTPUT("Could not find target in eCos compatibility list\r\n");
return -1; return -1;
} }

View File

@ -102,8 +102,8 @@ static int linux_os_create(struct target *target);
static int linux_os_dummy_update(struct rtos *rtos) static int linux_os_dummy_update(struct rtos *rtos)
{ {
/* update is done only when thread request come */ /* update is done only when thread request come
/* too many thread to do it on each stop */ * too many thread to do it on each stop */
return 0; return 0;
} }
@ -216,8 +216,10 @@ static int linux_os_thread_reg_list(struct rtos *rtos,
if (found == 0) { if (found == 0) {
LOG_ERROR LOG_ERROR
("current thread %" PRIx64": no target to perform access of core id %x", (
thread_id, next->core_id); "current thread %" PRIx64 ": no target to perform access of core id %x",
thread_id,
next->core_id);
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -296,9 +298,8 @@ static int linux_os_thread_reg_list(struct rtos *rtos,
hex_string = hex_string =
reg_converter(hex_string, &temp->context->PC, 4); reg_converter(hex_string, &temp->context->PC, 4);
for (i = 0; i < 100; i++) { /*100 */ for (i = 0; i < 100; i++) /*100 */
hex_string += sprintf(hex_string, "%02x", 0); hex_string += sprintf(hex_string, "%02x", 0);
}
uint32_t cpsr = 0x00000000; uint32_t cpsr = 0x00000000;
hex_string = reg_converter(hex_string, &cpsr, 4); hex_string = reg_converter(hex_string, &cpsr, 4);
@ -370,7 +371,6 @@ int fill_task_pid(struct target *target, struct threads *t)
int fill_task(struct target *target, struct threads *t) int fill_task(struct target *target, struct threads *t)
{ {
int retval; int retval;
uint32_t pid_addr = t->base_addr + PID; uint32_t pid_addr = t->base_addr + PID;
uint32_t mem_addr = t->base_addr + MEM; uint32_t mem_addr = t->base_addr + MEM;
@ -415,9 +415,8 @@ int fill_task(struct target *target, struct threads *t)
} else } else
LOG_ERROR LOG_ERROR
("fill task: unable to read memory -- ASID"); ("fill task: unable to read memory -- ASID");
} else { } else
t->asid = 0; t->asid = 0;
}
} else } else
LOG_ERROR("fill task: unable to read memory"); LOG_ERROR("fill task: unable to read memory");
@ -495,8 +494,7 @@ int get_current(struct target *target, int create)
int retval; int retval;
if (target_get_gdb_reg_list(head->target, &reg_list, if (target_get_gdb_reg_list(head->target, &reg_list,
&reg_list_size) != &reg_list_size) != ERROR_OK)
ERROR_OK)
return ERROR_TARGET_FAILURE; return ERROR_TARGET_FAILURE;
if (!reg_list[13]->valid) if (!reg_list[13]->valid)
@ -519,10 +517,8 @@ int get_current(struct target *target, int create)
linux_os->current_threads; linux_os->current_threads;
cpu = head->target->coreid; cpu = head->target->coreid;
while ((ct != NULL) while ((ct != NULL) && (ct->core_id != (int32_t) cpu))
&& (ct->core_id != (int32_t) cpu)) {
ct = ct->next; ct = ct->next;
}
if ((ct != NULL) && (ct->TS == 0xdeadbeef)) if ((ct != NULL) && (ct->TS == 0xdeadbeef))
ct->TS = TS; ct->TS = TS;
@ -776,9 +772,7 @@ int linux_get_tasks(struct target *target, int context)
retval = get_current(target, 1); retval = get_current(target, 1);
while (((t->base_addr != linux_os->init_task_addr) && while (((t->base_addr != linux_os->init_task_addr) &&
(t->base_addr != 0)) (t->base_addr != 0)) || (loop == 0)) {
|| (loop == 0)
) {
loop++; loop++;
retval = fill_task(target, t); retval = fill_task(target, t);
retval = get_name(target, t); retval = get_name(target, t);
@ -860,7 +854,6 @@ static int clean_threadlist(struct target *target)
static int linux_os_clean(struct target *target) static int linux_os_clean(struct target *target)
{ {
struct linux_os *os_linux = (struct linux_os *) struct linux_os *os_linux = (struct linux_os *)
target->rtos->rtos_specific_params; target->rtos->rtos_specific_params;
clean_threadlist(target); clean_threadlist(target);
@ -1005,7 +998,6 @@ static int linux_task_update(struct target *target, int context)
} }
thread_list = thread_list->next; thread_list = thread_list->next;
} }
int found = 0; int found = 0;
@ -1042,20 +1034,14 @@ static int linux_task_update(struct target *target, int context)
while (thread_list != NULL) { while (thread_list != NULL) {
#ifdef PID_CHECK #ifdef PID_CHECK
if (t->pid == thread_list->pid) { if (t->pid == thread_list->pid) {
#else #else
if (t->base_addr == thread_list->base_addr) { if (t->base_addr == thread_list->base_addr) {
#endif #endif
if (!thread_list->status) { if (!thread_list->status) {
#ifdef PID_CHECK #ifdef PID_CHECK
if (t->base_addr != thread_list->base_addr)
if (t->base_addr != LOG_INFO("thread base_addr has changed !!");
thread_list->base_addr) {
LOG_INFO
("thread base_addr has changed !!");
}
#endif #endif
/* this is not a current thread */ /* this is not a current thread */
thread_list->base_addr = t->base_addr; thread_list->base_addr = t->base_addr;
@ -1105,7 +1091,6 @@ static int linux_task_update(struct target *target, int context)
linux_os->thread_count++; linux_os->thread_count++;
} else } else
t->base_addr = next_task(target, t); t->base_addr = next_task(target, t);
} }
LOG_INFO("update thread done %" PRId64 ", mean%" PRId64 "\n", LOG_INFO("update thread done %" PRId64 ", mean%" PRId64 "\n",
@ -1119,7 +1104,6 @@ int linux_gdb_thread_packet(struct target *target,
struct connection *connection, char *packet, struct connection *connection, char *packet,
int packet_size) int packet_size)
{ {
int retval; int retval;
struct linux_os *linux_os = struct linux_os *linux_os =
(struct linux_os *)target->rtos->rtos_specific_params; (struct linux_os *)target->rtos->rtos_specific_params;
@ -1331,8 +1315,8 @@ int linux_gdb_h_packet(struct connection *connection,
} }
if (ct == NULL) { if (ct == NULL) {
/* no current thread can be identified */ /* no current thread can be identified
/* any way with smp */ * any way with smp */
LOG_INFO("no current thread identified"); LOG_INFO("no current thread identified");
/* attempt to display the name of the 2 threads identified with /* attempt to display the name of the 2 threads identified with
* get_current */ * get_current */
@ -1446,19 +1430,15 @@ static int linux_thread_packet(struct connection *connection, char *packet,
if (linux_os->threads_lookup == 1) { if (linux_os->threads_lookup == 1) {
ct = linux_os->current_threads; ct = linux_os->current_threads;
while ((ct != NULL) while ((ct != NULL) && (ct->core_id) != target->coreid)
&& (ct->core_id) != target->coreid) {
ct = ct->next; ct = ct->next;
}
if ((ct != NULL) && (ct->threadid == -1)) { if ((ct != NULL) && (ct->threadid == -1)) {
ct = linux_os->current_threads; ct = linux_os->current_threads;
while ((ct != NULL) while ((ct != NULL) && (ct->threadid == -1))
&& (ct->threadid == -1)) {
ct = ct->next; ct = ct->next;
} }
}
if ((ct != NULL) && (ct->threadid != if ((ct != NULL) && (ct->threadid !=
target->rtos-> target->rtos->
@ -1466,7 +1446,8 @@ static int linux_thread_packet(struct connection *connection, char *packet,
&& (target->rtos->current_threadid != -1)) && (target->rtos->current_threadid != -1))
LOG_WARNING("WARNING! current GDB thread do not match" \ LOG_WARNING("WARNING! current GDB thread do not match" \
"current thread running." \ "current thread running." \
"Switch thread in GDB to threadid %d", (int)ct->threadid); "Switch thread in GDB to threadid %d",
(int)ct->threadid);
LOG_INFO("threads_needs_update = 1"); LOG_INFO("threads_needs_update = 1");
linux_os->threads_needs_update = 1; linux_os->threads_needs_update = 1;
@ -1552,9 +1533,9 @@ static char *linux_ps_command(struct target *target)
int retval = ERROR_OK; int retval = ERROR_OK;
char *display; char *display;
if (linux_os->threads_lookup == 0) { if (linux_os->threads_lookup == 0)
retval = linux_get_tasks(target, 1); retval = linux_get_tasks(target, 1);
} else { else {
if (linux_os->threads_needs_update != 0) if (linux_os->threads_needs_update != 0)
retval = linux_task_update(target, 0); retval = linux_task_update(target, 0);
} }

View File

@ -22,25 +22,20 @@
#include "config.h" #include "config.h"
#endif #endif
#include "rtos.h" #include "rtos.h"
#include "target/target.h" #include "target/target.h"
#include "helper/log.h" #include "helper/log.h"
#include "server/gdb_server.h" #include "server/gdb_server.h"
static void hex_to_str(char *dst, char *hex_src); static void hex_to_str(char *dst, char *hex_src);
/* RTOSs */ /* RTOSs */
extern struct rtos_type FreeRTOS_rtos; extern struct rtos_type FreeRTOS_rtos;
extern struct rtos_type ThreadX_rtos; extern struct rtos_type ThreadX_rtos;
extern struct rtos_type eCos_rtos; extern struct rtos_type eCos_rtos;
extern struct rtos_type Linux_os; extern struct rtos_type Linux_os;
static struct rtos_type *rtos_types[] = static struct rtos_type *rtos_types[] = {
{
&ThreadX_rtos, &ThreadX_rtos,
&FreeRTOS_rtos, &FreeRTOS_rtos,
&eCos_rtos, &eCos_rtos,
@ -57,7 +52,6 @@ int rtos_smp_init(struct target *target)
return ERROR_TARGET_INIT_FAILED; return ERROR_TARGET_INIT_FAILED;
} }
int rtos_create(Jim_GetOptInfo *goi, struct target *target) int rtos_create(Jim_GetOptInfo *goi, struct target *target)
{ {
int x; int x;
@ -76,23 +70,20 @@ int rtos_create(Jim_GetOptInfo *goi, struct target * target)
} }
} }
if (target->rtos) { if (target->rtos)
free((void *)(target->rtos)); free((void *)(target->rtos));
} /* e = Jim_GetOpt_String(goi,
// e = Jim_GetOpt_String(goi, &cp, NULL); * &cp, NULL); */
// target->rtos = strdup(cp); /* target->rtos = strdup(cp); */
Jim_GetOpt_String(goi, &cp, NULL); Jim_GetOpt_String(goi, &cp, NULL);
/* now does target type exist */ /* now does target type exist */
if ( 0 == strcmp( cp, "auto") ) if (0 == strcmp(cp, "auto")) {
{ /* auto detection of RTOS */
// auto detection of RTOS
target->rtos_auto_detect = true; target->rtos_auto_detect = true;
x = 0; x = 0;
} } else {
else
{
for (x = 0; rtos_types[x]; x++) { for (x = 0; rtos_types[x]; x++) {
if (0 == strcmp(cp, rtos_types[x]->name)) { if (0 == strcmp(cp, rtos_types[x]->name)) {
@ -101,7 +92,8 @@ int rtos_create(Jim_GetOptInfo *goi, struct target * target)
} }
} }
if (rtos_types[x] == NULL) { if (rtos_types[x] == NULL) {
Jim_SetResultFormatted(goi->interp, "Unknown rtos type %s, try one of ", cp); Jim_SetResultFormatted(goi->interp, "Unknown rtos type %s, try one of ",
cp);
for (x = 0; rtos_types[x]; x++) { for (x = 0; rtos_types[x]; x++) {
if (rtos_types[x + 1]) { if (rtos_types[x + 1]) {
Jim_AppendStrings(goi->interp, Jim_AppendStrings(goi->interp,
@ -129,9 +121,7 @@ int rtos_create(Jim_GetOptInfo *goi, struct target * target)
target->rtos->gdb_thread_packet = rtos_thread_packet; target->rtos->gdb_thread_packet = rtos_thread_packet;
if (0 != strcmp(cp, "auto")) if (0 != strcmp(cp, "auto"))
{
target->rtos->type->create(target); target->rtos->type->create(target);
}
return JIM_OK; return JIM_OK;
} }
@ -140,7 +130,8 @@ int gdb_thread_packet(struct connection *connection, char *packet, int packet_si
{ {
struct target *target = get_target_from_connection(connection); struct target *target = get_target_from_connection(connection);
if (target->rtos == NULL) if (target->rtos == NULL)
return rtos_thread_packet(connection, packet, packet_size); /* thread not found*/ return rtos_thread_packet(connection, packet, packet_size); /* thread not
*found*/
return target->rtos->gdb_thread_packet(connection, packet, packet_size); return target->rtos->gdb_thread_packet(connection, packet, packet_size);
} }
/* return -1 if no rtos defined, 0 if rtos and symbol to be asked, 1 if all /* return -1 if no rtos defined, 0 if rtos and symbol to be asked, 1 if all
@ -171,8 +162,8 @@ int rtos_qsymbol(struct connection *connection, char *packet, int packet_size)
hex_to_str(name_str, hex_name_str); hex_to_str(name_str, hex_name_str);
symbol_num = 0; symbol_num = 0;
while ((target->rtos->symbols[symbol_num].symbol_name != NULL) while ((target->rtos->symbols[symbol_num].symbol_name != NULL) &&
&& (0 != strcmp(target->rtos->symbols[symbol_num].symbol_name, name_str))) (0 != strcmp(target->rtos->symbols[symbol_num].symbol_name, name_str)))
symbol_num++; symbol_num++;
if (target->rtos->symbols[symbol_num].symbol_name == NULL) { if (target->rtos->symbols[symbol_num].symbol_name == NULL) {
@ -194,7 +185,8 @@ int rtos_qsymbol(struct connection *connection, char *packet, int packet_size)
(1 == target->rtos->type->detect_rtos(target))) { (1 == target->rtos->type->detect_rtos(target))) {
/* Found correct RTOS or not autodetecting */ /* Found correct RTOS or not autodetecting */
if (target->rtos_auto_detect == true) if (target->rtos_auto_detect == true)
LOG_OUTPUT("Auto-detected RTOS: %s\r\n", target->rtos->type->name); LOG_OUTPUT("Auto-detected RTOS: %s\r\n",
target->rtos->type->name);
symbols_done = 1; symbols_done = 1;
} else { } else {
/* Auto detecting RTOS and currently not found */ /* Auto detecting RTOS and currently not found */
@ -203,7 +195,8 @@ int rtos_qsymbol(struct connection *connection, char *packet, int packet_size)
symbols_done = 1; symbols_done = 1;
else { else {
next_symbol_num = 0; next_symbol_num = 0;
target->rtos->type->get_symbol_list_to_lookup(&target->rtos->symbols); target->rtos->type->get_symbol_list_to_lookup(
&target->rtos->symbols);
} }
} }
} }
@ -225,34 +218,28 @@ int rtos_qsymbol(struct connection *connection, char *packet, int packet_size)
return -1; return -1;
} }
int rtos_thread_packet(struct connection *connection, char *packet, int packet_size) int rtos_thread_packet(struct connection *connection, char *packet, int packet_size)
{ {
struct target *target = get_target_from_connection(connection); struct target *target = get_target_from_connection(connection);
if (strstr(packet, "qThreadExtraInfo,")) if (strstr(packet, "qThreadExtraInfo,")) {
{ if ((target->rtos != NULL) && (target->rtos->thread_details != NULL) &&
if ((target->rtos != NULL) && (target->rtos->thread_details != NULL) && (target->rtos->thread_count != 0)) (target->rtos->thread_count != 0)) {
{
threadid_t threadid = 0; threadid_t threadid = 0;
int found = -1; int found = -1;
sscanf(packet, "qThreadExtraInfo,%" SCNx64, &threadid); sscanf(packet, "qThreadExtraInfo,%" SCNx64, &threadid);
if ((target->rtos != NULL) && (target->rtos->thread_details if ((target->rtos != NULL) && (target->rtos->thread_details != NULL)) {
!= NULL)) {
int thread_num; int thread_num;
for (thread_num = 0; thread_num for (thread_num = 0; thread_num < target->rtos->thread_count; thread_num++) {
< target->rtos->thread_count; thread_num++) { if (target->rtos->thread_details[thread_num].threadid == threadid) {
if (target->rtos->thread_details[thread_num].threadid if (target->rtos->thread_details[thread_num].exists)
== threadid) {
if (target->rtos->thread_details[thread_num].exists) {
found = thread_num; found = thread_num;
} }
} }
} }
}
if (found == -1) { if (found == -1) {
gdb_put_packet(connection, "E01", 3); // thread not found gdb_put_packet(connection, "E01", 3); /* thread not found */
return ERROR_OK; return ERROR_OK;
} }
@ -260,40 +247,27 @@ int rtos_thread_packet(struct connection *connection, char *packet, int packet_s
int str_size = 0; int str_size = 0;
if (detail->display_str != NULL) if (detail->display_str != NULL)
{
str_size += strlen(detail->display_str); str_size += strlen(detail->display_str);
}
if (detail->thread_name_str != NULL) if (detail->thread_name_str != NULL)
{
str_size += strlen(detail->thread_name_str); str_size += strlen(detail->thread_name_str);
}
if (detail->extra_info_str != NULL) if (detail->extra_info_str != NULL)
{
str_size += strlen(detail->extra_info_str); str_size += strlen(detail->extra_info_str);
}
char *tmp_str = (char *) malloc(str_size + 7); char *tmp_str = (char *) malloc(str_size + 7);
char *tmp_str_ptr = tmp_str; char *tmp_str_ptr = tmp_str;
if (detail->display_str != NULL) if (detail->display_str != NULL)
{
tmp_str_ptr += sprintf(tmp_str_ptr, "%s", detail->display_str); tmp_str_ptr += sprintf(tmp_str_ptr, "%s", detail->display_str);
} if (detail->thread_name_str != NULL) {
if ( detail->thread_name_str != NULL )
{
if (tmp_str_ptr != tmp_str) if (tmp_str_ptr != tmp_str)
{
tmp_str_ptr += sprintf(tmp_str_ptr, " : "); tmp_str_ptr += sprintf(tmp_str_ptr, " : ");
}
tmp_str_ptr += sprintf(tmp_str_ptr, "%s", detail->thread_name_str); tmp_str_ptr += sprintf(tmp_str_ptr, "%s", detail->thread_name_str);
} }
if ( detail->extra_info_str != NULL ) if (detail->extra_info_str != NULL) {
{
if (tmp_str_ptr != tmp_str) if (tmp_str_ptr != tmp_str)
{
tmp_str_ptr += sprintf(tmp_str_ptr, " : "); tmp_str_ptr += sprintf(tmp_str_ptr, " : ");
} tmp_str_ptr +=
tmp_str_ptr += sprintf( tmp_str_ptr, " : %s", detail->extra_info_str ); sprintf(tmp_str_ptr, " : %s", detail->extra_info_str);
} }
assert(strlen(tmp_str) == assert(strlen(tmp_str) ==
@ -310,11 +284,8 @@ int rtos_thread_packet(struct connection *connection, char *packet, int packet_s
} }
gdb_put_packet(connection, "", 0); gdb_put_packet(connection, "", 0);
return ERROR_OK; return ERROR_OK;
} } else if (strstr(packet, "qSymbol")) {
else if (strstr(packet, "qSymbol")) if (rtos_qsymbol(connection, packet, packet_size) == 1) {
{
if (rtos_qsymbol(connection, packet, packet_size) == 1)
{
target->rtos_auto_detect = false; target->rtos_auto_detect = false;
target->rtos->type->create(target); target->rtos->type->create(target);
target->rtos->type->update_threads(target->rtos); target->rtos->type->update_threads(target->rtos);
@ -322,91 +293,64 @@ int rtos_thread_packet(struct connection *connection, char *packet, int packet_s
gdb_put_packet(connection, "OK", 2); gdb_put_packet(connection, "OK", 2);
} }
return ERROR_OK; return ERROR_OK;
} } else if (strstr(packet, "qfThreadInfo")) {
else if (strstr(packet, "qfThreadInfo"))
{
int i; int i;
if ( ( target->rtos != NULL ) && ( target->rtos->thread_count != 0 ) ) if ((target->rtos != NULL) && (target->rtos->thread_count != 0)) {
{
char *out_str = (char *) malloc(17 * target->rtos->thread_count + 5); char *out_str = (char *) malloc(17 * target->rtos->thread_count + 5);
char *tmp_str = out_str; char *tmp_str = out_str;
tmp_str += sprintf(tmp_str, "m"); tmp_str += sprintf(tmp_str, "m");
for (i = 0; i < target->rtos->thread_count; i++) { for (i = 0; i < target->rtos->thread_count; i++) {
if (i != 0) { if (i != 0)
tmp_str += sprintf(tmp_str, ","); tmp_str += sprintf(tmp_str, ",");
}
tmp_str += sprintf(tmp_str, "%016" PRIx64, tmp_str += sprintf(tmp_str, "%016" PRIx64,
target->rtos->thread_details[i].threadid); target->rtos->thread_details[i].threadid);
} }
tmp_str[0] = 0; tmp_str[0] = 0;
gdb_put_packet(connection, out_str, strlen(out_str)); gdb_put_packet(connection, out_str, strlen(out_str));
} } else
else
{
gdb_put_packet(connection, "", 0); gdb_put_packet(connection, "", 0);
}
return ERROR_OK; return ERROR_OK;
} } else if (strstr(packet, "qsThreadInfo")) {
else if (strstr(packet, "qsThreadInfo"))
{
gdb_put_packet(connection, "l", 1); gdb_put_packet(connection, "l", 1);
return ERROR_OK; return ERROR_OK;
} } else if (strstr(packet, "qAttached")) {
else if (strstr(packet, "qAttached"))
{
gdb_put_packet(connection, "1", 1); gdb_put_packet(connection, "1", 1);
return ERROR_OK; return ERROR_OK;
} } else if (strstr(packet, "qOffsets")) {
else if (strstr(packet, "qOffsets"))
{
char offsets[] = "Text=0;Data=0;Bss=0"; char offsets[] = "Text=0;Data=0;Bss=0";
gdb_put_packet(connection, offsets, sizeof(offsets)-1); gdb_put_packet(connection, offsets, sizeof(offsets)-1);
return ERROR_OK; return ERROR_OK;
} } else if (strstr(packet, "qC")) {
else if (strstr(packet, "qC")) if (target->rtos != NULL) {
{
if( target->rtos!=NULL )
{
char buffer[15]; char buffer[15];
int size; int size;
size = snprintf(buffer, 15, "QC%08X", (int)target->rtos->current_thread); size = snprintf(buffer, 15, "QC%08X", (int)target->rtos->current_thread);
gdb_put_packet(connection, buffer, size); gdb_put_packet(connection, buffer, size);
} } else
else
{
gdb_put_packet(connection, "QC0", 3); gdb_put_packet(connection, "QC0", 3);
}
return ERROR_OK; return ERROR_OK;
} } else if (packet[0] == 'T') { /* Is thread alive? */
else if ( packet[0] == 'T' ) // Is thread alive?
{
threadid_t threadid; threadid_t threadid;
int found = -1; int found = -1;
sscanf(packet, "T%" SCNx64, &threadid); sscanf(packet, "T%" SCNx64, &threadid);
if ((target->rtos != NULL) && (target->rtos->thread_details if ((target->rtos != NULL) && (target->rtos->thread_details != NULL)) {
!= NULL)) {
int thread_num; int thread_num;
for (thread_num = 0; thread_num for (thread_num = 0; thread_num < target->rtos->thread_count; thread_num++) {
< target->rtos->thread_count; thread_num++) { if (target->rtos->thread_details[thread_num].threadid == threadid) {
if (target->rtos->thread_details[thread_num].threadid if (target->rtos->thread_details[thread_num].exists)
== threadid) {
if (target->rtos->thread_details[thread_num].exists) {
found = thread_num; found = thread_num;
} }
} }
} }
} if (found != -1)
if (found != -1) { gdb_put_packet(connection, "OK", 2); /* thread alive */
gdb_put_packet(connection, "OK", 2); // thread alive else
} else { gdb_put_packet(connection, "E01", 3); /* thread not found */
gdb_put_packet(connection, "E01", 3); // thread not found
}
return ERROR_OK; return ERROR_OK;
} } else if (packet[0] == 'H') { /* Set current thread ( 'c' for step and continue, 'g' for
else if ( packet[0] == 'H') // Set current thread ( 'c' for step and continue, 'g' for all other operations ) * all other operations ) */
{
if ((packet[1] == 'g') && (target->rtos != NULL)) if ((packet[1] == 'g') && (target->rtos != NULL))
sscanf(packet, "Hg%16" SCNx64, &target->rtos->current_threadid); sscanf(packet, "Hg%16" SCNx64, &target->rtos->current_threadid);
gdb_put_packet(connection, "OK", 2); gdb_put_packet(connection, "OK", 2);
@ -420,17 +364,16 @@ int rtos_get_gdb_reg_list(struct connection *connection)
{ {
struct target *target = get_target_from_connection(connection); struct target *target = get_target_from_connection(connection);
int64_t current_threadid = target->rtos->current_threadid; int64_t current_threadid = target->rtos->current_threadid;
if ((target->rtos != NULL) && if ((target->rtos != NULL) && (current_threadid != -1) &&
(current_threadid != -1) &&
(current_threadid != 0) && (current_threadid != 0) &&
((current_threadid != target->rtos->current_thread) || ((current_threadid != target->rtos->current_thread) ||
(target->smp))) /* in smp several current thread are possible */ (target->smp))) { /* in smp several current thread are possible */
{
char *hex_reg_list; char *hex_reg_list;
target->rtos->type->get_thread_reg_list( target->rtos, current_threadid, &hex_reg_list ); target->rtos->type->get_thread_reg_list(target->rtos,
current_threadid,
&hex_reg_list);
if ( hex_reg_list != NULL ) if (hex_reg_list != NULL) {
{
gdb_put_packet(connection, hex_reg_list, strlen(hex_reg_list)); gdb_put_packet(connection, hex_reg_list, strlen(hex_reg_list));
free(hex_reg_list); free(hex_reg_list);
return ERROR_OK; return ERROR_OK;
@ -439,9 +382,10 @@ int rtos_get_gdb_reg_list(struct connection *connection)
return ERROR_FAIL; return ERROR_FAIL;
} }
int rtos_generic_stack_read(struct target *target,
const struct rtos_register_stacking *stacking,
int rtos_generic_stack_read( struct target * target, const struct rtos_register_stacking* stacking, int64_t stack_ptr, char ** hex_reg_list ) int64_t stack_ptr,
char **hex_reg_list)
{ {
int list_size = 0; int list_size = 0;
char *tmp_str_ptr; char *tmp_str_ptr;
@ -449,66 +393,53 @@ int rtos_generic_stack_read( struct target * target, const struct rtos_register_
int i; int i;
int retval; int retval;
if ( stack_ptr == 0) if (stack_ptr == 0) {
{
LOG_OUTPUT("Error: null stack pointer in thread\r\n"); LOG_OUTPUT("Error: null stack pointer in thread\r\n");
return -5; return -5;
} }
// Read the stack /* Read the stack */
uint8_t *stack_data = (uint8_t *) malloc(stacking->stack_registers_size); uint8_t *stack_data = (uint8_t *) malloc(stacking->stack_registers_size);
uint32_t address = stack_ptr; uint32_t address = stack_ptr;
if (stacking->stack_growth_direction == 1) if (stacking->stack_growth_direction == 1)
{
address -= stacking->stack_registers_size; address -= stacking->stack_registers_size;
}
retval = target_read_buffer(target, address, stacking->stack_registers_size, stack_data); retval = target_read_buffer(target, address, stacking->stack_registers_size, stack_data);
if ( retval != ERROR_OK ) if (retval != ERROR_OK) {
{
LOG_OUTPUT("Error reading stack frame from FreeRTOS thread\r\n"); LOG_OUTPUT("Error reading stack frame from FreeRTOS thread\r\n");
return retval; return retval;
} }
/* #if 0
LOG_OUTPUT("Stack Data :"); LOG_OUTPUT("Stack Data :");
for (i = 0; i < stacking->stack_registers_size; i++) for (i = 0; i < stacking->stack_registers_size; i++)
{
LOG_OUTPUT("%02X", stack_data[i]); LOG_OUTPUT("%02X", stack_data[i]);
}
LOG_OUTPUT("\r\n"); LOG_OUTPUT("\r\n");
*/ #endif
for (i = 0; i < stacking->num_output_registers; i++) for (i = 0; i < stacking->num_output_registers; i++)
{
list_size += stacking->register_offsets[i].width_bits/8; list_size += stacking->register_offsets[i].width_bits/8;
}
*hex_reg_list = (char *)malloc(list_size*2 + 1); *hex_reg_list = (char *)malloc(list_size*2 + 1);
tmp_str_ptr = *hex_reg_list; tmp_str_ptr = *hex_reg_list;
new_stack_ptr = stack_ptr - stacking->stack_growth_direction * stacking->stack_registers_size; new_stack_ptr = stack_ptr - stacking->stack_growth_direction *
stacking->stack_registers_size;
if (stacking->stack_alignment != 0) { if (stacking->stack_alignment != 0) {
/* Align new stack pointer to x byte boundary */ /* Align new stack pointer to x byte boundary */
new_stack_ptr = new_stack_ptr =
(new_stack_ptr & (~((int64_t) stacking->stack_alignment - 1))) + (new_stack_ptr & (~((int64_t) stacking->stack_alignment - 1))) +
((stacking->stack_growth_direction == -1) ? stacking->stack_alignment : 0); ((stacking->stack_growth_direction == -1) ? stacking->stack_alignment : 0);
} }
for( i = 0; i < stacking->num_output_registers; i++ ) for (i = 0; i < stacking->num_output_registers; i++) {
{
int j; int j;
for ( j = 0; j < stacking->register_offsets[i].width_bits/8; j++ ) for (j = 0; j < stacking->register_offsets[i].width_bits/8; j++) {
{
if (stacking->register_offsets[i].offset == -1) if (stacking->register_offsets[i].offset == -1)
{
tmp_str_ptr += sprintf(tmp_str_ptr, "%02x", 0); tmp_str_ptr += sprintf(tmp_str_ptr, "%02x", 0);
}
else if (stacking->register_offsets[i].offset == -2) else if (stacking->register_offsets[i].offset == -2)
{ tmp_str_ptr += sprintf(tmp_str_ptr, "%02x",
tmp_str_ptr += sprintf( tmp_str_ptr, "%02x", ((uint8_t*)&new_stack_ptr)[j] ); ((uint8_t *)&new_stack_ptr)[j]);
}
else else
{ tmp_str_ptr += sprintf(tmp_str_ptr, "%02x",
tmp_str_ptr += sprintf( tmp_str_ptr,"%02x", stack_data[ stacking->register_offsets[i].offset + j ] ); stack_data[stacking->register_offsets[i].offset + j]);
} }
} }
} /* LOG_OUTPUT("Output register string: %s\r\n", *hex_reg_list); */
// LOG_OUTPUT("Output register string: %s\r\n", *hex_reg_list);
return ERROR_OK; return ERROR_OK;
} }
@ -517,25 +448,18 @@ int rtos_try_next( struct target * target )
int x; int x;
if (target->rtos == NULL) if (target->rtos == NULL)
{
return -1; return -1;
}
for (x = 0; rtos_types[x]; x++) { for (x = 0; rtos_types[x]; x++) {
if (target->rtos->type == rtos_types[x]) { if (target->rtos->type == rtos_types[x]) {
/* found */ /* found */
if ( rtos_types[x+1] != NULL ) if (rtos_types[x+1] != NULL) {
{
target->rtos->type = rtos_types[x+1]; target->rtos->type = rtos_types[x+1];
if (target->rtos->symbols != NULL) if (target->rtos->symbols != NULL)
{
free(target->rtos->symbols); free(target->rtos->symbols);
}
return 1; return 1;
} } else {
else /* No more rtos types */
{
// No more rtos types
return 0; return 0;
} }
@ -550,17 +474,16 @@ static void hex_to_str( char* dst, char * hex_src )
int src_pos = 0; int src_pos = 0;
int dst_pos = 0; int dst_pos = 0;
while ( hex_src[src_pos] != '\x00' ) while (hex_src[src_pos] != '\x00') {
{
char hex_char = hex_src[src_pos]; char hex_char = hex_src[src_pos];
char hex_digit_val = (hex_char>='a')?hex_char-'a'+10:(hex_char>='A')?hex_char-'A'+10:hex_char-'0'; char hex_digit_val =
if ( 0 == (src_pos & 0x01) ) (hex_char >=
{ 'a') ? hex_char-'a'+
10 : (hex_char >= 'A') ? hex_char-'A'+10 : hex_char-'0';
if (0 == (src_pos & 0x01)) {
dst[dst_pos] = hex_digit_val; dst[dst_pos] = hex_digit_val;
dst[dst_pos+1] = 0; dst[dst_pos+1] = 0;
} } else {
else
{
((unsigned char *)dst)[dst_pos] <<= 4; ((unsigned char *)dst)[dst_pos] <<= 4;
((unsigned char *)dst)[dst_pos] += hex_digit_val; ((unsigned char *)dst)[dst_pos] += hex_digit_val;
dst_pos++; dst_pos++;
@ -575,18 +498,13 @@ int str_to_hex(char *hex_dst, char *src)
char *posptr = hex_dst; char *posptr = hex_dst;
unsigned i; unsigned i;
for (i = 0; i < strlen(src); i++) for (i = 0; i < strlen(src); i++)
{
posptr += sprintf(posptr, "%02x", (unsigned char)src[i]); posptr += sprintf(posptr, "%02x", (unsigned char)src[i]);
return posptr - hex_dst;
} }
return (posptr-hex_dst);
}
int rtos_update_threads(struct target *target) int rtos_update_threads(struct target *target)
{ {
if ((target->rtos != NULL) && (target->rtos->type != NULL)) if ((target->rtos != NULL) && (target->rtos->type != NULL))
{
target->rtos->type->update_threads(target->rtos); target->rtos->type->update_threads(target->rtos);
}
return ERROR_OK; return ERROR_OK;
} }

View File

@ -21,7 +21,6 @@
#ifndef RTOS_H #ifndef RTOS_H
#define RTOS_H #define RTOS_H
#include "server/server.h" #include "server/server.h"
#include <helper/types.h> #include <helper/types.h>
#include <jim-nvp.h> #include <jim-nvp.h>
@ -34,15 +33,13 @@ struct reg;
/** /**
* Table should be terminated by an element with NULL in symbol_name * Table should be terminated by an element with NULL in symbol_name
*/ */
typedef struct symbol_table_elem_struct typedef struct symbol_table_elem_struct {
{
char *symbol_name; char *symbol_name;
symbol_address_t address; symbol_address_t address;
} symbol_table_elem_t; } symbol_table_elem_t;
struct thread_detail struct thread_detail {
{
threadid_t threadid; threadid_t threadid;
bool exists; bool exists;
char *display_str; char *display_str;
@ -50,11 +47,9 @@ struct thread_detail
char *extra_info_str; char *extra_info_str;
}; };
struct rtos struct rtos {
{
const struct rtos_type *type; const struct rtos_type *type;
symbol_table_elem_t *symbols; symbol_table_elem_t *symbols;
struct target *target; struct target *target;
/* add a context variable instead of global variable */ /* add a context variable instead of global variable */
@ -64,14 +59,9 @@ struct rtos
int thread_count; int thread_count;
int (*gdb_thread_packet)(struct connection *connection, char *packet, int packet_size); int (*gdb_thread_packet)(struct connection *connection, char *packet, int packet_size);
void *rtos_specific_params; void *rtos_specific_params;
}; };
struct rtos_type {
struct rtos_type
{
char *name; char *name;
int (*detect_rtos)(struct target *target); int (*detect_rtos)(struct target *target);
int (*create)(struct target *target); int (*create)(struct target *target);
@ -83,16 +73,14 @@ struct rtos_type
char * (*ps_command)(struct target *target); char * (*ps_command)(struct target *target);
}; };
struct stack_register_offset {
struct stack_register_offset signed short offset; /* offset in bytes from stack head, or -1 to indicate
{ * register is not stacked, or -2 to indicate this is the
signed short offset; // offset in bytes from stack head, or -1 to indicate register is not stacked, or -2 to indicate this is the stack pointer register * stack pointer register */
unsigned short width_bits; unsigned short width_bits;
}; };
struct rtos_register_stacking struct rtos_register_stacking {
{
unsigned char stack_registers_size; unsigned char stack_registers_size;
signed char stack_growth_direction; signed char stack_growth_direction;
unsigned char num_output_registers; unsigned char num_output_registers;
@ -103,7 +91,10 @@ struct rtos_register_stacking
#define GDB_THREAD_PACKET_NOT_CONSUMED (-40) #define GDB_THREAD_PACKET_NOT_CONSUMED (-40)
int rtos_create(Jim_GetOptInfo *goi, struct target *target); int rtos_create(Jim_GetOptInfo *goi, struct target *target);
int rtos_generic_stack_read( struct target * target, const struct rtos_register_stacking* stacking, int64_t stack_ptr, char ** hex_reg_list ); int rtos_generic_stack_read(struct target *target,
const struct rtos_register_stacking *stacking,
int64_t stack_ptr,
char **hex_reg_list);
int rtos_try_next(struct target *target); int rtos_try_next(struct target *target);
int gdb_thread_packet(struct connection *connection, char *packet, int packet_size); int gdb_thread_packet(struct connection *connection, char *packet, int packet_size);
int rtos_get_gdb_reg_list(struct connection *connection); int rtos_get_gdb_reg_list(struct connection *connection);
@ -113,4 +104,4 @@ int rtos_smp_init(struct target *target);
int rtos_qsymbol(struct connection *connection, char *packet, int packet_size); int rtos_qsymbol(struct connection *connection, char *packet, int packet_size);
int str_to_hex(char *hex_dst, char *src); int str_to_hex(char *hex_dst, char *src);
#endif // RTOS_H #endif /* RTOS_H */

View File

@ -51,14 +51,10 @@ static const struct stack_register_offset rtos_eCos_Cortex_M3_stack_offsets[] =
{ -1, 32 }, /* xPSR */ { -1, 32 }, /* xPSR */
}; };
const struct rtos_register_stacking rtos_eCos_Cortex_M3_stacking = {
const struct rtos_register_stacking rtos_eCos_Cortex_M3_stacking =
{
0x44, /* stack_registers_size */ 0x44, /* stack_registers_size */
-1, /* stack_growth_direction */ -1, /* stack_growth_direction */
26, /* num_output_registers */ 26, /* num_output_registers */
8, /* stack_alignment */ 8, /* stack_alignment */
rtos_eCos_Cortex_M3_stack_offsets /* register_offsets */ rtos_eCos_Cortex_M3_stack_offsets /* register_offsets */
}; };

View File

@ -27,4 +27,4 @@
extern const struct rtos_register_stacking rtos_eCos_Cortex_M3_stacking; extern const struct rtos_register_stacking rtos_eCos_Cortex_M3_stacking;
#endif //ifndef INCLUDED_RTOS_STANDARD_STACKINGS_H_ #endif /* ifndef INCLUDED_RTOS_STANDARD_STACKINGS_H_ */

View File

@ -53,14 +53,10 @@ static const struct stack_register_offset rtos_standard_Cortex_M3_stack_offsets[
{ 0x3c, 32 }, /* xPSR */ { 0x3c, 32 }, /* xPSR */
}; };
const struct rtos_register_stacking rtos_standard_Cortex_M3_stacking = {
const struct rtos_register_stacking rtos_standard_Cortex_M3_stacking =
{
0x40, /* stack_registers_size */ 0x40, /* stack_registers_size */
-1, /* stack_growth_direction */ -1, /* stack_growth_direction */
26, /* num_output_registers */ 26, /* num_output_registers */
8, /* stack_alignment */ 8, /* stack_alignment */
rtos_standard_Cortex_M3_stack_offsets /* register_offsets */ rtos_standard_Cortex_M3_stack_offsets /* register_offsets */
}; };

View File

@ -29,4 +29,4 @@
extern const struct rtos_register_stacking rtos_standard_Cortex_M3_stacking; extern const struct rtos_register_stacking rtos_standard_Cortex_M3_stacking;
#endif //ifndef INCLUDED_RTOS_STANDARD_STACKINGS_H_ #endif /* ifndef INCLUDED_RTOS_STANDARD_STACKINGS_H_ */