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.

interrupt nesting question

Other Parts Discussed in Thread: TMS320C6711D

I have a question..

Assume IntA allows nested interrupts. so IntB, which is of higher priority, interrupted IntA. While executing IntB, in case if IntaA occurs (interrupt flag gets set), then while exiting IntB whether it will go to IntA-starting or to the location where it left IntA earlier.

  • A key thing to keep in mind is that the hardware priority only functions as a tie breaker in the case there are multiple pending interrupts.  When you allow nested interrupts in IntA the way you determine whether another interrupt will pre-empt you is by altering IER prior to re-enabling GIE.

    The answer to your question depends on how you've handled IER within the ISRs for IntA and IntB.  I would recommend that at a minimum IntA disable itself in the IER, probably others too (lower priority interrupts).  If IntA disabled itself in IER and then the IntB ISR properly saved and restored IER then upon return from IntB you would see the original IntA complete its execution before the next IntA.

    If you want to nest interrupts I highly suggest using BIOS.  There are a lot of tiny details that you need to get precisely right.  BIOS makes it easy to setup the interrupts with whatever nesting you like and it gets the sequence of register modifications exactly right.  This article gives a quick tutorial on how to setup an interrupt using BIOS.  In particular the "interrupt mask" box controls the nesting behavior.

  • I have an existing code which does not use BIOS.

    In that I'm using nested interrupts. It has an ADC interrupt which disables itself first and enables GIE,  processes the signals and calls a function to make a packet update CRC and finally writes in to a buffer. There is only one high priority interrupt above ADC interrupt and that is EDMA interrupt. This EDMA interrupt copies the  buffer in to EDMA PING/PONG buffer and sets a flag.

    interrupt void ADC_ISR()        /* ADC interrupt service routine */
    {

        .....

        /* save interrupt registers */
        irp_save = IRP;
        ier_save = IER;
        csr_save = CSR;

        /* disable the ADC interrupt  */
        INTR_DISABLE(7);

        /* let other interrupts proceed */
        INTR_GLOBAL_ENABLE();

        .........

       ..../* do the processing*/

        .......

         update_packet();

        /* return interrupt registers */
        INTR_GLOBAL_DISABLE();
        IRP = irp_save;
        IER = ier_save;
        CSR = csr_save;

    }

    With this code, rarely  i'm seeing packet corruption. Packet has few bytes invalid but CRC is good. Means packet corruption is happening before CRC update.

    Any clue why it could get corrupted. Good amount of stack  (0x1200) allocated.

    I'm assuming only higher priority interrupts will be executed if they occur while ADC interrupt is getting executed.

    I'm not clear from documentation, if lower priority interrupts also can interrupt the ADC interrupt.

    Is there any possibility that, nested interrupt causing some damage to register usage.

    I saw the assembly listing. While writing registers on to stack at the entry of intterupt it used STW instruction but while retrieving from stack at the exit it used LDDW instead of LDW and loaded in pairs. Is this normal.

    What are the side effects nested interrupts.

    Listing source code for EDMA interrupt here..

    interrupt void edma_ISR()
    {

            /* change the ping pong buffer */
        if (*((volatile unsigned int *) (EVENTC_PARAMS + SRC)) ==
                                                (unsigned int) &mcbsp_xmit_buffer[PING])
            available_xmit_buf = 1;
        else
            available_xmit_buf = 0;
       
        mcbsp0_xmit_complete = 1;
        memcpy(&mcbsp_xmit_buffer[available_xmit_buf], &dcload[available_data_buf], 15);

        /* reset the interrupt */
        *((volatile unsigned int *) CIPR) = 0x00001000;   
    }

  • BTW, the DSP here is TMS320C6711D

  • Any enabled interrupt will be capable of pre-empting you once GIE is enabled. Prior to enabling GIE you should modify IER such that only the interrupts you want to be capable of pre-empting you are enabled. The hardware priority only serves as a tie-breaker for multiple pending interrupts. Practically speaking the IER configuration will be much more important.
  • OK, even if all enabled interrupts can pre-empt the ADC interrupt it should not be problem. There is not much activity on other enabled interrupts (there are 3 other interrupts enabled which i assume should not use more than some tens of bytes of stack). Moreover the situations i'm seeing should not have these interrupts occurring.

    Do you know of any possible side effects with nested interrupts other than stack overflow.

  • The main consequence of nested interrupts is larger stack requirement.  You should verify you have not overflowed the stack using the method described in this article

    Of course you could also run into timing issues that are specific to your code, but you'll be the best judge of that.  For example, if two ISRs are accessing a shared global structure and it's possible for one ISR to access before another ISR finishes then maybe you'd end up with the packet corruption you mention (i.e. if the structure is in an "inconsistent" state when the other ISR pre-empts it).