Nios stops responding to interrupts

T

tns1

Guest
QuartusII 4.0 SP1, SOPC builder with Nios 3.2, Cyclone C4.

I have the Nios32 @ 30mhz working fine with my user logic modules, but
any ISR I try works a random number of times (1 to 30 times?) and then
stops getting called. By bringing out some internal signals to pins, I
can see that the irq signal from my module is asserted, but the ISR just
does not get called. This is the first time I have tried using Nios
interrupts, but I am getting it straight from the examples.

As a test, I wrote an ISR that just increments and prints a count value,
and does not clear the interrupt. There is no foreground code other than
installing the vector and enabling interrupts. I would expect my ISR to
get called indefinitely, (context save, execute, context restore), but
it just works a random # of times and stops.

This is the only handler I have installed, but I know the spurious
handler is installed by default (it works), as well as the CWP handler
(dont know if it works - how to test?). The behavior suggests
stack/memory corruption from the context save/restore. I don't re-enable
interrupts in my ISR, so I don't expect nested interrupts.

I have seen weird behaviors whenever the systhesis does not match the
assembled libraries used to compile (forgot to use 'Generate'), but I
have triple-checked. Any ideas/new errata?
 
Hello,

I have seen similar behaviour. What I found is that if the main loop
is very tight, the interrupt handler will not get called ... very
bizarre.

ie: if I have a main loop of:

while (1); // loop infinitely, waiting for a HW interrupt

.... the ISR does not get called. However:

while (1) printf( "." ); // loop, printing a dot each time around

.... allows the ISR to be called. IIRC, even doing a small delay causes
the ISR not to be called, until the delay is sufficiently large. ie:

while (1)
for (i=0; i<DELAY; i++); // loop after waiting a bit

I verified the compiler did not optimize the delay out and that
caching was disabled.

For reasons I don't understand, the tight loop causes the calling of
the ISR to fail. Perhaps you have a similar situation.

Also make sure that the HW interrupt is asserted while outside of any
currently-running ISR, as Nios has to see it level-high.

Other than this wierd case, I haven't had ISR problems. I believe I
tested this with Nios 3.2 or maybe 3.01.

-- Pete


tns1 <tns1@cox.net> wrote in message news:<spiDc.4304$6r1.615@fed1read06>...
QuartusII 4.0 SP1, SOPC builder with Nios 3.2, Cyclone C4.

I have the Nios32 @ 30mhz working fine with my user logic modules, but
any ISR I try works a random number of times (1 to 30 times?) and then
stops getting called. By bringing out some internal signals to pins, I
can see that the irq signal from my module is asserted, but the ISR just
does not get called. This is the first time I have tried using Nios
interrupts, but I am getting it straight from the examples.

As a test, I wrote an ISR that just increments and prints a count value,
and does not clear the interrupt. There is no foreground code other than
installing the vector and enabling interrupts. I would expect my ISR to
get called indefinitely, (context save, execute, context restore), but
it just works a random # of times and stops.

This is the only handler I have installed, but I know the spurious
handler is installed by default (it works), as well as the CWP handler
(dont know if it works - how to test?). The behavior suggests
stack/memory corruption from the context save/restore. I don't re-enable
interrupts in my ISR, so I don't expect nested interrupts.

I have seen weird behaviors whenever the systhesis does not match the
assembled libraries used to compile (forgot to use 'Generate'), but I
have triple-checked. Any ideas/new errata?
 
Yes I remember now that how often the ISR was reliably called was
inversely proportional to how tight my main loop was ... ie, sometimes
I would see sporadic interrupt trapping like you are.

-- Pete

tns1 <tns1@cox.net> wrote in message news:<spiDc.4304$6r1.615@fed1read06>...
QuartusII 4.0 SP1, SOPC builder with Nios 3.2, Cyclone C4.

I have the Nios32 @ 30mhz working fine with my user logic modules, but
any ISR I try works a random number of times (1 to 30 times?) and then
stops getting called. By bringing out some internal signals to pins, I
can see that the irq signal from my module is asserted, but the ISR just
does not get called. This is the first time I have tried using Nios
interrupts, but I am getting it straight from the examples.

As a test, I wrote an ISR that just increments and prints a count value,
and does not clear the interrupt. There is no foreground code other than
installing the vector and enabling interrupts. I would expect my ISR to
get called indefinitely, (context save, execute, context restore), but
it just works a random # of times and stops.

