This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS570LC4357: Inconsistent behavior of VIM when clearing peripheral interrupt flag for pending IRQ

Part Number: TMS570LC4357
Other Parts Discussed in Thread: HALCOGEN

Hi,

We observed different VIM behaviors when clearing pending peripheral IRQs (e.g. RTI Compare 2 interrupt) using the peripheral interrupt flag (e.g. RTIINTFLAG.INT2) while IRQs are masked.

In some cases, clearing the pending interrupt by writing 1 to its peripheral interrupt flag is enough to effectively clear the pending interrupt in the VIM (i.e. clear INTREQ). Namely, this was observed when IRQs become masked due to an Undefined exception:

Case #1 - IRQs are masked following an Undefined exception:

  1. An Undefined exception is taken just before an RTI Compare 2 interrupt flag (RTIINTFLAG.INT2) is raised.
  2. Since IRQs are masked, the Compare 2 interrupt remains pending.
  3. Before unmasking IRQs, RTIINTFLAG.INT2 is cleared with a write/read operation to ensure flag is properly cleared.
  4. After the RTI flag clearing operation, the corresponding pending interrupt bit in INTREQ[0] is automatically cleared so the IRQ pending is not taken when unmasking IRQs.

However, in other cases, the peripheral interrupt flag is cleared, but INTREQ is not updated and the pending IRQ is still taken. Two such cases were observed:

Case #2 - IRQs are masked following an SVC exception:

  1. An SVC exception is taken just before an RTI Compare 2 interrupt flag (RTIINTFLAG.INT2) is raised.
  2. Since IRQs are masked, the Compare 2 interrupt remains pending.
  3. Before unmasking IRQs, RTIINTFLAG.INT2 is cleared with a write/read operation to ensure flag is properly cleared.
  4. After the RTI flag clearing operation, the corresponding pending interrupt bit in INTREQ[0] is not automatically cleared so the pending IRQ is taken when unmasking IRQs.

Case #3 - IRQs are masked following an IRQ:

  1. An IRQ is taken just before an RTI Compare 2 interrupt flag (RTIINTFLAG.INT2) is raised.
  2. Since IRQs are masked, the Compare 2 interrupt remains pending.
  3. Before unmasking IRQs, RTIINTFLAG.INT2 is cleared with a write/read operation to ensure flag is properly cleared.
  4. After the RTI flag clearing operation, the corresponding pending interrupt bit in INTREQ[0] is not  automatically cleared so the pending IRQ is taken when unmasking IRQs.

Why does clearing the RTI Interrupt flag also clear the pending interrupt in the VIM in case #1, but not in cases #2 and #3?

Note that in all 3 cases, the RTI Compare 2 Interrupt remains enabled (RTISETINTENA/RTICLEARINTENA.COMP2 = 1).

  • I am looking into this and will get back to you today.

    Regards, Sunil

  • Hi,

    Is it possible that the compare interrupt condition happens again after the flag is "cleared" in cases 2 and 3? In general, it is highly recommended to only clear pending status flags for enabled interrupts from within their dedicated ISRs.

  • Hi Sunil,

    Thank you for your reply. Where in the documentation can I find the recommendation to only clear pending status flags for enabled interrupts from within their dedicated ISRs? And by pending status flag, do you mean the peripheral interrupt flag (e.g. RTIINTFLAG.INT2), the pending interrupt bit in the VIM (e.g. ÎNTREQ0[4]), or both?

    Thank you,

    Antoine

  • Hi Antoine,

    It is not mandatory to only clear interrupt flags in their own ISRs. Interrupt management is largely left to the application to implement as it wishes.

    In cases 2 and 3 above, is it possible for the RTI compare match 2 event to occur between clearing it in the RTI and clearing it in the VIM?

  • Hi Antoine,

    Are there any updates on this thread?

    Regards, Sunil

  • Hi Sunil,

    We understood why, in the case #1, the INTREQ register is automatically cleared whereas it is not for cases #2 and #3. To go back to your first reply, no the condition does not occur again. What we observed is that the pending interrupt bit in INTREQ is cleared only in cases where the peripheral interrupt flag (e.g. RTIINTFLAG) is cleared AFTER having read the IRQINDEX. Indeed, in case #1, our code was reading IRQINDEX before clearing the flag, but not in cases #2 and #3.

    In our understanding, this is would be the same reason why simply clearing the peripheral interrupt flag is sufficient to clear INTREQ when we are inside the interrupt's handler: in that case the VIM has already read IRQINDEX in order to branch to the handler and so the clearing propagates to the INTREQ status bit.

    However, all this behavior is infered from what we observe, there seems to be nothing in the TMS570LC4357 Reference Manual or Datasheet describing this behavior. Could I then ask you to confirm that our understanding reflects the actual behavior of pending interrupts in the VIM i.e. that clearing the peripheral interrupt flags (e.g. RTIINTFLAG) has no effect on pending interrupt status bits in INTREQ registers, unless IRQINDEX has been read prior to the clearing?

    Thank you,

    Antoine

  • Hi Antoine,

    Yes, it is not sufficient to just clear the pending interrupt flag at the interrupt module source, more so if this clear is done outside of the assigned ISR. There are multiple ways to clear the pending interrupt condition in the VIM:

    1. Read the IRQIVEC / FIQIVEC registers in the VIM
      • These registers hold the index for the highest-priority pending interrupt.
      • This was the method used in older ARM architectures with no support for hardware vectoring.
    2. Read the IRQVECREG / FIQVECREG registers in the VIM
      • These registers are read using the "LDR PC, [PC, #-0x1B0]" instruction at the IRQ and FIQ vector addresses in intvecs.asm. This implements a "fake" vectoring mechanism if the CPU's built-in hardware vectoring mode is not used
      • These registers hold the address of the ISR for the highest-priority pending interrupt.
    3. When CPU acknowledges an interrupt request in hardware vectored mode (enabled by HALCoGen by default)
    4. Writing a '1' to the INTREQ flag

    So if you want to clear an RTI compare match interrupt flag outside of the assigned ISR, you do need to clear it at the RTI plus use method 4 to clear the flag in the VIM.

    Regards, Sunil