When ARM chips(cortex-A7)are compiled in thumb mode, the program may run abnormally, and the exception point has been located. The problematic C code is:
while (locked && result)
{
// while loop body
}
The assembly code compiled from the while( locked && result ) statement in thumb mode is as follows:
0x000e21c0 <+120>: cmp r3, #0
0x000e21c2 <+122>: ite eq
0x000e21c4 <+124>: moveq r3, #0
0x000e21c6 <+126>: andne.w r3, r11, #1
0x000e21ca <+130>: cmp r3, #0
0x000e21cc <+132>: beq.n 0xe226c
In which the value of locked is loaded into r3. Under normal circumstances, if locked=0, the code execution logic is 0x000e21c2 -> 0x000e21c4 -> 0x000e21ca. However, when the program runs to 0x000e21c4 (at this point, the value of PC is already 0x000e21ca), an interrupt occurs. The chip automatically gives the PC pointer (0x000e21ca) to the LR jump register, and then jumps to the interrupt handler function IRQ.
In the interrupt handling function, in order to normally jump back to the moment when the interrupt is triggered, the operation sub r0,lr,#4 is executed to roll back one instruction. At this time, lr=0x000e21ca - 4 = 0x000e21c6, resulting in PC=0x000e21c6 when exiting the interrupt, while the normal situation should be 0x000e21c4.
IRQ:
...
sub r0,lr,#4
...
stmfd sp!,{r0-r2,r4,r5}
The above logic will cause the program to enter the while loop body when locked = 0, resulting in abnormal program operation.
Therefore, I would like to know how to operate the LR register in the interrupt handling function in this case, in order to ensure that after exiting the interrupt function, it returns to the normal code logic.
There are multiple
lrregisters on a Cortex-A CPU. These are called banked registers. An interrupt will transition to irq mode, where there is a banked (different copy) oflr. Upon returning, the cpsr is restored and the mode is change which results in the original copy of thelrbeing used.If your interrupt system is not structured like this, you have broken a Cortex-A model and need to explain. If you have ported some system from a Cortex-M framework, you may have inadvertently caused this issue. So the code in the 'loop body' is entirely correct. It is the interrupt handler that is suspect, but it is unclear as to the issue without knowing larger system level constructs of how the 'main line' and interrupts are interacting.