Storing integers and using ISR's

Running a simple ISR generated internally from one of the timers. Keeping my ISR's short I am doing a very basic calculation part of which is an integer that is generated in the main program. Knowing that this is an 8 bit machine I am guessing that writing this integer from the main program in C is going to take more than 1 clock cycle so I run the risk of the ISR being executed in the middle after only one byte has been written and I am going to be dealing with corrupted data. Alternately in the main program I can cli(), store the value and subsequently sei(), but in this case I believe I could miss the interrupt during this period. What are my options? Thanks

CLI doesn't cancel interrupts it just delays its execution. You will miss an interrupt if same interrupt happens twice or more when interrupts disabled. Your ISR will be invoked only once.

Might atomic access be what you're thinking of?

I can find nothing on "CLI just delays interrupt execution". Two interrupts cannot happen in my case during the couple cycles it takes to write an integer. But I cannot find any reference from Arduino wrt the interrupt just being delayed and then called immediately after sei() is executed in the main code. The atomic access I did not know about, better idea, but I do not need it for the simple code I am using, good to know for later tho. THx guys

Interrupts are queued. Only one of each type of interrupt however.

It is better to use interrupts() and noInterrupts() in your code. cli() and sei() are not portable.

Use a critical section as you describe -- just keep it short:

int
    x;
.
.
.

void loop()
{
    //critical section
    noInterrupts();
    var = SomeTable[x];
    interrupts();

    .
    .
    .
}

ISR foo( void )
{
    x = x + 1;
}

Interrupts that occur while the critical section executes won't be lost or forgotten (unless they're coming in on the same channel faster than the CS could finish, in which case they're likely going to be missed anyway...) They'll simply execute when the CS is over, after interrupts() is executed.

philosophictaylor: I can find nothing on "CLI just delays interrupt execution". Two interrupts cannot happen in my case during the couple cycles it takes to write an integer. But I cannot find any reference from Arduino wrt the interrupt just being delayed and then called immediately after sei() is executed in the main code.

From Atmag328 reference manual (chapter 4.7 Reset and Interrupt Handling):

If an interrupt condition occurs while the corresponding interrupt enable bit is cleared, the Interrupt Flag will be set and remembered until the interrupt is enabled, or the flag is cleared by software. Similarly, if one or more interrupt conditions occur while the Global Interrupt Enable bit is cleared, the corresponding Interrupt Flag(s) will be set and remembered until the Global Interrupt Enable bit is set, and will then be executed by order of priority.

Almost all other micro-controllers use similar logic.

cli():noInterrupts() and sei():interrupts() are exactly the same. No reason to use the first, when the last is Arduino specific.

define interrupts() sei()

define noInterrupts() cli()

I don't know what you have been planing for that integer in the ISR, but in worst case scenario can be done with Atomic utility.

Thanks guys, you answered the questions I asked, and even the questions I didn't know to ask, amazing!

Blackfin, in your example shouldn't the int x be declared as volatile?

Metallor: Blackfin, in your example shouldn't the int x be declared as volatile?

Probably. My thinking was that the critical section ensures the loop() operation on the variable completes before an interrupt occurs which could mess up registers etc. Without a CS, absolutely declare it volatile.

Without a CS, absolutely declare it volatile.

The need for the volatile keyword has nothing to do with the presence or absence of a critical section. The keyword is need on any variable external to the function, used in the function, that can be changed by an interrupt.

misha782: cli():noInterrupts() and sei():interrupts() are exactly the same. No reason to use the first, when the last is Arduino specific.

define interrupts() sei()

define noInterrupts() cli()

I don't know what you have been planing for that integer in the ISR, but in worst case scenario can be done with Atomic utility.

This is an Arduino-specific forum and "Arduino" is a lot bigger than 8-bit AVR. I spend about 40 hours per week in front of the Arduino IDE and I can't remember the last project that I used an AVR processor.

Neither of those solutions will work on my Arduinos.

Another example of a critical section, which is relevant to the original question on timers is that it is quite common to configure the timer registers with interrupts disabled. You don't want the ISR to run when you have the timer half-configured. In that case, you would usually clear the interrupt bit just before re-enabling interrupts.

MorganS: This is an Arduino-specific forum and "Arduino" is a lot bigger than 8-bit AVR. I spend about 40 hours per week in front of the Arduino IDE and I can't remember the last project that I used an AVR processor.

Correct me if I'm wrong, but from all the arduinos available only the arduine Due, Zero and Genuino 101 are using a processor that is not based on the avr 8-bit architecture. So if you are not using one of those, then you are actually using an AVR processor.

Where does the ESP8266 fit in your world? Intel's Edison or Galileo?

Yes I do a lot of work with the Due although it is not my favorite.

Well, I was assuming AVR so excuse my french then… Forgot to add a reference…

#define interrupts() sei()
#define noInterrupts() cli()

arduino.h Line#101-102

MorganS: Where does the ESP8266 fit in your world? Intel's Edison or Galileo?

Technically the ESP8266 is not an arduino, although it can be programmed by the arduino IDE. I just hit on this, because most arduinos are using the avr architecture, so it is pretty safe to assume the OP's arduino does so as well.

I don't believe it is safe to make that assumption. Lots of first-timers come here with non-AVR Arduino-compatibles.

MorganS: I don't believe it is safe to make that assumption. Lots of first-timers come here with non-AVR Arduino-compatibles.

philosophictaylor: Knowing that this is an 8 bit machine [...]

ESP8266, Intel's Edison and Intel's Galileo are all 32-bit architectures though ...

Without the OP stating which arduino he is using, this is guesswork anyways.