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 Priorities for TMS470R1B1M

Other Parts Discussed in Thread: TMS470R1B1M

I am trying to understand more about interrupt priorities. So I understand that there are 2 interrupt types – Fast (FIQ) and normal (IRQ). FIQ interrupts have higher priority than IRQ.

 

Questions:

  1. All IRQ interrupts are at same priority – so IRQs are serviced on first come first served basis (is my understanding correct about this?).
  2. I noticed that there is channel (CIM) mapping. Does this provide any means to set priorities for various IRQ interrupts?
  3. I conducted a test – When the firmware hit a breakpoint in my serial ISR (for SCI1 – RX), I checked for CPSR register. This was set to 0x800000092 which indicates that an IRQ interrupt was generated. So I set the “I” bit in CPSR register to 0 (CPSR = 0x80000012) in order to allow other IRQ interrupts (was wondering if there is any other high priority IRQ interrupt) to trigger immediately while it is in the middle of processing SCI-RX interrupt. The moment I changed CPSR it would re-enter into SCI-RX ISR again – so now it is stuck in SCI-RX ISR forever. So my guess is that it tries to re-enter same ISR as SCI-RX ISR was not completely serviced. So is it possible to do nested interrupts? 

Pinakin

  • Pinakin Potdar said:
    • All IRQ interrupts are at same priority – so IRQs are serviced on first come first served basis (is my understanding correct about this?).

    Yes this is correct.  The CPU only has 2 different interrupt priority levels, FIQ and IRQ.

    FIQ is best dedicated to a single, low latency interrupt.  This is because if you avoid dispatching you can begin the FIQ interrupt handler immediately at the vector address of 0x1C  without any branches that cause pipeline discontinuities and add extra cycles of latency.

    And the FIQ has dedicated, banked registers that can be used to handle a single event w.o. saving/restoring any context to /from the stack.  Another times saving feature.

    IRQ gets used for all the other events.

    To accelerate IRQ dispatch, we provide the CIM which looks across all of the interrupt requests and outputs an index pointing to the highest priority interrupt channel that is active when the index is read.   This wasn't a standard feature in the ARM7TDMI days but is not pretty much standard on the Cortex series.. 

    The 'vector' generated by the CIM is a channel # or an index.   It's not a 32-bit address that you jump to.  Instead it is an index that you can use to jump indirectly through a vector table that you place in memory.       

    NB: If you do upgrade to the TMS570 you'll still have this mode available, but there is one further mode where the vector table is held in the VIM (replaces CIM) and the vector is provided directly to the CPU during the IRQ handshake such that you don't ever go to address 0x18 in this mode, you go directly to the ISR.   

    The CIM on the TMS470R1B1M prioritizes the channels in a fixed order.   Channel 0 should always be the highest priority, and 31 the lowest.

    But you can check me on this - CIM is documented in SPNU189H section 4.3.

    Pinakin Potdar said:
    I noticed that there is channel (CIM) mapping. Does this provide any means to set priorities for various IRQ interrupts?

    The IEM is used to control the mapping of peripheral interrupt requests to the CIM channels.   See SPNU211a.   So what this does is let you control the priority (in terms of which peripheral's  index is read from the IRQIVEC register of CIM first..).     So if you want a particular peripheral to be highest priority then map it to CIM channel 0 and when it is actively pending you'll get it's vector out of the IRQIVEC register [instead of any other lower priority pending interrupts mapped to channels 1-31..]    IEM I believe also lets you expand the CIM by mapping more than one request to an interrupt channel in CIM.

    Pinakin Potdar said:
    I conducted a test – When the firmware hit a breakpoint in my serial ISR (for SCI1 – RX), I checked for CPSR register. This was set to 0x800000092 which indicates that an IRQ interrupt was generated. So I set the “I” bit in CPSR register to 0 (CPSR = 0x80000012) in order to allow other IRQ interrupts (was wondering if there is any other high priority IRQ interrupt) to trigger immediately while it is in the middle of processing SCI-RX interrupt. The moment I changed CPSR it would re-enter into SCI-RX ISR again – so now it is stuck in SCI-RX ISR forever. So my guess is that it tries to re-enter same ISR as SCI-RX ISR was not completely serviced. So is it possible to do nested interrupts? 

    It is possible to nest interrupts, but to do it correctly you need to change the CIM Interrupt Mask Register (REQMASK) register.

    When you nest you're inside some interrupt handler at level 'N' of the CIM.

    If you have prioritized your requests going into CIM,  you only want to nest (allow interruptions of the ISR for channel N) from channels 0 to N-1..

    So you should be saving the REQMASK register on the the IRQ stack,  then changing it to disable all interrupts from the current channel N t channel 31.. 

    And you also need to save the LR and SPSR for the IRQ mode onto the stack or else these will be 'corrupted' by the nested interrupt.

    *then* you can re-enable interrupts in the CPSR.

    You of course have to undo these steps when you exit from the ISR for channel N...

    You have to decide if it's worth doing this or not.


    Another school of thought is to make use of an RTOS.   In the ISR you only do the critical peripheral register manipulation and notify the RTOS via some construct that there is a task related to handling the peirpheral that needs to be performed in the background.  There are even some constructs that carry data along w. the 'flag'.   Then get out of the ISR quickly.    Any significant processing gets done in a task and is prioritized by the RTOS.
    You just need to weigh this option against the overhead for nesting and decide on which is better...