After careful examination of the source code and the Chibios traces, I have some more information on this issue, and a possible cause.
Let's say that I have the following threads:
Thread A, priority 128
Thread B, priority 129
And the following sequence:
1. Thread B executes (higher priority)
2. Thread B gets to WAITING state (call to chThdSleep())
3. Thread A starts execution.
4. SysTick Handler preempts Thread A.
5. Due to increase in system counter, Thread B gets in READY state.
6. Execution returns to Thread A. (WRONG!!!
7. Priority order violation gets triggered.
After this, it becomes clear to me that for some reason the SysTick handler does not perform a context switch that it had to.
Follows my SysTick handler. I can't see anything wrong with it. Comparing it to the handlers in the examples provided by Chibios, it seems identical.
Code: Select all
I started digging Chibios source code. I found that CH_IRQ_EPILOGUE()
which is ultimately responsible for the context switch.
there is the following condition check:
Code: Select all
if ((SCB->ICSR & SCB_ICSR_RETTOBASE_Msk) != 0U)
According to this
, the context switch will only take place if the SysTick handler is the only interrupt being executed. If SysTick has preempted another lower priority (non-system) interrupt, there will be no context switch. I am not sure whether I would consider this a bug or a feature.
In my case there are non-system / fast-IRQs (i.e. without CH_IRQ_PROLOGUE()
guards), of lower
priority than SysTick. I believe that such a handler gets preempted by SysTick, which results in no switching.
Giovanni, do you believe that this would be the case? Do all fast-IRQs must be of higher priority than all system IRQs?