SV#8, when sleeping in main and interrupt happens when in idle
Posted: Thu Oct 28, 2021 11:06 pm
I'm getting the Halt with SV#8 . I know this is typically caused by IRQs with priorities <=2 . I've reviewed the interrupt priorities, and they are all > 2 for the ones I am using (Vector15C is 10 for example). As a side note, I wonder why don't we set all interrupt priorities in ChibiOS/HAL to 15 on initialization. Because at reset, they are all 0 (highest priority).
So, here's what is going on. From main(), I issue a wspiCommand. The main() thread duly goes to sleep, as it calls osalThreadSuspendS - waiting for the interrupt to occur and wake it up. Great. So, main thread goes to sleep and switches to the IDLE thread. A context switch occurs, and soon after the interrupt happens and I get a Halt with SV#8 (ch.dbg.lock_cnt != 0).
1. ch.dbg.lock_cnt is 1 when the main() thread goes to sleep by calling osalThreadSuspendS(). I created a trace event here - see USER wspicmd below.
2. A context switch occurs to the IDLE thread
3. Vector15C (STM32_QUADSPI1_HANDLER) interrupt occurs
4. Halt SV#8
I captured a trace of what's going on:
I knew it would reach the halt condition soon after the osalThreadSuspendS() in wspiCommand, so I placed a breakpoint there. I also added a watchpoint on ch.dbg.lock_cnt, and a breakpoint in the idle thread.
As you can see below, it went straight from the osalThreadSuspendS() in wspiCommand() to the Halt without hitting the watchpoint or landing in the idle thread.
All this is happening upon bootup, while I'm initializing a bunch of stuff. I'm probably missing something, but I fail to see where ch.dbg.lock_cnt is decremented back to 0? Other interrupts occur in my system (8 or so UART interrupts while printing out string), but they didn't trigger this problem - but that's probably because it was always in the main thread and never got to switch to the IDLE thread for those interrupts. That's a difference.
Help!
So, here's what is going on. From main(), I issue a wspiCommand. The main() thread duly goes to sleep, as it calls osalThreadSuspendS - waiting for the interrupt to occur and wake it up. Great. So, main thread goes to sleep and switches to the IDLE thread. A context switch occurs, and soon after the interrupt happens and I get a Halt with SV#8 (ch.dbg.lock_cnt != 0).
1. ch.dbg.lock_cnt is 1 when the main() thread goes to sleep by calling osalThreadSuspendS(). I created a trace event here - see USER wspicmd below.
2. A context switch occurs to the IDLE thread
3. Vector15C (STM32_QUADSPI1_HANDLER) interrupt occurs
4. Halt SV#8
I captured a trace of what's going on:
Code: Select all
0,t=21,dt=0,rt=3705723 HALT {reason = 0x801c33c "SV#8"}
1,t=21,dt=0,rt=3705616 ISR_ENTER {name = 0x801b958 <__func__.10306.lto_priv.678> "Vector15C"}
2,t=21,dt=0,rt=3705269 SWITCH in = idle, out_state = 3, wtobjp = (void *) 0x20005f38 <WSPID1+8>
3,t=21,dt=0,rt=3705051 USER wspicmd,1I knew it would reach the halt condition soon after the osalThreadSuspendS() in wspiCommand, so I placed a breakpoint there. I also added a watchpoint on ch.dbg.lock_cnt, and a breakpoint in the idle thread.
Code: Select all
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x080099aa in wspiCommand at ../../ChibiOS_20.x.x/os/hal/osal/rt-nil/osal.h:735
2 hw watchpoint keep y ch.dbg.lock_cnt
3 breakpoint keep y 0x080018c0 in _idle_thread.lto_priv.362 at ../../ChibiOS_20.x.x/os/rt/src/chsys.c:73As you can see below, it went straight from the osalThreadSuspendS() in wspiCommand() to the Halt without hitting the watchpoint or landing in the idle thread.
Code: Select all
(gdb) where
#0 wspiCommand (wspip=0x20005f30 <WSPID1>, cmdp=cmdp@entry=0x801c460 <cmd_reset_enable_4>) at ../../ChibiOS_20.x.x/os/hal/src/hal_wspi.c:235
(gdb) c
Continuing.
Thread 1 received signal SIGINT, Interrupt.
[Switching to Thread 536900256]
0x080039a0 in chSysHalt (reason=reason@entry=0x801c33c "SV#8") at ../../ChibiOS_20.x.x/os/rt/src/chsys.c:199All this is happening upon bootup, while I'm initializing a bunch of stuff. I'm probably missing something, but I fail to see where ch.dbg.lock_cnt is decremented back to 0? Other interrupts occur in my system (8 or so UART interrupts while printing out string), but they didn't trigger this problem - but that's probably because it was always in the main thread and never got to switch to the IDLE thread for those interrupts. That's a difference.
Help!