1 /***************************************************************************
3 * This program is free software; you can redistribute it and/or modify *
4 * it under the terms of the GNU General Public License as published by *
5 * the Free Software Foundation; either version 2 of the License, or *
6 * (at your option) any later version. *
8 * This program is distributed in the hope that it will be useful, *
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
11 * GNU General Public License for more details. *
13 * You should have received a copy of the GNU General Public License *
14 * along with this program; if not, write to the *
15 * Free Software Foundation, Inc., *
16 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
17 ***************************************************************************/
23 #include <helper/time_support.h>
24 #include <jtag/jtag.h>
25 #include "target/target.h"
26 #include "target/target_type.h"
28 #include "helper/log.h"
29 #include "rtos_ecos_stackings.h"
31 static int eCos_detect_rtos( struct target
* target
);
32 static int eCos_create( struct target
* target
);
33 static int eCos_update_threads( struct rtos
* rtos
);
34 static int eCos_get_thread_reg_list(struct rtos
*rtos
, int64_t thread_id
, char ** hex_reg_list
);
35 static int eCos_get_symbol_list_to_lookup(symbol_table_elem_t
* symbol_list
[]);
37 struct eCos_thread_state
44 struct eCos_thread_state eCos_thread_states
[] =
54 #define ECOS_NUM_STATES (sizeof(eCos_thread_states)/sizeof(struct eCos_thread_state))
59 unsigned char pointer_width
;
60 unsigned char thread_stack_offset
;
61 unsigned char thread_name_offset
;
62 unsigned char thread_state_offset
;
63 unsigned char thread_next_offset
;
64 unsigned char thread_uniqueid_offset
;
65 const struct rtos_register_stacking
* stacking_info
;
68 const struct eCos_params eCos_params_list
[] =
70 { "cortex_m3", // target_name
72 0x0c, // thread_stack_offset;
73 0x9c, // thread_name_offset;
74 0x3c, // thread_state_offset;
75 0xa0, // thread_next_offset
76 0x4c, // thread_uniqueid_offset
77 &rtos_eCos_Cortex_M3_stacking
// stacking_info
82 #define ECOS_NUM_PARAMS ((int)(sizeof(eCos_params_list)/sizeof(struct eCos_params)))
84 enum eCos_symbol_values
86 eCos_VAL_thread_list
= 0,
87 eCos_VAL_current_thread_ptr
= 1
90 static char* eCos_symbol_list
[] =
92 "Cyg_Thread::thread_list",
93 "Cyg_Scheduler_Base::current_thread",
99 #define ECOS_NUM_SYMBOLS (sizeof(eCos_symbol_list)/sizeof(char*))
102 const struct rtos_type eCos_rtos
=
106 .detect_rtos
= eCos_detect_rtos
,
107 .create
= eCos_create
,
108 .update_threads
= eCos_update_threads
,
109 .get_thread_reg_list
= eCos_get_thread_reg_list
,
110 .get_symbol_list_to_lookup
= eCos_get_symbol_list_to_lookup
,
114 static int eCos_update_threads( struct rtos
* rtos
)
118 int thread_list_size
= 0;
119 const struct eCos_params
* param
;
126 if (rtos
->rtos_specific_params
== NULL
)
131 param
= (const struct eCos_params
*) rtos
->rtos_specific_params
;
133 if ( rtos
->symbols
== NULL
)
135 LOG_OUTPUT("No symbols for eCos\r\n");
139 if ( rtos
->symbols
[eCos_VAL_thread_list
].address
== 0 )
141 LOG_OUTPUT("Don't have the thread list head\r\n");
146 // wipe out previous thread details if any
147 if ( rtos
->thread_details
!= NULL
)
150 for( j
= 0; j
< rtos
->thread_count
; j
++ )
152 if ( rtos
->thread_details
[j
].display_str
!= NULL
)
154 free( rtos
->thread_details
[j
].display_str
);
155 rtos
->thread_details
[j
].display_str
= NULL
;
157 if ( rtos
->thread_details
[j
].thread_name_str
!= NULL
)
159 free( rtos
->thread_details
[j
].thread_name_str
);
160 rtos
->thread_details
[j
].thread_name_str
= NULL
;
162 if ( rtos
->thread_details
[j
].extra_info_str
!= NULL
)
164 free( rtos
->thread_details
[j
].extra_info_str
);
165 rtos
->thread_details
[j
].extra_info_str
= NULL
;
168 free( rtos
->thread_details
);
169 rtos
->thread_details
= NULL
;
173 // determine the number of current threads
174 uint32_t thread_list_head
= rtos
->symbols
[eCos_VAL_thread_list
].address
;
175 uint32_t thread_index
;
176 target_read_buffer( rtos
->target
, thread_list_head
, param
->pointer_width
, (uint8_t *) &thread_index
);
177 uint32_t first_thread
= thread_index
;
181 retval
= target_read_buffer( rtos
->target
, thread_index
+ param
->thread_next_offset
, param
->pointer_width
, (uint8_t *) &thread_index
);
182 if (retval
!= ERROR_OK
)
184 } while( thread_index
!=first_thread
);
186 // read the current thread id
187 uint32_t current_thread_addr
;
188 retval
= target_read_buffer( rtos
->target
, rtos
->symbols
[eCos_VAL_current_thread_ptr
].address
, 4, (uint8_t *)¤t_thread_addr
);
189 if (retval
!= ERROR_OK
)
191 rtos
->current_thread
= 0;
192 retval
= target_read_buffer( rtos
->target
, current_thread_addr
+ param
->thread_uniqueid_offset
, 2, (uint8_t *)&rtos
->current_thread
);
193 if ( retval
!= ERROR_OK
)
195 LOG_OUTPUT("Could not read eCos current thread from target\r\n");
199 if ( ( thread_list_size
== 0 ) || ( rtos
->current_thread
== 0 ) )
201 // Either : No RTOS threads - there is always at least the current execution though
202 // OR : No current thread - all threads suspended - show the current execution of idling
203 char tmp_str
[] = "Current Execution";
206 rtos
->thread_details
= (struct thread_detail
*) malloc( sizeof( struct thread_detail
) * thread_list_size
);
207 rtos
->thread_details
->threadid
= 1;
208 rtos
->thread_details
->exists
= true;
209 rtos
->thread_details
->display_str
= NULL
;
210 rtos
->thread_details
->extra_info_str
= NULL
;
211 rtos
->thread_details
->thread_name_str
= (char*) malloc( sizeof(tmp_str
) );
212 strcpy( rtos
->thread_details
->thread_name_str
, tmp_str
);
215 if ( thread_list_size
== 0 )
217 rtos
->thread_count
= 1;
223 // create space for new thread details
224 rtos
->thread_details
= (struct thread_detail
*) malloc( sizeof( struct thread_detail
) * thread_list_size
);
227 // loop over all threads
228 thread_index
= first_thread
;
232 #define ECOS_THREAD_NAME_STR_SIZE (200)
233 char tmp_str
[ECOS_THREAD_NAME_STR_SIZE
];
235 uint32_t name_ptr
= 0;
236 uint32_t prev_thread_ptr
;
238 // Save the thread pointer
240 retval
= target_read_buffer( rtos
->target
, thread_index
+ param
->thread_uniqueid_offset
, 2, (uint8_t *)&thread_id
);
241 if ( retval
!= ERROR_OK
)
243 LOG_OUTPUT("Could not read eCos thread id from target\r\n");
246 rtos
->thread_details
[tasks_found
].threadid
= thread_id
;
248 // read the name pointer
249 retval
= target_read_buffer( rtos
->target
, thread_index
+ param
->thread_name_offset
, param
->pointer_width
, (uint8_t *)&name_ptr
);
250 if ( retval
!= ERROR_OK
)
252 LOG_OUTPUT("Could not read eCos thread name pointer from target\r\n");
256 // Read the thread name
257 retval
= target_read_buffer( rtos
->target
, name_ptr
, ECOS_THREAD_NAME_STR_SIZE
, (uint8_t *)&tmp_str
);
258 if ( retval
!= ERROR_OK
)
260 LOG_OUTPUT("Error reading thread name from eCos target\r\n");
263 tmp_str
[ECOS_THREAD_NAME_STR_SIZE
-1] = '\x00';
265 if ( tmp_str
[0] == '\x00' )
267 strcpy(tmp_str
,"No Name");
270 rtos
->thread_details
[tasks_found
].thread_name_str
= (char*)malloc( strlen(tmp_str
)+1 );
271 strcpy( rtos
->thread_details
[tasks_found
].thread_name_str
, tmp_str
);
273 // Read the thread status
274 int64_t thread_status
= 0;
275 retval
= target_read_buffer( rtos
->target
, thread_index
+ param
->thread_state_offset
, 4, (uint8_t *)&thread_status
);
276 if ( retval
!= ERROR_OK
)
278 LOG_OUTPUT("Error reading thread state from eCos target\r\n");
282 for( i
= 0; (i
< ECOS_NUM_STATES
) && (eCos_thread_states
[i
].value
!=thread_status
); i
++ )
287 if (i
< ECOS_NUM_STATES
)
289 state_desc
= eCos_thread_states
[i
].desc
;
293 state_desc
= "Unknown state";
296 rtos
->thread_details
[tasks_found
].extra_info_str
= (char*)malloc( strlen(state_desc
)+1 );
297 strcpy( rtos
->thread_details
[tasks_found
].extra_info_str
, state_desc
);
299 rtos
->thread_details
[tasks_found
].exists
= true;
301 rtos
->thread_details
[tasks_found
].display_str
= NULL
;
305 prev_thread_ptr
= thread_index
;
307 // Get the location of the next thread structure.
308 thread_index
= rtos
->symbols
[eCos_VAL_thread_list
].address
;
309 retval
= target_read_buffer( rtos
->target
, prev_thread_ptr
+ param
->thread_next_offset
, param
->pointer_width
, (uint8_t *) &thread_index
);
310 if ( retval
!= ERROR_OK
)
312 LOG_OUTPUT("Error reading next thread pointer in eCos thread list\r\n");
316 while( thread_index
!=first_thread
);
318 rtos
->thread_count
= tasks_found
;
322 static int eCos_get_thread_reg_list(struct rtos
*rtos
, int64_t thread_id
, char ** hex_reg_list
)
326 const struct eCos_params
* param
;
328 *hex_reg_list
= NULL
;
335 if ( thread_id
== 0 )
340 if (rtos
->rtos_specific_params
== NULL
)
345 param
= (const struct eCos_params
*) rtos
->rtos_specific_params
;
348 // Find the thread with that thread id
350 uint32_t thread_list_head
= rtos
->symbols
[eCos_VAL_thread_list
].address
;
351 uint32_t thread_index
;
352 target_read_buffer( rtos
->target
, thread_list_head
, param
->pointer_width
, (uint8_t *) &thread_index
);
356 retval
= target_read_buffer( rtos
->target
, thread_index
+ param
->thread_uniqueid_offset
, 2, (uint8_t*)&id
);
357 if ( retval
!= ERROR_OK
)
359 LOG_OUTPUT("Error reading unique id from eCos thread\r\n");
368 target_read_buffer( rtos
->target
, thread_index
+ param
->thread_next_offset
, param
->pointer_width
, (uint8_t *) &thread_index
);
373 // Read the stack pointer
374 int64_t stack_ptr
= 0;
375 retval
= target_read_buffer( rtos
->target
, thread_index
+ param
->thread_stack_offset
, param
->pointer_width
, (uint8_t*)&stack_ptr
);
376 if ( retval
!= ERROR_OK
)
378 LOG_OUTPUT("Error reading stack frame from eCos thread\r\n");
382 return rtos_generic_stack_read( rtos
->target
, param
->stacking_info
, stack_ptr
, hex_reg_list
);
390 static int eCos_get_symbol_list_to_lookup(symbol_table_elem_t
* symbol_list
[])
393 *symbol_list
= (symbol_table_elem_t
*) malloc( sizeof( symbol_table_elem_t
) * ECOS_NUM_SYMBOLS
);
395 for( i
= 0; i
< ECOS_NUM_SYMBOLS
; i
++ )
397 (*symbol_list
)[i
].symbol_name
= eCos_symbol_list
[i
];
403 static int eCos_detect_rtos( struct target
* target
)
405 if ( ( target
->rtos
->symbols
!= NULL
) &&
406 ( target
->rtos
->symbols
[eCos_VAL_thread_list
].address
!= 0 ) )
414 static int eCos_create( struct target
* target
)
417 while ( ( i
< ECOS_NUM_PARAMS
) && ( 0 != strcmp( eCos_params_list
[i
].target_name
, target
->type
->name
) ) )
421 if ( i
>= ECOS_NUM_PARAMS
)
423 LOG_OUTPUT("Could not find target in eCos compatibility list\r\n");
427 target
->rtos
->rtos_specific_params
= (void*) &eCos_params_list
[i
];
428 target
->rtos
->current_thread
= 0;
429 target
->rtos
->thread_details
= NULL
;
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)