Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

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                                                           
      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 developing on ARM Cortex M4 STM32F411E evaluation board. I read the programming manual (PM0214) and right now I'm playing around with the interrupt enable and priority registers. But I'm thinking if the issue was interrupt disable or priority then I would not have gone as far as entering the SVC_Handler so the issue must be something else. – smolaie Aug 6, 2018 at 20:30 Yeah, getting interrupts to work properly on ARM Cortex-M is like an ultimate divine miracle. Love this thing. – smolaie Aug 7, 2018 at 3:42

The problem was my interrupt vectors were all even numbers (ARM mode). Attempting to execute instructions when the T bit is 0 (least significant bit of the vector numbers) results in a fault or lockup. Since Cortex-M runs only in Thumb2 state I had to indicate my exception was running in thumb state by placing ".thumb_func" above my interrupt handler in my context-switch assembly.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.