cancel
Showing results for 
Search instead for 
Did you mean: 

How to correctly initialize and config SVC interrrupt

SMola
Associate II

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?

1 ACCEPTED SOLUTION

Accepted Solutions
CHead
Associate III

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.

View solution in original post

6 REPLIES 6
CHead
Associate III

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.

SMola
Associate II

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,

SMola
Associate II

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?

SMola
Associate II

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?

ArturasV
Senior

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.

SMola
Associate II

@ArturasV​ Appreciate the help from you guys.