Design Article
Migrating ARM7 Code to a Cortex-M3 MCU, Part 2
Todd Hixon
10/30/2009 1:00 AM EDT
In Part 1 in this series, I dealt with the myriad of details relating to exception vector table formating, startup code/stack configuration, remapping RAM functions, and hardware interrupt configuration that a programmer must be concerned with porting code from an existing ARM7 to the Cortex-M3 core. Now in this second part, the tutorial continues with a discussion of software interrupts, fault handling, the SWP command, instruction time, assembly language, and optimizations.
Software interrupts
The ARM7TDMI allows software to generate an exception via the SWI instruction. This exception is typically used as an interface to system drivers or other privileged code that cannot be called directly. An example usage of the ARM-mode version of the SWI instruction is shown below:
swi 0x123456
The ARM7TDMI responds by setting R14 to the instruction after the SWI, disabling IRQ, changing to SVC mode and jumping to the SWI exception table vector. ARM-mode SWI requests can be processed with this basic exception handler:
swi_exception_handler:
stmfd sp!, {r10}
ldr r10, {r14, #-4} ; get the SWI instruction
bic r10, r10, #ff000000 ; get the SWI operand from the instruction
; Code to handle event based on operand in r10
ldmia sp!, {r10, pc}^ ; return from handler
The Cortex-M3 has a similar mechanism using the SVC instruction however the handler is different because the NVIC automatically stacks R0-R3, R12, LR, PC, and PSR. The handler must first determine whether the Main or Process stack was used in order to access the SVC operand and any other parameters that might be passed.
svc_exception_handler:
tst lr, #4
ite eq
mrseq r0, MSP
mrsne r0, PSP
ldr r1, [r0, #24] ; stacked PC
ldrb r1, [r1, #-2] ; get the operand from the SVC instruction
; Code to handle SVC based on operand in r1
bx lr ; return from handler
Another difference in the two software interrupt implementations is that while an SWI exception handler is allowed to invoke another SWI exception, the Cortex-M3 NVIC cannot respond to an exception with the same priority as what is currently executing (attempting to do so will trigger a usage fault).



SPLatMan
11/7/2011 12:41 AM EST
The above code must be untested. Compare and Branch on Non-Zero (cbnz) and Compare and Branch on Zero compare the value in a register with zero, and conditionally branch ***forward*** a constant value.
The sample code expects them to branch backwards.
This just cost us 30 minutes work!
Sign in to Reply