Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
card10
openocd
Commits
e2b6de3d
Commit
e2b6de3d
authored
Jul 28, 2008
by
oharboe
Browse files
retired reset run_and_init/halt
git-svn-id:
svn://svn.berlios.de/openocd/trunk@877
b42882b7-edfa-0310-969c-e2dbd0fdcd60
parent
9244c600
Changes
38
Hide whitespace changes
Inline
Side-by-side
doc/openocd.texi
View file @
e2b6de3d
...
...
@@ -540,11 +540,6 @@ Event is one of the following:
@option
{
pre
_
resume
}
or @option
{
gdb
_
program
_
config
}
.
@option
{
post
_
reset
}
and @option
{
reset
}
will produce the same results.
@item @b
{
run
_
and
_
halt
_
time
}
<@var
{
target#
}
> <@var
{
time
_
in
_
ms
}
>
@cindex run
_
and
_
halt
_
time
The amount of time the debugger should wait after releasing reset before it asserts
a debug request. This is used by the @option
{
run
_
and
_
halt
}
and @option
{
run
_
and
_
init
}
reset modes.
@item @b
{
working
_
area
}
<@var
{
target#
}
> <@var
{
address
}
> <@var
{
size
}
>
<@var
{
backup
}
|@var
{
nobackup
}
>
@cindex working
_
area
...
...
@@ -795,8 +790,7 @@ OpenOCD will wait 5 seconds for the target to resume.
@cindex step
Single
-
step the target at its current code position, or at an optional address.
@item @b
{
reset
}
[
@option
{
run
}
|@option
{
halt
}
|@option
{
init
}
|@option
{
run
_
and
_
halt
}
|@option
{
run
_
and
_
init
}
]
@item @b
{
reset
}
[
@option
{
run
}
|@option
{
halt
}
|@option
{
init
}
]
@cindex reset
Perform a hard
-
reset. The optional parameter specifies what should happen after the reset.
...
...
@@ -812,15 +806,7 @@ Immediately halt the target (works only with certain configurations).
@cindex reset init
Immediately halt the target, and execute the reset script
(
works only with certain
configurations
)
@item @b
{
run
_
and
_
halt
}
@cindex reset run
_
and
_
halt
Let the target run for a certain amount of time, then request a halt.
@item @b
{
run
_
and
_
init
}
@cindex reset run
_
and
_
init
Let the target run for a certain amount of time, then request a halt. Execute the
reset script once the target enters debug mode.
@end itemize
The runtime can be set using the @option
{
run
_
and
_
halt
_
time
}
command.
@end itemize
@subsection Memory access commands
...
...
src/target/target.c
View file @
e2b6de3d
...
...
@@ -55,7 +55,6 @@ int cli_target_callback_event_handler(struct target_s *target, enum target_event
int
handle_target_command
(
struct
command_context_s
*
cmd_ctx
,
char
*
cmd
,
char
**
args
,
int
argc
);
int
handle_targets_command
(
struct
command_context_s
*
cmd_ctx
,
char
*
cmd
,
char
**
args
,
int
argc
);
int
handle_run_and_halt_time_command
(
struct
command_context_s
*
cmd_ctx
,
char
*
cmd
,
char
**
args
,
int
argc
);
int
handle_working_area_command
(
struct
command_context_s
*
cmd_ctx
,
char
*
cmd
,
char
**
args
,
int
argc
);
int
handle_reg_command
(
struct
command_context_s
*
cmd_ctx
,
char
*
cmd
,
char
**
args
,
int
argc
);
...
...
@@ -194,8 +193,8 @@ target_t* get_target_by_num(int num)
int
get_num_by_target
(
target_t
*
query_target
)
{
target_t
*
target
=
targets
;
int
i
=
0
;
int
i
=
0
;
while
(
target
)
{
if
(
target
==
query_target
)
...
...
@@ -203,48 +202,23 @@ int get_num_by_target(target_t *query_target)
target
=
target
->
next
;
i
++
;
}
return
-
1
;
}
target_t
*
get_current_target
(
command_context_t
*
cmd_ctx
)
{
target_t
*
target
=
get_target_by_num
(
cmd_ctx
->
current_target
);
if
(
target
==
NULL
)
{
LOG_ERROR
(
"BUG: current_target out of bounds"
);
exit
(
-
1
);
}
return
target
;
}
/* Process target initialization, when target entered debug out of reset
* the handler is unregistered at the end of this function, so it's only called once
*/
int
target_init_handler
(
struct
target_s
*
target
,
enum
target_event
event
,
void
*
priv
)
{
struct
command_context_s
*
cmd_ctx
=
priv
;
if
(
event
==
TARGET_EVENT_HALTED
)
{
target_unregister_event_callback
(
target_init_handler
,
priv
);
target_invoke_script
(
cmd_ctx
,
target
,
"post_reset"
);
jtag_execute_queue
();
}
return
ERROR_OK
;
return
target
;
}
int
target_run_and_halt_handler
(
void
*
priv
)
{
target_t
*
target
=
priv
;
target_halt
(
target
);
return
ERROR_OK
;
}
int
target_poll
(
struct
target_s
*
target
)
{
...
...
@@ -271,21 +245,21 @@ int target_halt(struct target_s *target)
int
target_resume
(
struct
target_s
*
target
,
int
current
,
u32
address
,
int
handle_breakpoints
,
int
debug_execution
)
{
int
retval
;
/* We can't poll until after examine */
if
(
!
target
->
type
->
examined
)
{
LOG_ERROR
(
"Target not examined yet"
);
return
ERROR_FAIL
;
}
/* note that resume *must* be asynchronous. The CPU can halt before we poll. The CPU can
* even halt at the current PC as a result of a software breakpoint being inserted by (a bug?)
* the application.
*/
if
((
retval
=
target
->
type
->
resume
(
target
,
current
,
address
,
handle_breakpoints
,
debug_execution
))
!=
ERROR_OK
)
return
retval
;
return
retval
;
}
...
...
@@ -301,27 +275,27 @@ int target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mo
target_invoke_script
(
cmd_ctx
,
target
,
"pre_reset"
);
target
=
target
->
next
;
}
if
((
retval
=
jtag_init_reset
(
cmd_ctx
))
!=
ERROR_OK
)
return
retval
;
keep_alive
();
/* we might be running on a very slow JTAG clk */
/* First time this is executed after launching OpenOCD, it will read out
/* First time this is executed after launching OpenOCD, it will read out
* the type of CPU, etc. and init Embedded ICE registers in host
* memory.
*
* memory.
*
* It will also set up ICE registers in the target.
*
* However, if we assert TRST later, we need to set up the registers again.
*
*
* However, if we assert TRST later, we need to set up the registers again.
*
* For the "reset halt/init" case we must only set up the registers here.
*/
if
((
retval
=
target_examine
(
cmd_ctx
))
!=
ERROR_OK
)
return
retval
;
keep_alive
();
/* we might be running on a very slow JTAG clk */
target
=
targets
;
while
(
target
)
{
...
...
@@ -338,46 +312,25 @@ int target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mo
LOG_WARNING
(
"JTAG communication failed asserting reset."
);
retval
=
ERROR_OK
;
}
/* request target halt if necessary, and schedule further action */
target
=
targets
;
while
(
target
)
{
switch
(
reset_mode
)
if
(
reset_mode
!=
RESET_RUN
)
{
case
RESET_RUN
:
/* nothing to do if target just wants to be run */
break
;
case
RESET_RUN_AND_HALT
:
/* schedule halt */
target_register_timer_callback
(
target_run_and_halt_handler
,
target
->
run_and_halt_time
,
0
,
target
);
break
;
case
RESET_RUN_AND_INIT
:
/* schedule halt */
target_register_timer_callback
(
target_run_and_halt_handler
,
target
->
run_and_halt_time
,
0
,
target
);
target_register_event_callback
(
target_init_handler
,
cmd_ctx
);
break
;
case
RESET_HALT
:
if
((
jtag_reset_config
&
RESET_SRST_PULLS_TRST
)
==
0
)
target_halt
(
target
);
break
;
case
RESET_INIT
:
if
((
jtag_reset_config
&
RESET_SRST_PULLS_TRST
)
==
0
)
target_halt
(
target
);
target_register_event_callback
(
target_init_handler
,
cmd_ctx
);
break
;
default:
LOG_ERROR
(
"BUG: unknown target->reset_mode"
);
if
((
jtag_reset_config
&
RESET_SRST_PULLS_TRST
)
==
0
)
target_halt
(
target
);
}
target
=
target
->
next
;
}
if
((
retval
=
jtag_execute_queue
())
!=
ERROR_OK
)
{
LOG_WARNING
(
"JTAG communication failed while reset was asserted. Consider using srst_only for reset_config."
);
retval
=
ERROR_OK
;
retval
=
ERROR_OK
;
}
target
=
targets
;
while
(
target
)
{
...
...
@@ -389,10 +342,10 @@ int target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mo
LOG_WARNING
(
"Failed to reset target into halted mode - issuing halt"
);
target
->
type
->
halt
(
target
);
}
target
=
target
->
next
;
}
if
((
retval
=
jtag_execute_queue
())
!=
ERROR_OK
)
{
LOG_WARNING
(
"JTAG communication failed while deasserting reset."
);
...
...
@@ -404,64 +357,23 @@ int target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mo
/* If TRST was asserted we need to set up registers again */
if
((
retval
=
target_examine
(
cmd_ctx
))
!=
ERROR_OK
)
return
retval
;
}
}
LOG_DEBUG
(
"Waiting for halted stated as appropriate"
);
/* Wait for reset to complete, maximum 5 seconds. */
gettimeofday
(
&
timeout
,
NULL
);
timeval_add_time
(
&
timeout
,
5
,
0
);
for
(;;)
if
((
reset_mode
==
RESET_HALT
)
||
(
reset_mode
==
RESET_INIT
))
{
gettimeofday
(
&
now
,
NULL
);
target_call_timer_callbacks_now
();
target
=
targets
;
while
(
target
)
/* Wait for reset to complete, maximum 5 seconds. */
if
(((
retval
=
target_wait_state
(
target
,
TARGET_HALTED
,
5000
)))
==
ERROR_OK
)
{
LOG_DEBUG
(
"Polling target"
);
target_poll
(
target
);
if
((
reset_mode
==
RESET_RUN_AND_INIT
)
||
(
reset_mode
==
RESET_RUN_AND_HALT
)
||
(
reset_mode
==
RESET_HALT
)
||
(
reset_mode
==
RESET_INIT
))
{
if
(
target
->
state
!=
TARGET_HALTED
)
{
if
((
now
.
tv_sec
>
timeout
.
tv_sec
)
||
((
now
.
tv_sec
==
timeout
.
tv_sec
)
&&
(
now
.
tv_usec
>=
timeout
.
tv_usec
)))
{
LOG_USER
(
"Timed out waiting for halt after reset"
);
goto
done
;
}
/* this will send alive messages on e.g. GDB remote protocol. */
usleep
(
500
*
1000
);
LOG_USER_N
(
"%s"
,
""
);
/* avoid warning about zero length formatting message*/
goto
again
;
}
}
target
=
target
->
next
;
if
(
reset_mode
==
RESET_INIT
)
target_invoke_script
(
cmd_ctx
,
target
,
"post_reset"
);
}
/* All targets we're waiting for are halted */
break
;
again:
;
}
done:
/* We want any events to be processed before the prompt */
target_call_timer_callbacks_now
();
/* if we timed out we need to unregister these handlers */
target
=
targets
;
while
(
target
)
{
target_unregister_timer_callback
(
target_run_and_halt_handler
,
target
);
target
=
target
->
next
;
}
target_unregister_event_callback
(
target_init_handler
,
cmd_ctx
);
return
retval
;
}
...
...
@@ -486,8 +398,8 @@ static int default_examine(struct command_context_s *cmd_ctx, struct target_s *t
/* Targets that correctly implement init+examine, i.e.
* no communication with target during init:
*
* XScale
*
* XScale
*/
int
target_examine
(
struct
command_context_s
*
cmd_ctx
)
{
...
...
@@ -545,7 +457,7 @@ static int target_run_algorithm_imp(struct target_s *target, int num_mem_params,
int
target_init
(
struct
command_context_s
*
cmd_ctx
)
{
target_t
*
target
=
targets
;
while
(
target
)
{
target
->
type
->
examined
=
0
;
...
...
@@ -553,13 +465,13 @@ int target_init(struct command_context_s *cmd_ctx)
{
target
->
type
->
examine
=
default_examine
;
}
if
(
target
->
type
->
init_target
(
cmd_ctx
,
target
)
!=
ERROR_OK
)
{
LOG_ERROR
(
"target '%s' init failed"
,
target
->
type
->
name
);
exit
(
-
1
);
}
/* Set up default functions if none are provided by target */
if
(
target
->
type
->
virt2phys
==
NULL
)
{
...
...
@@ -578,44 +490,44 @@ int target_init(struct command_context_s *cmd_ctx)
target
->
type
->
run_algorithm_imp
=
target
->
type
->
run_algorithm
;
target
->
type
->
run_algorithm
=
target_run_algorithm_imp
;
if
(
target
->
type
->
mmu
==
NULL
)
{
target
->
type
->
mmu
=
default_mmu
;
}
target
=
target
->
next
;
}
if
(
targets
)
{
target_register_user_commands
(
cmd_ctx
);
target_register_timer_callback
(
handle_target
,
100
,
1
,
NULL
);
}
return
ERROR_OK
;
}
int
target_register_event_callback
(
int
(
*
callback
)(
struct
target_s
*
target
,
enum
target_event
event
,
void
*
priv
),
void
*
priv
)
{
target_event_callback_t
**
callbacks_p
=
&
target_event_callbacks
;
if
(
callback
==
NULL
)
{
return
ERROR_INVALID_ARGUMENTS
;
}
if
(
*
callbacks_p
)
{
while
((
*
callbacks_p
)
->
next
)
callbacks_p
=
&
((
*
callbacks_p
)
->
next
);
callbacks_p
=
&
((
*
callbacks_p
)
->
next
);
}
(
*
callbacks_p
)
=
malloc
(
sizeof
(
target_event_callback_t
));
(
*
callbacks_p
)
->
callback
=
callback
;
(
*
callbacks_p
)
->
priv
=
priv
;
(
*
callbacks_p
)
->
next
=
NULL
;
return
ERROR_OK
;
}
...
...
@@ -623,24 +535,24 @@ int target_register_timer_callback(int (*callback)(void *priv), int time_ms, int
{
target_timer_callback_t
**
callbacks_p
=
&
target_timer_callbacks
;
struct
timeval
now
;
if
(
callback
==
NULL
)
{
return
ERROR_INVALID_ARGUMENTS
;
}
if
(
*
callbacks_p
)
{
while
((
*
callbacks_p
)
->
next
)
callbacks_p
=
&
((
*
callbacks_p
)
->
next
);
callbacks_p
=
&
((
*
callbacks_p
)
->
next
);
}
(
*
callbacks_p
)
=
malloc
(
sizeof
(
target_timer_callback_t
));
(
*
callbacks_p
)
->
callback
=
callback
;
(
*
callbacks_p
)
->
periodic
=
periodic
;
(
*
callbacks_p
)
->
time_ms
=
time_ms
;
gettimeofday
(
&
now
,
NULL
);
(
*
callbacks_p
)
->
when
.
tv_usec
=
now
.
tv_usec
+
(
time_ms
%
1000
)
*
1000
;
time_ms
-=
(
time_ms
%
1000
);
...
...
@@ -650,10 +562,10 @@ int target_register_timer_callback(int (*callback)(void *priv), int time_ms, int
(
*
callbacks_p
)
->
when
.
tv_usec
=
(
*
callbacks_p
)
->
when
.
tv_usec
-
1000000
;
(
*
callbacks_p
)
->
when
.
tv_sec
+=
1
;
}
(
*
callbacks_p
)
->
priv
=
priv
;
(
*
callbacks_p
)
->
next
=
NULL
;
return
ERROR_OK
;
}
...
...
@@ -661,12 +573,12 @@ int target_unregister_event_callback(int (*callback)(struct target_s *target, en
{
target_event_callback_t
**
p
=
&
target_event_callbacks
;
target_event_callback_t
*
c
=
target_event_callbacks
;
if
(
callback
==
NULL
)
{
return
ERROR_INVALID_ARGUMENTS
;
}
while
(
c
)
{
target_event_callback_t
*
next
=
c
->
next
;
...
...
@@ -680,7 +592,7 @@ int target_unregister_event_callback(int (*callback)(struct target_s *target, en
p
=
&
(
c
->
next
);
c
=
next
;
}
return
ERROR_OK
;
}
...
...
@@ -688,12 +600,12 @@ int target_unregister_timer_callback(int (*callback)(void *priv), void *priv)
{
target_timer_callback_t
**
p
=
&
target_timer_callbacks
;
target_timer_callback_t
*
c
=
target_timer_callbacks
;
if
(
callback
==
NULL
)
{
return
ERROR_INVALID_ARGUMENTS
;
}
while
(
c
)
{
target_timer_callback_t
*
next
=
c
->
next
;
...
...
@@ -707,7 +619,7 @@ int target_unregister_timer_callback(int (*callback)(void *priv), void *priv)
p
=
&
(
c
->
next
);
c
=
next
;
}
return
ERROR_OK
;
}
...
...
@@ -715,16 +627,16 @@ int target_call_event_callbacks(target_t *target, enum target_event event)
{
target_event_callback_t
*
callback
=
target_event_callbacks
;
target_event_callback_t
*
next_callback
;
LOG_DEBUG
(
"target event %i"
,
event
);
while
(
callback
)
{
next_callback
=
callback
->
next
;
callback
->
callback
(
target
,
event
,
callback
->
priv
);
callback
=
next_callback
;
}
return
ERROR_OK
;
}
...
...
@@ -735,13 +647,13 @@ static int target_call_timer_callbacks_check_time(int checktime)
struct
timeval
now
;
keep_alive
();
gettimeofday
(
&
now
,
NULL
);
while
(
callback
)
{
next_callback
=
callback
->
next
;
if
((
!
checktime
&&
callback
->
periodic
)
||
(((
now
.
tv_sec
>=
callback
->
when
.
tv_sec
)
&&
(
now
.
tv_usec
>=
callback
->
when
.
tv_usec
))
||
(
now
.
tv_sec
>
callback
->
when
.
tv_sec
)))
...
...
@@ -765,10 +677,10 @@ static int target_call_timer_callbacks_check_time(int checktime)
target_unregister_timer_callback
(
callback
->
callback
,
callback
->
priv
);
}
}
callback
=
next_callback
;
}
return
ERROR_OK
;
}
...
...
@@ -787,7 +699,7 @@ int target_alloc_working_area(struct target_s *target, u32 size, working_area_t
{
working_area_t
*
c
=
target
->
working_areas
;
working_area_t
*
new_wa
=
NULL
;
/* Reevaluate working area address based on MMU state*/
if
(
target
->
working_areas
==
NULL
)
{
...
...
@@ -807,14 +719,14 @@ int target_alloc_working_area(struct target_s *target, u32 size, working_area_t
target
->
working_area
=
target
->
working_area_phys
;
}
}
/* only allocate multiples of 4 byte */
if
(
size
%
4
)
{
LOG_ERROR
(
"BUG: code tried to allocate unaligned number of bytes, padding"
);
size
=
CEIL
(
size
,
4
);
}
/* see if there's already a matching working area */
while
(
c
)
{
...
...
@@ -825,16 +737,16 @@ int target_alloc_working_area(struct target_s *target, u32 size, working_area_t
}
c
=
c
->
next
;
}
/* if not, allocate a new one */
if
(
!
new_wa
)
{
working_area_t
**
p
=
&
target
->
working_areas
;
u32
first_free
=
target
->
working_area
;
u32
free_size
=
target
->
working_area_size
;
LOG_DEBUG
(
"allocating new working area"
);
c
=
target
->
working_areas
;
while
(
c
)
{
...
...
@@ -843,18 +755,18 @@ int target_alloc_working_area(struct target_s *target, u32 size, working_area_t
p
=
&
c
->
next
;
c
=
c
->
next
;
}
if
(
free_size
<
size
)
{
LOG_WARNING
(
"not enough working area available(requested %d, free %d)"
,
size
,
free_size
);
return
ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
}
new_wa
=
malloc
(
sizeof
(
working_area_t
));
new_wa
->
next
=
NULL
;
new_wa
->
size
=
size
;
new_wa
->
address
=
first_free
;
if
(
target
->
backup_working_area
)
{
new_wa
->
backup
=
malloc
(
new_wa
->
size
);
...
...
@@ -864,18 +776,18 @@ int target_alloc_working_area(struct target_s *target, u32 size, working_area_t
{
new_wa
->
backup
=
NULL
;
}
/* put new entry in list */
*
p
=
new_wa
;
}
/* mark as used, and return the new (reused) area */
new_wa
->
free
=
0
;
*
area
=
new_wa
;
/* user pointer */
new_wa
->
user
=
area
;
return
ERROR_OK
;
}
...
...
@@ -883,16 +795,16 @@ int target_free_working_area_restore(struct target_s *target, working_area_t *ar
{
if
(
area
->
free
)
return
ERROR_OK
;
if
(
restore
&&
target
->
backup_working_area
)
target
->
type
->
write_memory
(
target
,
area
->
address
,
4
,
area
->
size
/
4
,
area
->
backup
);
area
->
free
=
1
;
/* mark user pointer invalid */
*
area
->
user
=
NULL
;
area
->
user
=
NULL
;
return
ERROR_OK
;