This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

dummy isr for unused interrupts

Hello together,

I'm using the XC866-Board from Infineon.
As I don't use all the availible interrupts in my program I would like to simply overwrite the NOPs of the interrupt vectors with RETIs to make sure the program does not accidentaly run into my code when an unused interrupt should occure.
Is there a simpler alternative than writing a interrupt service routine for every unused interrupt like

void dummyISR() interrupt xy
{
}

Thanks in advance

  • hi,

    Is there a simpler alternative than writing a interrupt service routine for every unused interrupt

    Indeed, just disable them with IE register(s). When they are individualy disabled then no ISR is called.
    As about dummy ISR then there is not easy way to do it because some interrupts require for their pending flag must be cleared by software. In such case, the simple RETI is not enough.

    Regards,
    Oleg

  • You're right about the IR-flags. I didn't think about that.
    So I'll just disable them all (except the ones I use of course) respectively I'll just not enable them (as they are disabled by default).

    Thanks for the quick answer!

  • Some people say it is good practise to provide a dummy ISR for every interrupt whether it is enabled or not, just in case the IE register gets written to by some program malfunction. I can't really see the point, though, as a program malfunction of that nature would most likely screw everything up anyway.

  • Why should it screw up everything?
    I mean if by some malfunction the IR-Bit of an unused interrupt is set and you reset it in an isr that does nothing else there's no problem, is there?
    But if an interrupt that's not used is called and there is no interrupt vector at its address the controller executes the NOPs until it gets to an instruction (maybe another isr or whatever was placed at the beginning of the memory after the interrupt vector table).
    This really causes your program to screw up everything if you're unlucky.

  • "Why should it screw up everything?"

    If the software has gone wild enough to write to a register you didn't intend it to then it is very unlikely it is going to recover gracefully.

    "I mean if by some malfunction the IR-Bit of an unused interrupt is set and you reset it in an isr that does nothing else there's no problem, is there?"

    No ISR will be called if the interrupt is disabled in IE.

    "But if an interrupt that's not used is called and there is no interrupt vector at its address the controller executes the NOPs until it gets to an instruction"

    In this case the controller will vector to the appropriate address and execute whatever instructions are there. I'm not sure where you get this idea about executing NOPs from.

    "This really causes your program to screw up everything if you're unlucky."

    If the interrupt was disabled yet some malfunction caused its ISR to be called then you are probably already screwed. Handling the interrupt isn't going to make much difference.

  • The issue of unused interrupts should not be an issue for production ready project.
    However it can really kill your productivity during development.

    Thus I make all unused interrupts like this

    ////////////////////////////////////////////////////////////
    //
    //  ISR 2: void ISR_EI1 (void)
    //
    
    void ISR_EI1 (void) interrupt 2 using 0
    {
      Icrash(); // just kill stray interrupts
    }  // end ISR_EI1
    And Icrash look like this
    void Icrash(void)
    {
    for (;;)
    }

    This does not cure stray interrupts but, it does provide an easily detected means of catching your screwup. When I stop the program in the ICE it will sit RIGHT THERE when the bug was IE or start code related.

    Erik

  • "If the software has gone wild enough to write to a register you didn't intend it to then it is very unlikely it is going to recover gracefully."
    No, but at least it could stay in the isr and not do any more harm...

    "No ISR will be called if the interrupt is disabled in IE."
    I know, but if I would enable all interrupts and have a dummy routine then it would jump to this routine and stay there.

    "I'm not sure where you get this idea about executing NOPs from."
    The NOPs are not in the isr but at the location of the interrupt vectors. And if the controller gets there it executes the NOPs

  • "The issue of unused interrupts should not be an issue for production ready project."
    The only 'production' my project will come to is one single controller. Insofar I thought it would not be too bad a idea.
    Thanks for the code, I'll try that.

  • This doesn't have to do with a dummy isr but here's a troubleshooting technique I find useful. I add a counter at the beginning of each isr (initialized to zero of course).

    uint isr_x_cntr=0;
    void isr_x(void) interrupt num_x
    {
    isr_x_cntr++;
    //rest of stuff goes here
    }


    If I'm working with a state machine whose transitions originate in different isrs examining the counts can tell me where things went wrong. Example, forgetting to clear the flag in a timer isr yields unbelievably high counts and you spot it right away in the watch window.
    Transmitting a SMBus packet may show one start count, one address/ACK count, 7 data byte/ACK counts and 1 data byte/NACK count. Showing those same counts everytime is a big clue about where to look in your code.
    Another example is where a vector has multiple sources, say the SPI overrun or write collision sources. It's nice to see not only what sources generated requests but how many were generated, sometimes you can correlate that number with some other activity in your system.

  • "No, but at least it could stay in the isr and not do any more harm..."

    I just can't see that that would make any difference. It would stop the main thread of execution at some unknown point after that thread had already run wild. You've no way of telling whether this is a better or worse situation than the one you've prevented.

    "I know, but if I would enable all interrupts and have a dummy routine then it would jump to this routine and stay there."

    But why would you want to do that? Assume a glitch on an unused external interrupt pin. If the interrupt is disabled nothing happens, if it is enabled the program hangs. What's the point?

    "The NOPs are not in the isr but at the location of the interrupt vectors. And if the controller gets there it executes the NOPs"

    If you're using C51 and you don't have an ISR for that interrupt you'll most likely find there's program code at the location that is vectored to. There's no reason to suspect you'll find NOPs there.

  • Hi,
    we realized something very similar. We needed an isr jump table to an adress with offset. So we place the jumps by hand into the code.

    VEC_SEG     EQU 2         ;Segment für Sprungziel z.B. 2 für 2:OFFSETh
    VEC_OFF     EQU 0000H     ;Offset im Segment z.B. 1000H für SEG:1000h
    
    VECT_TAB SECTION CODE AT 0    ; linken auf Adresse 0000h
    VEC_PROC PROC
      ; The RESET vector (0000H) is used by the boot application
      JMPS 0, 0800H             ;bm-Vektor-Tabelle auf 0x800 verschoben
      JMPS VEC_SEG,VEC_OFF+004H
    VEC_PROC ENDP
    VECT_TAB ENDS
    
    
    $if (MONITOR = 0)
     VECT_TAB0 SECTION CODE AT 8       ; Ohne Monitor linken auf Adresse 0008h
    $else
     VECT_TAB0 SECTION CODE AT 00CH    ; Mit Monitor inken auf Adresse 000Ch
    $endif
    
    VEC_PROC0 PROC
    $if (MONITOR = 0)
      JMPS VEC_SEG,VEC_OFF+008H
    $endif
      JMPS VEC_SEG,VEC_OFF+00CH
      JMPS VEC_SEG,VEC_OFF+010H
      JMPS VEC_SEG,VEC_OFF+014H
      JMPS VEC_SEG,VEC_OFF+018H
      JMPS VEC_SEG,VEC_OFF+01CH
      JMPS VEC_SEG,VEC_OFF+020H
      JMPS VEC_SEG,VEC_OFF+024H
      JMPS VEC_SEG,VEC_OFF+028H
      JMPS VEC_SEG,VEC_OFF+02CH
      JMPS VEC_SEG,VEC_OFF+030H
      JMPS VEC_SEG,VEC_OFF+034H
      JMPS VEC_SEG,VEC_OFF+038H
      JMPS VEC_SEG,VEC_OFF+03CH
      JMPS VEC_SEG,VEC_OFF+040H  ;CC0INT
      JMPS VEC_SEG,VEC_OFF+044H  ;CC1INT
      JMPS VEC_SEG,VEC_OFF+048H  ;CC2INT
      JMPS VEC_SEG,VEC_OFF+04CH  ;CC3INT
      JMPS VEC_SEG,VEC_OFF+050H  ;CC4INT
      JMPS VEC_SEG,VEC_OFF+054H  ;CC5INT
      JMPS VEC_SEG,VEC_OFF+058H  ;CC6INT
      JMPS VEC_SEG,VEC_OFF+05CH  ;CC7INT
      JMPS VEC_SEG,VEC_OFF+060H  ;CC8INT
      JMPS VEC_SEG,VEC_OFF+064H  ;CC9INT
      JMPS VEC_SEG,VEC_OFF+068H  ;CC10INT
      JMPS VEC_SEG,VEC_OFF+06CH  ;CC11INT
      JMPS VEC_SEG,VEC_OFF+070H  ;CC12INT
      JMPS VEC_SEG,VEC_OFF+074H  ;CC13INT
      JMPS VEC_SEG,VEC_OFF+078H  ;CC14INT
    VEC_PROC0 ENDP
    VECT_TAB0 ENDS
    

    In the same manner it should be possible to place RETI commands at a defined adress. I hope you will find something similar in A51 assemmbler because this code is written for the C167.

    ...Leo

  • Hi Leo,

    sorry for not answering so long but I've been on holiday :-)
    Thank you very much for the code - that's exactly what I was looking for!
    I'll see what I can find for the A51.

    Many greets