Would you like to react to this message? Create an account in a few clicks or log in to continue.

You are not connected. Please login or register

"Interrupts::retI Error: No active Interrupt". How to debug this error?

3 posters

Go down  Message [Page 1 of 1]

hotwolf

hotwolf

Hello,

I have an Arduino sketch (DIYWaterChiller) in which I'm trying to capture the pulse rate of two water flow sensors. In my SimulIDC circuit (DiYWaterChiller.sim1), I'm using two clocks to model the sensors. These are connected to the Arduino UNO interrupts 2 and 3.

Shortly after turning one of these clocks in simulation, The simulator reports the error:

Interrupts::retI Error: No active Interrupt

I assume this means that an RETI instruction was executed outside of an interrupt service routine, which would be a compiler bug.

Is there a way to immediately stop the simulation when an error occurs, to check the program counter, stack, ...? Or how can this be debugged?

arcachofo

arcachofo

I assume this means that an RETI instruction was executed outside of an interrupt service routine, which would be a compiler bug.
Not sure, I'm investigating the issue.

Is there a way to immediately stop the simulation when an error occurs, to check the program counter, stack, ...? Or how can this be debugged?
In general you can use the debugger, but here everything is happening in the libraries, so not much to do.

hotwolf

hotwolf

Thanks for looking at this issue.

I've switched over to running my code on the real hardware and there I also seem to be observing runaway code, whenever I initialize the TimerInterrupt library. So the simulator is probably correct, and there might be a misplaced RETI instruction in the code.
As a suggestion for future versions of the SimulIDE, it would be helpful to either get more information along with the error message or to stop the simulation immediately to see the debug information in the MCU monitor.

arcachofo

arcachofo

I've switched over to running my code on the real hardware and there I also seem to be observing runaway code, whenever I initialize the TimerInterrupt library. So the simulator is probably correct, and there might be a misplaced RETI instruction in the code.
Yes, maybe there is something wrong (or just weird) in the library, but I'm not sure that Simulide is doing what it should.

I reproduced the issue with a minimal example and the problem happens when both attachInterrupt and ITimer2.attachInterruptInterval are used.
Each one alone works ok.

The problem appears when Pin Change Interrupt happens while executing TimerHandler().
This is what is happening:

Interrupt::raise "T2COA"
Interrupt::execute "T2COA"
Interrupt::exitInt "T2COA"
Interrupt::raise "T2COA"
Interrupt::execute "T2COA"   << It should exit from this interrupt before executing INT1
Interrupt::raise "INT1"
Interrupt::execute "INT1"      << Executes INT1 without Reti from T2COA
Interrupt::exitInt "INT1"
Interrupt::execute "T2COA"  << Executes again T2COA, Seems that Simulide should not do this
Interrupt::exitInt "T2COA"
Interrupts::retI Error: No active Interrupt

hotwolf

hotwolf

Thanks for taking the time to investigate this problem. So there seem to be two bugs in the simulation model of the Atmega: The I-bit becomes ignored if multiple interrupt sources are involved and the return address is not captured correctly on the stack.
Should we then move this discussion thread over to bug reports?

arcachofo

arcachofo

As I debugged it got more complicated.

What is happening is that T2COA interrupt is triggered while the previous one is not finished.
Debug messages above didn't catch this due to where the msg was placed.

The I-bit becomes ignored if multiple interrupt sources are involved and the return address is not captured correctly on the stack.
I don't understand what exactly you mean.

Should we then move this discussion thread over to bug reports?
Moved.

hotwolf

hotwolf

arcachofo wrote:

The I-bit becomes ignored if multiple interrupt sources are involved and the return address is not captured correctly on the stack.
I don't understand what exactly you mean.


I meant that the global interrupt enable bit should prevent nested interrupt execution, but it seems that it doesn't do that in the simulation.  And, that the return address to the interrupted "T2COA" routine was captured incorrectly, but I guess that was rather an interrupt overrun.

arcachofo

arcachofo

Well.. the whole problem happens because interrupts are enabled by software inside T2COA interrupt.
Then Pin change interrupt is executed as a nested interrupt.
And in the meanwhile T2COA triggers again.

Maybe this is causing problems in the real hardware, but I'm not sure if Simulide is handling the situation correctly.

KerimF

KerimF

From ATmega8 datasheet:

The I-bit is cleared by hardware after an interrupt has occurred, and is set by the RETI instruction to enable subsequent interrupts.

Status Register [SREG]
Bit 7 – I: Global Interrupt Enable



Last edited by KerimF on Thu May 11, 2023 6:35 pm; edited 1 time in total

arcachofo

arcachofo

The I-bit is cleared by hardware after an interrupt has occurred, and is set by the RETI instruction to enable subsequent interrupts.
Yes, and can be set by software to allow nested interrupts.

KerimF

KerimF

arcachofo wrote:
The I-bit is cleared by hardware after an interrupt has occurred, and is set by the RETI instruction to enable subsequent interrupts.
Yes, and can be set by software to allow nested interrupts.

I see.
I forgot it because I used not to allow nested interrupts for being somehow risky. And when real necessary, I let the codes of the interrupt routines be very short.

arcachofo

arcachofo

And when real necessary, I let the codes of the interrupt routines be very short.
Yes that is something to think about.
For example, in this case there are some Serial.println("flow_in_isr()"); inside interrupt routines.
This takes a long time at 9600 baud and could cause some interrupts to be lost and/or make the loop() routine very slow because the cpu is most of the time executing interrupts.
EDIT: or maybe not, Serial most probably uses interrupts as well.

In any case I have the problem identified and a solution is roughly implemented, but I have to check if it is working correctly in other cases.

arcachofo

arcachofo

The problem happens when an interrupt that was interrupted is raised while executing the nested interrupt:
- T2COA interrupt raised.
- Execute T2COA.
- Enable nested interrupts by software.
- INT1 interrupt raised (not Pin Change sorry).
- Execute INT1.
- T2COA interrupt raised. << Should be ignored, but Simulide adds it to pending interrupts.
- RETI from INT1.
- Execute T2COA again. << It should just return to T2COA, instead it jumps to T2COA vector address.  
- Everything is a mess from now.

KerimF

KerimF

arcachofo wrote:The problem happens when an interrupt that was interrupted is raised while executing the nested interrupt:
- T2COA interrupt raised.
- Execute T2COA.
- Enable nested interrupts by software.
- INT1 interrupt raised (not Pin Change sorry).
- Execute INT1.
- T2COA interrupt raised. << Should be ignored, but Simulide adds it to pending interrupts.
- RETI from INT1.
- Execute T2COA again. << It should just return to T2COA, instead it jumps to T2COA vector address.  
- Everything is a mess from now.

As long you can discover what happens in the wrong way, it will be just a question of time for you to solve it.
For instance, once a while, my brain surprises me by solving a weird, but important, problem even after I forgot it for a rather long time!
It is much like the time needed by the brain to synthesize the proper antibiotic against a 'natural' infection.

arcachofo

arcachofo

This issue should be solved in development version. Download here:
https://simulide.forumotion.com/t550-simulide-trunk-tester-builds#2961

hotwolf

hotwolf

Thanks for fixing this interrupt issue so quickly. I can confirm, that I that I no longer see the error message in my simulation.

arcachofo likes this post

Sponsored content



Back to top  Message [Page 1 of 1]

Permissions in this forum:
You cannot reply to topics in this forum