2013-09-27 08:34 AM
I have a really baffling problem. Perhaps it is not even a problem. It's just something I noticed when debugging my program. Register 3 goes to it's reset value when I return from an interrupt service routine. I am pushing r0-r2 and later popping them, and am returning by using the bx lr command. On this last command, bx lr, return to before interrupt flag, r3 is reset.
Is it supposed to do this? I don't want to avoid using register 3 through all my program, just in case an interrupt occurs and it gets reset. Example code follows. @@@ Directives .thumb @ (same as saying '.code 16') .syntax unified @@@ Equates .equ STACKINIT, 0x20005000 .equ NVIC_ISER1, 0xE000E104 @ This register is used to enable the global ethernet interrupt .equ NVIC_ISPR1, 0xE000E204 @ This register is used to enable the global ethernet interrupt .section .text .org 0 @@@ Vectors vectors: .word STACKINIT @ stack pointer value when stack is empty .word _start + 1 @ reset vector (manually adjust to odd for thumb) .word _nmi_handler + 1 @ .word _hard_fault + 1 @ .word _memory_fault + 1 @ .word _bus_fault + 1 @ .word _usage_fault + 1 @ .org 0x0134 .word _Ethernet + 1 @ Ethernet recieve a packet interrupt, start parsing .org 0x0256 _start: ldr r0, = NVIC_ISER1 @ this enables the Ethernet to interrupt the core ldr r1, = 0x20000000 str r1, [r0] loop: ldr r0, = NVIC_ISPR1 @ this enables the Ethernet to interrupt the core ldr r1, = 0x20000000 str r1, [r0] b loop @ continue forever _dummy: @ if any int gets triggered, just hang in a loop _nmi_handler: _hard_fault: _memory_fault: _bus_fault: _usage_fault: b _dummy _Ethernet: push {r2} push {r1} push {r0} ldr r3, = 0x10101010 @ let don see if it worked. pop {r0} pop {r1} pop {r2} bx lr #zero-degrees-of-separation #worst-forum-software-ever #register-3-isr-bx-lr-reset2013-09-27 08:49 AM
The Cortex-M3 pushes a stack frame on interrupts, and uses the same context for tail chained handlers.
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/Babefdjc.html
2013-09-27 09:32 AM
In laymans terms ... The CPU is doing the work of saving r0-r3 for me, and by not expecting that I falsely perceived it as being reset?
Thanks again, Clive. Are you employed by ST? I wonder about your intersection of expertise and availability. It is uncanny.2013-09-27 04:22 PM
I wrote a longer response but the forum ate it, and won't go back.
The Cortex M3/M4 pushes the processor context is a fashion compatible with the C ABI calling standard, this permits the direct calling of C routines under interrupt with no magic or any assembler shims or wrappers. In this manner it is quite elegant. The pushing makes the interrupt start at little more latent, but conversely doesn't require any additional work by the handler, and permits multiple handlers to be tail-chained without restoring the original context. No, I don't work for ST, but have a pretty pervasive internet connection from multiple platforms. I've been doing this for a while, and have a pretty broad and deep experience in the semiconductor and electronics space. Unlike crosswords, sudoku and speed chess, doing this has more direct impact. If I can offer some insight in a minute that saves someone hours or days, I've made the difference I'm looking to make.