# Is setting software flags an effective use of interrupts?

I'm currently working on a microcontroller(Arduino) project in which I wish to use interrupts generated by pushbuttons and timers. However, I'm not sure if I'm 'effectively' using the interrupts. Here is my following architecture approach:

Let's say I have three interrupt sources: one tied to a digital input, and two tied to internal timers. Upon a hardware interrupt flag being set, the associated ISRs will run.

I also implement a 'main loop'. This main loop is untimed in the sense that it will continuously run as fast the processor allows. Within this loop, there is a series of software flags that are checked. These software flags are set in the ISRs. This loop is demonstrated in the pseudo code below:

/* main loop */
while(1)
{
// Check digital input flag
if(digi_in_flag)
// do some routine

//check timer 1
if(timer1_flag)
// do something routine

//check timer 2
if(timer2_flag)
// do something routine
}


Now the reason I'm doing this is to keep the ISRs short. Essentially, my ISRs only set a software flag that is then checked in main loop. Some of these routines lead to SPI/I2C communications, so I didn't want to place those comms in an ISR.

So my question: does this make sense? Does this actually create a more efficient program? I feel like I'm still 'polling' by checking software flags. Alternatively to using interrupts, I could have written a loop that just checks a digital input (as opposed to a software flag set by an interrupt), or I could have just made a function to check time duration (i.e. curr_time - prev_time) instead of relying on a timer interrupt to set a software flag.

Any thoughts on this? Also, I'm limited to a single thread in this design.

Thanks

• Have you considered idling until the interrupt occurs? Oct 8, 2016 at 17:08
• Why wasn't this asked in the Arduino stack exchange? Sep 13, 2018 at 16:04

To talk efficiency you need to identify what it means for you.

Your design is all right, but as you guess there're other options available like putting execution into ISR rather than in main loop. Let's consider the following:

• in your current design when interrupt happens only flag is set; execution, related to the "next" flag will be performed only when main thread finishes processing current flag, and your application will remember that there will be at least one related interrupt (flag is set = related interrupt occur at least once). This is more or less linear approach, which logically and physically separates processing of flags;
• now consider you put flag/interrupt processing into ISR. Then you should take very precise care about interrupt enable/disable. If new interrupt comes, it may interrupt service of current "flag" and start servicing new "flag". What (external) process, attached to service of first flag, will think about it? Next, if two same interrupts occur while previous servicing did not finish, will processing overlap and external device malfunction?

You see - there're a number of choices (we see 2 above), and you must select the strategy which best fits the attached device protocols and their timing. There're no wrong ways of doing things, there're ways which lead you into situations when (a) you just can not implement what you want specific way and (2) solution is not scalable (in time or capacity).

I believe your actual question is: "Is polling a flag faster than polling a pin directly?" If that is the case, a made the following test:

I put an Arduino polling a pin directly (Direct port manipulation):

if (readPIN == 1)


then It increments a counter and checks(polls) if it reaches 100 000 counts. if so, it prints the time that went by.

Afterwards I change the polling to a flag (int):

if (flag == 1)


And the results are*:

• Polling the pin directly: 277ms

• Polling the flag: 264ms

*this is not the actual time it takes to poll it 100 000 times. It is the time it takes to execute the software, altering only this one line. Thus, what matters is the difference (277 - 264 = 13ms)

Concluding, polling the flag is faster.