I think, the missing real RTOS hits me. I cannot accomplish what I want to implement:
It looks like, this is not possible, not supported (due to a real RTOS is missing).
I use TeensyThreads, fine, but no way to use semaphores, esp. no means available to trigger a thread from inside an ISR handler.
(TeensyThreads does not have semaphores, using Mutex in ISR handler crashes, and not a real scheduler which would schedule right after INT ISR)
How to do?
I do not want to set a shared global variable and at the end I had to poll this variable (it would be still a polling approach!)
It would not be immediately (in real-time) when INT was fired, instead I would just "realize" the variable has been changed after
an elapsed delay, e.g. when I come back to loop().
I do not have anything in loop(), all runs as threads: (loop() is like "idle thread" (and delays several milli-seconds there).
I need to trigger a thread which handles my interrupt. But outside of the MCU INT context (inside ISR other INTs are blocked, Serial.print()
and other functions using HW INTs are not possible!).
But after a GPIO INT was triggered - I want to fire SPI transactions, needing as well interrupts - not possible right now.
Polling a global variable is "unpredictable" when it will be seen, the interrupt latency would be too large, unpredictable when, not real-time.
I want to have my ISR handler, running as a thread, being scheduled immediately after the HW ISR function has released a semaphore and ISR returns from INT
(as CMSIS FreeRTOS does).
The lack of a real RTOS, e.g. CMSIS FreeRTOS, a real scheduler which works together with interrupts, is "painful".
Thinking about how to make it available:
a) try to port and integrate CMSIS FreeRTOS (or any other RTOS with support for INT handling and scheduling)
b) implement an assembly code based "context switch", e.g. modify the LR register and other MCU registers (where to continue after INT ISR will return) and jump to my ISR thread handler
(running outside the INT context, able to use also INTs)
c) but tricky: I want to jump immediately after INT handler "returns from interrupt" to the ISR thread handler. But when this one finishes - it should continue at the code line
where the INT has kicked in. So, I had to save and restore the context properly. A thread is interrupted, a thread is running after ISR, but it should go back to original interrupted thread.
d) usually, an RTOS would use the PendSV interrupt to do this job: set pending INT during a HW INT, so that scheduler is invoked right after return from HW ISR (by PendSV is triggered).
No idea if PendSV vector can be rerouted to FreeRTOS (or to my scheduler) inside the Arduino/Teensy LIBs: the INT vector table must be altered.
Does anybody have a solution (or better idea) - how to get a thread triggered from an ISR? (and executed immediately right after ISR has finished)?
Such an ISR would just have a semaphore set to release the ISR thread handler which runs outside INT context as any other thread and can use any other function.
Do not do any polling of a shared global variable (unpredictable when it will be seen)!
- when GPIO interrupt is triggered - a thread should be released (running outside INT context)
- the interrupt handler should unlock a semaphore, "give from ISR", so that as the next code the thread waiting on semaphore starts running (immediately)
It looks like, this is not possible, not supported (due to a real RTOS is missing).
I use TeensyThreads, fine, but no way to use semaphores, esp. no means available to trigger a thread from inside an ISR handler.
(TeensyThreads does not have semaphores, using Mutex in ISR handler crashes, and not a real scheduler which would schedule right after INT ISR)
How to do?
I do not want to set a shared global variable and at the end I had to poll this variable (it would be still a polling approach!)
It would not be immediately (in real-time) when INT was fired, instead I would just "realize" the variable has been changed after
an elapsed delay, e.g. when I come back to loop().
I do not have anything in loop(), all runs as threads: (loop() is like "idle thread" (and delays several milli-seconds there).
I need to trigger a thread which handles my interrupt. But outside of the MCU INT context (inside ISR other INTs are blocked, Serial.print()
and other functions using HW INTs are not possible!).
But after a GPIO INT was triggered - I want to fire SPI transactions, needing as well interrupts - not possible right now.
Polling a global variable is "unpredictable" when it will be seen, the interrupt latency would be too large, unpredictable when, not real-time.
I want to have my ISR handler, running as a thread, being scheduled immediately after the HW ISR function has released a semaphore and ISR returns from INT
(as CMSIS FreeRTOS does).
The lack of a real RTOS, e.g. CMSIS FreeRTOS, a real scheduler which works together with interrupts, is "painful".
Thinking about how to make it available:
a) try to port and integrate CMSIS FreeRTOS (or any other RTOS with support for INT handling and scheduling)
b) implement an assembly code based "context switch", e.g. modify the LR register and other MCU registers (where to continue after INT ISR will return) and jump to my ISR thread handler
(running outside the INT context, able to use also INTs)
c) but tricky: I want to jump immediately after INT handler "returns from interrupt" to the ISR thread handler. But when this one finishes - it should continue at the code line
where the INT has kicked in. So, I had to save and restore the context properly. A thread is interrupted, a thread is running after ISR, but it should go back to original interrupted thread.
d) usually, an RTOS would use the PendSV interrupt to do this job: set pending INT during a HW INT, so that scheduler is invoked right after return from HW ISR (by PendSV is triggered).
No idea if PendSV vector can be rerouted to FreeRTOS (or to my scheduler) inside the Arduino/Teensy LIBs: the INT vector table must be altered.
Does anybody have a solution (or better idea) - how to get a thread triggered from an ISR? (and executed immediately right after ISR has finished)?
Such an ISR would just have a semaphore set to release the ISR thread handler which runs outside INT context as any other thread and can use any other function.
Do not do any polling of a shared global variable (unpredictable when it will be seen)!