2018-08-08 09:32 PM
I'm creating a context switch program for a personal mini ARM kernel project and the context switch program is written entirely in Assembly. The problem is when I make a SVC call (svc 0) I enter the SVC_Handler but when I try to execute the next instruction I then enter a different handler ("UsageFault_Handler"). The fault occurs before I can pop any of the registers in the SVC_Handler.
Here's a register dump of my gdb screen (right after I enter SVC_Handler and encounter UsageFault_Handler):
(gdb) i r
r0 0x1 1
r1 0x20000bcc 536873932
r2 0x40004404 1073759236
r3 0x1 1
r4 0x0 0
r5 0xc 12
r6 0x3 3
r7 0x20000fe4 536874980
r8 0x1 1
r9 0x0 0
r10 0xb 11
r11 0xa 10
r12 0x2 2
sp 0x2001ffa8 0x2001ffa8
lr 0xfffffff1 4294967281
pc 0x8000188 0x8000188 <UsageFault_Handler>
cpsr 0x3 3
And my context switch:
activate:
cpsie i
/* save kernel state into msp */
mrs ip, msp
push {r4-r11,ip,lr}
/* retrieve routine parameters and switch to the process stack psp */
ldmfd r0!, {ip,lr}
msr control, ip
isb
msr psp, r0
/* software stack frame. load user state */
pop {r4-r11}
/* hardware stack frame. the cpu pops r0-r3, r12 (IP), LR, PC, xPSR automatically */
/* jump to user task*/
bx lr
SVC_Handler:
/* automatically use the msp as the sp when entering handler mode */
/* pop msp stack */
pop {r4-r11,ip,lr}
mov sp, ip
/* back to the thread mode if no other active exception */
bx lr
Not sure what could be causing this problem because I made sure interrupts are enabled and initialized SVC priority to 0x0 (highest priority). Also, I'm using the ARM Cortex M4 STM32F411E evaluation board.
I'm thinking im initialising and configuring the interrupt wrong or the problem is somewhere else? Anyone came across this problem before on this board?
Solved! Go to Solution.
2018-08-09 05:37 PM
It would help if you could read CFSR after taking the usage fault to find out what type of fault it is. One possible reason for a usage fault is that your interrupt vector table has an even number in it; interrupt vectors must all be odd since Cortex-M4 only supports the Thumb ISA, not ARM ISA.
2018-08-09 05:37 PM
It would help if you could read CFSR after taking the usage fault to find out what type of fault it is. One possible reason for a usage fault is that your interrupt vector table has an even number in it; interrupt vectors must all be odd since Cortex-M4 only supports the Thumb ISA, not ARM ISA.
2018-08-12 09:18 PM
Hi @CHead ,
Thank you for replying. I'm using GDB and I'm not sure how I can access the CFSR register. Is this register only accessible through hardware debugger probes like the "Segger J-Link"?
Thanks,
2018-08-12 10:26 PM
So using GDB I've printed the SVC_Handler address and it looks like the address of the least significant bit of the vector is 0 so the vector is even:
(gdb) p SVC_Handler
$1 = {<text variable, no debug info>} 0x80001b0 <SVC_Handler>
You were suggesting the least significant bit should be set to 1 to indicate that this exception handler is a thumb code?
2018-08-13 12:36 AM
Hi @CHead ,
Looks like you were correct. Adding ".thumb_func" above my SVC_Handler definition in my context-switch allowed me to run my exception in thumb state. But please, if you can, let me know how I can retrieve CFSR register value. Do I need a hardware debugger probe to determine this register value using GDB?
2018-08-13 04:56 AM
CFSR is a simple register in system memory. If you are using a CMSIS, you can get the value of that with SCB->CFSR. If you want in in assembly, you can simply get it like this:
"ldr r0, =0xE000ED28"
"ldr r1, [r0]"
Note that i do not know assembly very well, maybe it is possible to do it another way.
2018-08-13 07:33 PM
@ArturasV Appreciate the help from you guys.