This is the only handler I have installed, but I know the spurious
handler is installed by default (it works), as well as the CWP handler
(dont know if it works - how to test?). The behavior suggests
stack/memory corruption from the context save/restore. I don't re-enable
interrupts in my ISR, so I don't expect nested interrupts.

I have seen weird behaviors whenever the systhesis does not match the
assembled libraries used to compile (forgot to use 'Generate'), but I
have triple-checked. Any ideas/new errata?
 
I have an 8ms delay in my main loop now, and I still have the problem so
it does not seem like the same one. I can try adding more code to my
loop. Still, neither the behavior you describe nor the one I am seeing
are correct so what's the root cause?

My user logic module clears the IRQ whenever I read a register. Normally
this is done in the ISR. Eventually the IRQ does not clear because the
ISR is not called. (This does not seem to be the case of the ISR getting
called, but not clearing the IRQ for some reason). I tried adding a read
of the same clearing register in my main loop every 100ms. This 'kick
starts' the Nios when it is ignoring IRQs, but probably at a cost of a
lost IRQ - it works, but is not acceptable.

I can also exit my main loop (via a terminal key press), and perform a
manual read of the clearing register. This does clear the asserted IRQ
signal, but does NOT restore the system to normal operation. Even though
main line code runs OK, subsequent IRQs are still ignored. The only way
to re-enable interrupts is to reset everything. This really sounds like
an IRQ is being blocked in the Nios core kinda like interrupts were
never re-enabled internally during the previous context restore (or
vector table corruption or...). I guess I need to try the debugger so I
can look at stack pointers, status registers, etc.

I read about an option on the CWP manager that selects between HW & SW
handling of overflows on the register window but I don't see this choice
on any tool dialog.





Peter Sommerfeld wrote:
Yes I remember now that how often the ISR was reliably called was
inversely proportional to how tight my main loop was ... ie, sometimes
I would see sporadic interrupt trapping like you are.

-- Pete

tns1 <tns1@cox.net> wrote in message news:<spiDc.4304$6r1.615@fed1read06>...

QuartusII 4.0 SP1, SOPC builder with Nios 3.2, Cyclone C4.

I have the Nios32 @ 30mhz working fine with my user logic modules, but
any ISR I try works a random number of times (1 to 30 times?) and then
stops getting called. By bringing out some internal signals to pins, I
can see that the irq signal from my module is asserted, but the ISR just
does not get called. This is the first time I have tried using Nios
interrupts, but I am getting it straight from the examples.

As a test, I wrote an ISR that just increments and prints a count value,
and does not clear the interrupt. There is no foreground code other than
installing the vector and enabling interrupts. I would expect my ISR to
get called indefinitely, (context save, execute, context restore), but
it just works a random # of times and stops.

This is the only handler I have installed, but I know the spurious
handler is installed by default (it works), as well as the CWP handler
(dont know if it works - how to test?). The behavior suggests
stack/memory corruption from the context save/restore. I don't re-enable
interrupts in my ISR, so I don't expect nested interrupts.

I have seen weird behaviors whenever the systhesis does not match the
assembled libraries used to compile (forgot to use 'Generate'), but I
have triple-checked. Any ideas/new errata?
 
My user logic module clears the IRQ whenever I read a register. Normally
this is done in the ISR. Eventually the IRQ does not clear because the
ISR is not called. (This does not seem to be the case of the ISR getting
called, but not clearing the IRQ for some reason). I tried adding a read
of the same clearing register in my main loop every 100ms. This 'kick
starts' the Nios when it is ignoring IRQs, but probably at a cost of a
lost IRQ - it works, but is not acceptable.
I don't know anything about Nios.

You might try talking to software geeks. There is a classic interrupt
bug where the IRS turns off the interrupt but forgets to make one
last check to see if an interrupt came in just before it turned it off.

You should be able to debug this with a little work. Do you have a LED
on your IRQ signal? Is it on or off? If it's on, then the software
is not processing it. If it's off... Keep dividing the search.

Bugs that happen often/easily are easy to fix. The hard ones are the
ones that only happen when you aren't looking or once per week or month.

