Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
19 years ago

Potential _interrupt_handler infinite loop

I added a 16550 UART FPGA Core and when receiving large quantities of data my system is locking up because it is in an infinite loop within the _interrupt_handler assembly code in vector.s. What I find is that I appear to get an interrupt but when I enter _interrupt_handler it appears the ipending register is 0 and this causes an infinite loop!

At the beginning of _interrupt_handler it reads the ipending register to determine which interrupts are pending:

rdctl r24, ipending

Later the following code runs to determine which interrupt to process by basically shifting r24 and incrementing r4 until there is a 1 in the lower bit. It then uses r4 to determine which call to make:

6:

andi r3, r24, 1

bne r3, zero, 7f

addi r4, r4, 1

srli r24, r24, 1

br 6b

7:

When I hang, r24 is 0! I'm not sure how this happens, but since r24 is 0 I can never break out of the loop. I assume ipending was 0 when it was copied as otherwise I should not end up stuck in this loop. When I break with the debugger and dump the registers I get:

r3 = 0

r4 = 0x656c462 (obviously ran for a while)

r24 = 0 (actual disassembly shows this as register et)

ipending = 0x44 (after I break with the debugger)

If I go and then break again, r4 changes to 0x79af66b. If I manually set r3 to the ipending value, clear r4 and then go, I get out of the loop and the code appears to run fine except for the lost data.

I suspect that I have a HW problem which is aggravating this. However, I am not sure exactly what the HW can do so that I can end up in this situation.

Any ideas how I could appear to be processing an interrupt but yet not have one pending?

Any ideas how the HW interrupt functionality could case a problem like this?

Shouldn't the system be able to handle a spurious interrupt if this is the cause?

It's not clear to me there is an easy fix to this. Obviously any changes here would effect every interrupt so it's possible that there shouldn't be any changes. However, it's certainly something to investigate.

I'm using Quartus 5.1 SP1 Web Edition, NIOS II 5.1, ecos for 5.1. This problem also occurs with the 5.0 versions.

Thanks,

Stefan

4 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    originally posted by stefanlevie@Mar 10 2006, 01:58 PM

    i added a 16550 uart fpga core and when receiving large quantities of data my system is locking up because it is in an infinite loop within the _interrupt_handler assembly code in vector.s. what i find is that i appear to get an interrupt but when i enter _interrupt_handler it appears the ipending register is 0 and this causes an infinite loop!

    at the beginning of _interrupt_handler it reads the ipending register to determine which interrupts are pending:

    rdctl r24, ipending

    later the following code runs to determine which interrupt to process by basically shifting r24 and incrementing r4 until there is a 1 in the lower bit. it then uses r4 to determine which call to make:

    6:

    andi r3, r24, 1

    bne r3, zero, 7f

    addi r4, r4, 1

    srli r24, r24, 1

    br 6b

    7:

    when i hang, r24 is 0! i'm not sure how this happens, but since r24 is 0 i can never break out of the loop. i assume ipending was 0 when it was copied as otherwise i should not end up stuck in this loop. when i break with the debugger and dump the registers i get:

    r3 = 0

    r4 = 0x656c462 (obviously ran for a while)

    r24 = 0 (actual disassembly shows this as register et)

    ipending = 0x44 (after i break with the debugger)

    if i go and then break again, r4 changes to 0x79af66b. if i manually set r3 to the ipending value, clear r4 and then go, i get out of the loop and the code appears to run fine except for the lost data.

    i suspect that i have a hw problem which is aggravating this. however, i am not sure exactly what the hw can do so that i can end up in this situation.

    any ideas how i could appear to be processing an interrupt but yet not have one pending?

    any ideas how the hw interrupt functionality could case a problem like this?

    shouldn't the system be able to handle a spurious interrupt if this is the cause?

    it's not clear to me there is an easy fix to this. obviously any changes here would effect every interrupt so it's possible that there shouldn't be any changes. however, it's certainly something to investigate.

    i'm using quartus 5.1 sp1 web edition, nios ii 5.1, ecos for 5.1. this problem also occurs with the 5.0 versions.

    thanks,

    stefan

    <div align='right'><{post_snapback}> (index.php?act=findpost&pid=13321)

    --- quote end ---

    --- Quote End ---

    I suggest you take a look at page 3-11 Determining the Cause of Exceprions in the Nios II Processor Reference Handbook n2cpu_nii5v1.pdf. Is your problem actually an exception? If not then as you surmise it&#39;s likely to be a hardware bug.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    In addition to rugbybloke&#39;s comments: if this is a hardware issue a likely cause is the UART hardware irq output assumes that its IQR output is handled in an edge sensitive manner. That is, the UART asserts its interrupt pin for a while and then clears it on its own, assuming that whatever is being driven by its IRQ is edge sensitive.

    In fact, wtih Avalon/Nios, IRQ is passed directly from a peripheral to the bus master (i.e. Nios processor) without any conditioning. Nios expects that once IRQ is asserted, it will be held there (level sensitive) until the processor & software have a chance to respond.

    This is discussed in the Nios II Processor Reference Handbook section on Excpetion Processing.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The UART Core was designed with level interrupts, but unfortunately there was a bug in the Timeout Interrupt where it was deasserted when the next data byte was received instead of when SW read the UART. Changing this eliminated the problem. Thanks for the help and pointers.

    Does anybody have any comments on whether or not the _interrupt_handler code should be changed to prevent an infinite loop?

    Thanks,

    Stefan
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    originally posted by stefanlevie@Mar 16 2006, 06:10 PM

    the uart core was designed with level interrupts, but unfortunately there was a bug in the timeout interrupt where it was deasserted when the next data byte was received instead of when sw read the uart. changing this eliminated the problem. thanks for the help and pointers.

    does anybody have any comments on whether or not the _interrupt_handler code should be changed to prevent an infinite loop?

    thanks,

    stefan

    <div align='right'><{post_snapback}> (index.php?act=findpost&pid=13523)

    --- quote end ---

    --- Quote End ---

    It&#39;s a bit of a tough one that, you can only get into the infinite loop with broken hardware, is it better to flag this with an infinite loop or ignore it?