| |||
Home > Semihosting > Adding an application SWI handler > Multi-ICE |
To ensure that the application SWI handler will successfully cooperate with Multi-ICE semihosting mechanism:
Install the application SWI handler into the vector table.
Modify $semihosting_vector
to
point to a location at the end of the application handler. This
point in the handler must only be reached if your handler does not handle
the SWI.
Before Multi-ICE traps the SWI, your SWI handler must restore all registers to the values they had when your SWI handler was entered. Typically, this means that your SWI handler must store the registers to a stack on entry and restore them before falling through to the semihosting vector address.
It is essential that the actual position $semihosting_vector
points
to within the application handler is correct.
See exception handling in the ADS Developer Guide for writing SWI handlers.
The following example SWI handler can detect if it fails to handle a SWI. In this case, it branches to an error handler:
; r0 = 1 if SWI handled CMP r0, #1 ; Test if SWI has been handled. BNE NoSuchSWI ; Call unknown SWI handler. LDMFD sp!, {r0} ; Unstack SPSR... MSR spsr_cxsf, r0 ; ...and restore it. LDMFD sp!, {r0-r12,pc}^ ; Restore registers and return.
This code could be modified to co-operate with Multi-ICE semihosting as follows:
; r0 = 1 if SWI handled CMP r0, #1 ; Test if SWI has been handled. LDMFD sp!, {r0} ; Unstack SPSR... MSR spsr_cxsf, r0 ; ...and restore it. LDMFD sp!, {r0-r12,lr} ; Restore registers. MOVEQS pc, lr ; Return if SWI handled. Semi_SWI MOVS pc,lr ; Fall through to Multi-ICE ; interface handler.
The $semihosting_vector
variable must be
set up to point to the address of Semi_SWI
. The instruction
at Semi_SWI
never gets executed because Multi-ICE
returns directly to the application after processing the semihosted
SWI (see Figure 5.2).
Using a normal SWI return instruction ensures that the application does not crash if the semihosting breakpoint is not set up. The semihosting action requested is not carried out and the handler simply returns.
You must also be careful if you modify $semihosting_vector
to
point to the fall-through part of the application SWI handler. If $semihosting_vector
changes
value before the application starts execution, and semihosted SWIs
are invoked before the application SWI handler is installed, an
unknown watchpoint error will occur.
The error occurs because the vector table location for the
SWI has not yet had the application handler installed into it and
might still contain the software breakpoint bit pattern. Because
the $semihosting_vector
address has moved to
a place that cannot currently be reached, Multi-ICE no longer knows
about the triggered breakpoint. To prevent this from happening,
you must change the contents of $semihosting_vector
only at
the point in your code where the application SWI handler is installed
into the vector table.
If semihosting is not required at all by an application, this
process can be simplified by setting $semihosting_enabled
to
0.