--
The suespammers.org mail server is located in California. So are all my
other mailboxes. Please do not send unsolicited bulk e-mail or unsolicited
commercial e-mail to my suespammers.org address or any of my other addresses.
These are my opinions, not necessarily my employer's. I hate spam.
 
Have you read the STATUS reg? You can read it with a RDCTL %g7
instruction. Bit 15 of the reg is the interrupt enable and 9..14 are
the current interrupt priority. If these aren't what they should be
(ie. IE is 0, IPRI is <= IRQ #) then something wierd is definitely
going on.

-- Pete

tns1 <tns1@cox.net> wrote in message news:<oEWDc.15991$6r1.6614@fed1read06>...
I have an 8ms delay in my main loop now, and I still have the problem so
it does not seem like the same one. I can try adding more code to my
loop. Still, neither the behavior you describe nor the one I am seeing
are correct so what's the root cause?

My user logic module clears the IRQ whenever I read a register. Normally
this is done in the ISR. Eventually the IRQ does not clear because the
ISR is not called. (This does not seem to be the case of the ISR getting
called, but not clearing the IRQ for some reason). I tried adding a read
of the same clearing register in my main loop every 100ms. This 'kick
starts' the Nios when it is ignoring IRQs, but probably at a cost of a
lost IRQ - it works, but is not acceptable.

I can also exit my main loop (via a terminal key press), and perform a
manual read of the clearing register. This does clear the asserted IRQ
signal, but does NOT restore the system to normal operation. Even though
main line code runs OK, subsequent IRQs are still ignored. The only way
to re-enable interrupts is to reset everything. This really sounds like
an IRQ is being blocked in the Nios core kinda like interrupts were
never re-enabled internally during the previous context restore (or
vector table corruption or...). I guess I need to try the debugger so I
can look at stack pointers, status registers, etc.

I read about an option on the CWP manager that selects between HW & SW
handling of overflows on the register window but I don't see this choice
on any tool dialog.
 
Thanks for the tip. Right now my code is all C, but I have hopes of
getting GDB working tomorrow - should answer many questions. One thing
that I did find is that delays in either the ISR or the main loop did
not help. Since the problem behavior masks interrupts, I forced an
interruptenableblah() but it did not fix things. Odd, I believe the
debug port uart uses interrupts and it never stops working.

I looked for vector table corruption and noticed that all the vectors,
including my installed ones, point to addresses in flash. My system is
supposed to copy the flash code to sram and execute from there. This
does not seem correct unless all IRQs are first directed thru a trapping
routine like I have seen for some RTOSes. The debugger should tell all.


Peter Sommerfeld wrote:
Have you read the STATUS reg? You can read it with a RDCTL %g7
instruction. Bit 15 of the reg is the interrupt enable and 9..14 are
the current interrupt priority. If these aren't what they should be
(ie. IE is 0, IPRI is <= IRQ #) then something wierd is definitely
going on.

-- Pete

tns1 <tns1@cox.net> wrote in message news:<oEWDc.15991$6r1.6614@fed1read06>...

I have an 8ms delay in my main loop now, and I still have the problem so
it does not seem like the same one. I can try adding more code to my
loop. Still, neither the behavior you describe nor the one I am seeing
are correct so what's the root cause?

My user logic module clears the IRQ whenever I read a register. Normally
this is done in the ISR. Eventually the IRQ does not clear because the
ISR is not called. (This does not seem to be the case of the ISR getting
called, but not clearing the IRQ for some reason). I tried adding a read
of the same clearing register in my main loop every 100ms. This 'kick
starts' the Nios when it is ignoring IRQs, but probably at a cost of a
lost IRQ - it works, but is not acceptable.

I can also exit my main loop (via a terminal key press), and perform a
manual read of the clearing register. This does clear the asserted IRQ
signal, but does NOT restore the system to normal operation. Even though
main line code runs OK, subsequent IRQs are still ignored. The only way
to re-enable interrupts is to reset everything. This really sounds like
an IRQ is being blocked in the Nios core kinda like interrupts were
never re-enabled internally during the previous context restore (or
vector table corruption or...). I guess I need to try the debugger so I
can look at stack pointers, status registers, etc.

I read about an option on the CWP manager that selects between HW & SW
handling of overflows on the register window but I don't see this choice
on any tool dialog.
 

Welcome to EDABoard.com

Sponsor

Back
Top