Does while(1) affect interrupts?

Thread Starter

Xavier Pacheco Paulino

Joined Oct 21, 2015
728
My question is: Doesn't the program get stuck at while (1)? How is the flow of this program? I mean, can the program execute what is inside while (1) loop and execute interrupts and then go back to while (1)?


#include <avr/io.h>
#include <avr/interrupt.h>
// TIMER0 with prescaler clkI/O/1024
#define TIMER0_PRESCALER (1 << CS02) | (1 << CS00)
void main()
{
// ... do something ...
// init Timer0
TIMSK |= (1 << TOIE0); // interrupt enable - here overflow
TCCR0 |= TIMER0_PRESCALER; // use defined prescaler value
// ... do something ...
while (1)
{
// ... do something ...
} /* end of while(1) */
}
// *** Interrupt Service Routine *****************************************
// Timer0 overflow interrupt handler (~65ms 4MHz@1024 precale factor)
ISR(TIMER0_OVF_vect)
{
// handle interrupt
}
 

Picbuster

Joined Dec 2, 2013
1,057
When your loop is to fast like
while(1) { }
A problem could occur depending on type of mpu and the number of interrupts per (micro/)second.
I did run into this problem with a PIC 16F690.
A few NOP's in the while solved the problem.
Picbuster
 

simozz

Joined Jul 23, 2017
170
When the interrupt is executed, the program counter jumps to the interrupt routine, which will being executed and then the program counter will jump back to the while(1) block.
A knowledge of Assembly programming and architecture would clarify this doubt.
 

spinnaker

Joined Oct 29, 2009
7,830
My question is: Doesn't the program get stuck at while (1)? How is the flow of this program? I mean, can the program execute what is inside while (1) loop and execute interrupts and then go back to while (1)?


#include <avr/io.h>
#include <avr/interrupt.h>
// TIMER0 with prescaler clkI/O/1024
#define TIMER0_PRESCALER (1 << CS02) | (1 << CS00)
void main()
{
// ... do something ...
// init Timer0
TIMSK |= (1 << TOIE0); // interrupt enable - here overflow
TCCR0 |= TIMER0_PRESCALER; // use defined prescaler value
// ... do something ...
while (1)
{
// ... do something ...
} /* end of while(1) */
}
// *** Interrupt Service Routine *****************************************
// Timer0 overflow interrupt handler (~65ms 4MHz@1024 precale factor)
ISR(TIMER0_OVF_vect)
{
// handle interrupt
}

You answered your own questions with your questions. ;)

For more detail, when the interrupt occurs, execution of the code within the while loop is halted. The current program counter is pushed onto the stack. The interrupt occurs and the interrupt handler is executed. When the is exited the program counter from the while loop is popped off of the stack and execution continues.

It is important that code withing your interrupt routine be brief so that no other interrupt events occur during its execution.
 

Parth786

Joined Jun 19, 2017
642
Hi
Please use code tags.
C:
#include <avr/io.h>
#include <avr/interrupt.h>
// TIMER0 with prescaler clkI/O/1024
#define TIMER0_PRESCALER (1 << CS02) | (1 << CS00)
void main()
{
    // ... do something ...
    // init Timer0
   TIMSK |= (1 << TOIE0); // interrupt enable - here overflow
   TCCR0 |= TIMER0_PRESCALER; // use defined prescaler value
  // ... do something ...
  while (1)
   {
      // ... do something ...
   }      /* end of while(1) */
}

// *** Interrupt Service Routine *****************************************
// Timer0 overflow interrupt handler (~65ms 4MHz@1024 precale factor)
ISR(TIMER0_OVF_vect)
{
    // handle interrupt
}
 

nsaspook

Joined Aug 27, 2009
16,258
When your loop is to fast like
while(1) { }
A problem could occur depending on type of mpu and the number of interrupts per (micro/)second.
I did run into this problem with a PIC 16F690.
A few NOP's in the while solved the problem.
Picbuster
Good point on providing time for interrupts to be processed in code that mainly runs a tight loop of instructions that are uninterruptible during execution. Some 'good' C compilers like to eliminate 'useless' code. Most have a predefined volatile NOP sequence that won't be tossed.
 

joeyd999

Joined Jun 6, 2011
6,204
Good point on providing time for interrupts to be processed in code that mainly runs a tight loop of instructions that are uninterruptible during execution. Some 'good' C compilers like to eliminate 'useless' code. Most have a predefined volatile NOP sequence that won't be tossed.
The only difference on a PIC is that the interrupt latency will average about 1 instruction cycle longer in a tight goto $ loop.

I disagree that this will affect interrupts in any other way, at least on a PIC.

Otherwise, there would be random times when interrupts broke the code (i.e. an interrupt exactly during the execution of a branch).

Someone will have to show me an exact instance of a goto $ breaking interrupts in order for me to believe otherwise.
 

nsaspook

Joined Aug 27, 2009
16,258
The only difference on a PIC is that the interrupt latency will average about 1 instruction cycle longer in a tight goto $ loop.

I disagree that this will affect interrupts in any other way, at least on a PIC.

Otherwise, there would be random times when interrupts broke the code (i.e. an interrupt exactly during the execution of a branch).

Someone will have to show me an exact instance of a goto $ breaking interrupts in order for me to believe otherwise.
You're right if the ISR rate is low and the main loop does nothing. It generally won't affect correctness on a low end PIC but it could affect interrupt latency and execution speed with resource contention on other PIC architectures. If it's an idle loop doing nothing it won't hurt and it might help on other type of cpu with a prefetch buffer if you copy the C code.
 

spinnaker

Joined Oct 29, 2009
7,830
You're right if the ISR rate is low and the main loop does nothing. It generally won't affect correctness on a low end PIC but it could affect interrupt latency and execution speed with resource contention on other PIC architectures. If it's an idle loop doing nothing it won't hurt and it might help on other type of cpu with a prefetch buffer if you copy the C code.

The TS is just a beginner please do not try to confuse the TS.
 
Top