Context switch within Interrupt Service Routine

Discussions and support about ChibiOS/RT, the free embedded RTOS.
Post Reply
xnr
Posts: 9
Joined: Fri Jul 18, 2014 4:49 pm

Context switch within Interrupt Service Routine

Post by xnr »

I'm currently porting ChibiOS 2.6.4 to a new platform. But I think this question is more general os related and port independent.

(This paragraph may be skipped.)
After I managed to implement port_switch(), I ran the TestThread. All tests until delayed threading passed. I figured out I must have missed enabling interrupts in PORT_IRQ_EPILOGUE(). Mutex priority inversion was the next test to fail. It was locked inside the loop of test_cpu_pulse(). I thought must be a missing interrupt enabling again, so for test purposes I directly inserted the according code right before the loop. But nothing happened. I figured out that no new timer interrupts were taking place because the old interrupt handler didn't return.

This brings me to my actual question: What should happen if chSysSwitch() is called from withing an interrupt handler?

Let me explain my problem. Assume there are two threads with same priority and TIME_QUANTUM is > 0 (so round robin scheduling is enabled). Thread A is currently running. A timer interrupt occures, chSysTimerHandler is called. In the IRQ_PORT_EPILOGUE doReschedule functions switch from thread A to thread B. Thread B does its thing, e.g. while(1);. No other interrupts will occure because the Interrupt Service Routine didn't return yet.
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Context switch within Interrupt Service Routine

Post by Giovanni »

It depends on the architecture, does your CPU have a dedicated stack for IRQs? if so you should only switch after the IRQ stack has been emptied and the ISR has returned (see all the tricks in the ARMCMx port, it switches after the ISR return by using a fake return frame).

If your CPU has a single stack then it is much simples, just follow the lines of the MSP or AVR ports.

Note that after the switch, it is guaranteed that the switched-in thread re-enables the interrupt.

It is a good idea to have the state checker enabled while testing, it could reveal something.

Giovanni
xnr
Posts: 9
Joined: Fri Jul 18, 2014 4:49 pm

Re: Context switch within Interrupt Service Routine

Post by xnr »

The CPU has one stack and I also tried to follow the MSP430 port. And before the Interrupt Service Routine is called all registers are saved (including link register). I still don't see how the Interrupt Service Routine should return after thread B switched in.
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Context switch within Interrupt Service Routine

Post by Giovanni »

If you do the context switch from *within* the ISR then it is the thread B that re-enables the interrupts and continues the execution, the ISR returns when thread A is executed again.

Of course this assumes that re-enabling interrupts is sufficient to exit the ISR state without having to execute a dedicated instruction.

If this assumption is not true then you should follow the ARMCMx model where the switch is done after the ISR return.

Giovanni
xnr
Posts: 9
Joined: Fri Jul 18, 2014 4:49 pm

Re: Context switch within Interrupt Service Routine

Post by xnr »

Giovanni wrote:If you do the context switch from *within* the ISR then it is the thread B that re-enables the interrupts and continues the execution, the ISR returns when thread A is executed again.

Yes, this is what I observed.
Giovanni wrote:Of course this assumes that re-enabling interrupts is sufficient to exit the ISR state without having to execute a dedicated instruction.

Unfortunately, re-enabling isn't sufficient. ISR has to return, otherwise the Interrupt Controller states that the (Timer) Interrupt is still In-Service and blocks all other succeeding (Timer) Interrupts.

Thanks a lot for your great support! :)
Post Reply