|Home > Using the CADI Interface Methods from a Debugger > Execution control > Execution mode control|
This section describes how to control the execution mode.
To provide fully controlled debugging of the target, the attached debugger must be able to control the execution of the target.
CADI provides this capability with a set of method calls that can
determine the current state of the target and initiate state changes such as stopping or
running. This target execution control is closely coupled to
The mode, that is, the state of the target, can be explicitly requested by
CADIExecGetMode(). This might be useful to, for
example, connect to an existing simulation.
ARM does not recommend polling of the target state, however. The
modeChange() callback of
must be implemented by the caller to eliminate the requirement for such polling calls
and prevent blocking the interface. The returned mode is of type
CADI_EXECMODE_t. The returned state is either
CADI_EXECMODE_Bptas the target state from
CADIExecSetMode() is the counterpart to
CADIExecGetMode(). It receives a 32-bit unsigned
integer as parameter. The provided value is typically of type
CADI_EXECMODE_t which is a 32-bit unsigned integer. The intended use is to
CADI_EXECMODE_Stop to the target.
CADIExecSetMode()to set the target state to
// very basic example of debugger accessing registers in connected target // cadi is a connected simulation object of type CADI cout << "Client: Invoking target->CADIExecSetMode(3)" << endl; cadi->CADIExecSetMode(3); cout << "Client: Invoking target->CADIExecGetMode()" << endl; uint32_t execMode; cadi->CADIExecGetMode(&execMode); cout << "Client: Target's current mode is: " << execMode << endl;
For a subset of execution modes, the dedicated methods are preferable.
CADIExecContinue() to start or continue
the execution of a target component. This asynchronous call immediately
returns after triggering the target, so the execution might not
start immediately. The registered callback object (from the caller)
is responsible for indicating the actual beginning of the target
execution by issuing a
CADIExecContinue() is called and the
target is running (
CADI_EXECMODE_Run), the target
must ignore the call and return
CADIExecStop() to stop a running
simulation. This method returns immediately and the target is not
typically stopped when the call returns. The caller must wait for
modeChange() callback that indicates
CADIExecStop() is called and the target
is already stopped (
call must be ignored by the target and return
In general, clients must expect that mode changes can occur asynchronously. If for example an asynchronous mode change occurred during the execution of:
if (t->CADIExecGetMode()==CADI_EXECMODE_Stop) t->CADIExecContinue()
the second call might return
the client receives a
modeChange message on the
callback thread. The client must handle all possible outcomes of
this race condition.
In addition to the ability to run the target until the next breakpoint or the end of simulation, you can use
CADIExecSingleStep() to step the target component for one or more steps.
Target steps can be specified as either cycle steps or instruction steps. That is, the target is either stepped for a specific number of clock cycles or stepped until the corresponding instructions are completely finished.
stepOver parameter of
stepping over call instructions. This is primarily intended for
use with source level debugging where some methods or function calls must
not be stepped through.
The method is asynchronous and the call returns immediately
and typically before the instructions have been finished. A sequence
CADI_EXECMODE_Stop are issued
to inform the caller about the progress of the execution.
CADIExecSingleStep() is called and
the target is running, the call must be ignored and
A CADI reset is intended to bring a simulation platform, or one of its components, back into a specific state.
This simulation reset must be distinguished from a real hardware reset because it might perform, for example, certain initialization steps that real hardware does not do.
CADI resets are identified by their reset level and a name. The corresponding reset level numbers must be used uniquely within a target. There must not be two different resets defined to be of the same reset level.
CADI permits free definition of its simulation reset levels. Each associated reset can differ in the addressed components or resources. One reset might, for example, only initialize the core registers in a processor, but another reset might modify both the core registers and memory in the target.
CADI reserves reset 0 as a Hard Reset and explicitly specifies the semantics of this reset. All other reset levels, however, can be customized and might differ from model to model. Reset level numbers can be chosen arbitrarily and have no other meaning than representing a certain simulation reset. There is, for example, no ordering of reset levels by their severity.
Because CADI reset 0, the Hard Reset, has fixed semantics, it must be implemented by every model providing a CADI implementation. This Hard Reset resets all state variables of a model including those that would not be modified by a real hardware reset. After the reset, the simulation platform must be in the same state as it was immediately after instantiating it. The corresponding initialization values must be well-defined and must not be chosen randomly. This guarantees that a simulation run with the same loaded application is reproducible after a hard reset.
CADIExecReset()for any reset level must not touch any set breakpoint or unregister any registered callback object.
A call to
CADIExecReset(0) must trigger
this behavior of the target:
CADIExecReset(0), it is
the responsibility of the calling debugger to reload applications
if that is required.
To determine the supported resets for a target, call the
which provides a list with the corresponding identifiers. The contained
reset level number must be forwarded to
trigger the required reset.
CADIExecReset() is an asynchronous call and can therefore return before the actual reset of the target has finished.
After the target has ended all required actions, the simulation thread sends out
modeChange(CADI_EXECMODE_ResetDone) callback to all registered debuggers. Because
a target can only accept one CADI reset at a time, the calling debugger can depend on the
receiving the end notification for its
CADIExecReset() call and then
proceed with other required functionality such as loading applications to the target.
is identical to the legacy
Targets must support both callbacks to maintain backwards compatibility.
ARM recommends using
modeChange(CADI_EXECMODE_ResetDone) in client code because
a future version of CADI is to deprecate the
CADICallbackObj class is an important part of the mechanism for controlling target execution. Unlike the interface calls of the
CADI class that initiates behavior changes in the target, the callback mechanism reports changes in the target state back to the caller.
Some callback calls are optional and are not required for the execution control. These include:
Callbacks in CADI are asynchronous and can be received even
if a debugger has not triggered any behavior. This is required to
enable connection of multiple debuggers to a single target. If for
example one debugger requests a running target to stop, all connected
debuggers receive a
that instructs the debuggers to change their state and to update
the target views.
CADICallbackObjmust only be called from the simulation thread. The associated debugger thread must not, either directly or indirectly, call a callback of this class.
The most important, and almost mandatory, callback for execution
control is the
modeChange() method. It reports
any change of the state of the target state or if a breakpoint is
modeChange() receives the execution mode
and, if required, the breakpoint ID. The typical execution modes
modeChange() callback is only
permitted if the state changed and the new state has been reached.
For example, a change to
only be issued if the target was previously in another state, typically
and the target is now in the stopped state and has finished ALL
implied updates of target resources.
A change to
an additional breakpoint ID to inform the caller that the breakpoint
has been hit. In all other cases, this parameter has to be set to
zero which indicates an invalid breakpoint ID.
A mode change to
be issued for every hit breakpoint. If multiple breakpoints triggered
at the time, each of them must be reported by dedicated calls. This
might be the case if, for example, a register breakpoint and a program breakpoint
are hit simultaneously. Both must be reported to enable the caller
to react properly to the two events.
A mode change to
CADI_EXECMODE_ResetDone indicates the end of a CADI reset
and the debugger must update all its views. The debugger might also take additional actions
if the debugger was responsible for the reset, to control the execution mode. The caller
might expect characteristic sequences of
modeChange() callbacks in response
to a specific requested functionality.
Table 3-2 Typical modeChange() callback responses
|Target state||Called interface method||Expected modeChange() sequence|
modeChange(CADI_EXECMODE_Run, 0) modeChange(CADI_EXECMODE_Stop, 0)
Debugger has set a program breakpoint (ID=1) to be hit.
modeChange(CADI_EXECMODE_Run, 0) modeChange(CADI_EXECMODE_Bpt, 1) modeChange(CADI_EXECMODE_Stop, 0)
Debugger has set a program breakpoint (ID=1) on the next instruction and a memory breakpoint (ID =2) on an address is modified after finishing the current instruction.
modeChange(CADI_EXECMODE_Run, 0) modeChange(CADI_EXECMODE_Bpt, 1) modeChange(CADI_EXECMODE_Bpt, 2) modeChange(CADI_EXECMODE_Stop, 0)
Debugger has set a breakpoint (ID=1)
modeChange(CADI_EXECMODE_Run, 0) modeChange(CADI_EXECMODE_Bpt, 1)