Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AVR programming, interrupt handling

I develop a C application with atmega168a-pu and interrupts. I use the following interrupts:

ISR(TIMER0_COMPA_vect);
ISR(TIMER0_COMPB_vect);
ISR (TIMER2_COMPA_vect);
ISR(SPI_STC_vect);
ISR(TIMER1_COMPA_vect);
ISR (PCINT1_vect);

and my code looks like

int main(void){
///initialization etc.
   sei();
   while(1){
    ///do some stuff and wait the interrupts
   }
return 0;
}

I want to block all other interrupts when an interrupt occurs and enable the interrupts just before exiting the interrupt function.

Could you please explain it on a code snippet how I can do it?

EDIT: http://www.nongnu.org/avr-libc/user-manual/optimization.html#optim_code_reorder states that such usage cause reodering problem.

function(){
  cli();
  ..
  sei();
}
like image 281
Johan Elmander Avatar asked Oct 21 '22 05:10

Johan Elmander


2 Answers

The previous answer I posted here was based on the original question, not mentioning the reordering problem of the avr-gcc. Obviously it is too long ago, that I worked with the AVR but there was a bell ringing regarding disabling the interrupts

Revised Answer to the question

Protect interrupts from being interrupted

Atmel writes about the Interrupt handling in the databook:

When an interrupt occurs, the Global Interrupt Enable I-bit is cleared and all interrupts are disabled. The user software can write logic one to the I-bit to enable nested interrupts. All enabled interrupts can then interrupt the current interrupt routine. The I-bit is automatically set when a Return from Interrupt instruction – RETI – is executed.

Hence the behavior you ask for is already implemented in hardware.

Reordering issue

I also did some investigation on this reordering issue. Obviously there is huge disagreement whether this is an error of the compiler or not. It seems that the main risk of the reordering is that the interrupts are disabled for a longer period of time than they are expected to be. During my research I did not find a solution on that except of solutions causing more load/store activity which is not really an option I think.

like image 63
junix Avatar answered Nov 11 '22 17:11

junix


The question here is a bit strange because the default behavior of interrupts is that new interrupts are disabled (as in won't fire) while an interrupt is being serviced.

With regards to writing code that must not be interrupted I have generally found it enough to just use the atomic functionality in <util/atomic.h>. If this is not sufficient and you really must ensure there is no reordering perhaps you can write the critical sections in assembly.

It's possible that you could use memory barriers along with making everything in that code section volatile but that would be a fairly sizable pessimization in many cases. The assembly generated by this might hint at what you would write if you were to write the assembly by hand.

like image 41
shuttle87 Avatar answered Nov 11 '22 18:11

shuttle87