Coding with Interrupts Newbie

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello all,

I am asking if anyone knows of any documentation for common rules as far as "good coding" with interrupts. For instance, what happens if I am in an interrupt service routine and another interrupt is called? Is it safe to call other functions in an interrupt?

Basically, I am looking for good coding practices when using interrupts. I am familiar with C, but lacking experience with interrupts. I am kinda new to them. I understand how they work, kinda, but am looking for some good coding practices.

Any help, links, etc..would be of great help. I'm sure there are "basic" rules when dealing with interrupts. If it helps at all, I plan to use timer overflow interrupts to keep scannig button presses. What happens during that time, is up for grabs. You people in here seem to have some of the best experts and that is why I am here. Thanks for any basic, good coding practices regarding interrupts.

I have read the interrupt article in this forum, but ask for the basic "DO NOT's" and "DO's" of interrupts. I have rambled enough. Thanks for any help.

Thank you all!

c newbie

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

make your interrupt routines do the bare minimum to get the job done.

I believe that on the AVRs interrupts can be interrupted (unless the interrupts are turned off inside the interrupt handler), but this will vary across different micro controllers (eg, the PIC, which is a terrible creature, will not allow new interrupts to trigger while an interrupt is outstanding). The GCC port for the AVR provides signal handlers and interrupt handlers which are distinguished by the fact that signal handlers cannot be interrupted.

Calling a function from an interrupt can be a bad idea-- I know that this can cause serious problems on some microcontrollers, but I'm new to the AVRs, so you might get away with it-- you would need to write some code and examine the list file to see if this is kosher or not.

Typically, an ISR modifies some global flags that can be caught and handled later or updates a counter or records the value of some input.

Obviously, if you modify any globals in an ISR you need to make sure they are volatile. If the global being modified is more than an 8-bit value, then everywhere else that you use it you need to make sure that it's protected everywhere in the code (i.e. if you have a 16 bit variable x and you want to say x=x+x; in main, you should surround that statement with cli() and sei() so that you don't get something fun where your interrupt triggers after the lower byte has been modified, sets x to 0, then returns, and then the upper byte of x is set apropriately.

interrupts are nice creatures, and when you need one, nothing else will quite do the trick. However, (like threads) they can lead to really nasty bugs that are difficult to replicate and can make code very difficult to analyze. For many things, it's often better to stick with a polling loop, although this is generally considered ugly. The advantage of the polling loop is that you're a lot more likely to get it right and, depending on what you're doing in the loop, it may be significantly faster than using an ISR. The disadvantage is that as you add more things into your polling loop, it becomes increasingly ugly and difficult to maintain. At the point where you're checking whatever it is you're interested in between every few lines in a 20 line polling loop you need to switch to interrupts for your sanity and the sanity of others :-)

Hope this is somewhat useful.

-sean

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
For instance, what happens if I am in an interrupt service routine and another interrupt is called? Is it safe to call other functions in an interrupt?

I feel you may need to differentiate in your mind between an ISR and a function call. They are similar but not the same.

An interrupt is a function that effectively gets called by the hardware when an event occurs. The microcontroller itself is responsible for saving the current program counter and vectoring to your function. Your code is responsible for environment preservation, though in C this should be handled for you.

In the case of the AVR, my (strong) recommendation would be to declare your ISRs using SIGNAL, rather than INTERRUPT. That way the ISR cannot be interrupted during the execution of the ISR.

It is OK to call other functions from within an ISR, though one has to bear in mind that function call and return take CPU cycles and this may matter.

I hope that helps. If it is not clear, please post again.

Andy

If we are not supposed to eat animals, why are they made out of meat?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

for me, i have this keypad attached to external interrupt 0. what it basically do is detect he keypress and displays it on the LCD. all the important functions are called inside the ISR (determine the keypress, determine where the program will proceed based on the keypress, and displays the keypressed on the LCD). i have lots of menu, so you can imagine the external ISR 0 with lots of cases, if-then-else statements, and lots of function calls. but this doesn't really matter much to me since this is the only thing my program does. get keypress, determine the next state, the next state... plus an RTC which utilizes timer2's assynchronous feature, and uses a faster clock speed (7.3728MHz).

it should have matter most if i had my program done lots of things at the same time like "multi-tasking". its not really like multi-tasking but more on servicing lots of interrupts at almost the same time.

for my part, depends on what should be done on the program but better make your interrupts as short as possible.
:)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

AndyG wrote:

In the case of the AVR, my (strong) recommendation would be to declare your ISRs using SIGNAL, rather than INTERRUPT. That way the ISR cannot be interrupted during the execution of the ISR.

Just a note that the above is only valid for the GCC compiler. Every compiler has their own way of defining Interrupt Service Routines. (This is because the C Standard unfortunately does not specify a standard way to declare ISRs.)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In the AVR processor, the standard operating scheme is that ALL other ints are disabled when one interrupt is serviced.

This happens because the the standard interrupt mechanism clears the global interrupt enable when an interupt is detected and sets it back when an RETI is executed. The assumption is always that the enable was set because an interrupt could not have happened if it was not set.

That said, you CAN manipulate the global interrupt enable within the ISR. You have to be really careful, as it can get you into trouble.

One of the things you really need to watch for is handling of the status register within the ISR (in assembler). You should save it on entry and restore it on exit. If you do not, then ANY instruction in the ISR that changes the status register can muck things up in the code that was interrupted. For example, if you do a TST instruction, expecting to use the result in a branch and the INT happens between the TST and the branch AND the status register is changed by the ISR, your branch can go bad. Now, you might say, what are the odds of doing that? The answer is WAAAAY too high!

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
One of the things you really need to watch for is handling of the status register within the ISR (in assembler). You should save it on entry and restore it on exit. If you do not, then ANY instruction in the ISR that changes the status register can muck things up in the code that was interrupted.

is this done automatically in C?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jay warren wrote:
is this done automatically in C?

Yes it is.

/* John Butera */