Advice regarding variable access from interrupt routines

14 views
Skip to first unread message

Alun Jones

unread,
Jan 7, 2013, 9:02:45 AM1/7/13
to jal...@googlegroups.com
Hi all,

Quite often I need to access a variable both from inside an interrupt service routine and from the main loop of  a program. When this is a
byte value, it's presumably safe to just mark the variable as a volatile and everything will be OK.

When it's a word or a dword, there is presumably the risk of an interrupt happening half way through an update or an access taking place in
the main loop. In this case, there is presumably a risk of getting a half-updated value back.

The example I'm looking at at the moment is reading an ADC value and returning it via I2C (using i2c_hw_slave_msg). My main loop is doing
the ADC conversions and storing the value in a word variable. The I2C interrupt-triggered procedure is picking up the most recent value and
returning it to the master.

Now, if the I2C interrupt routine fires while the main loop is half way through updating the variable, there's a good chance I'll send a bad value
to the master.

This is just one example - I've also hit the same issue whilst trying to write interrupt driven RTC routines.

I can see various ways around it, but none of them feel particularly satisfactory, especially where it's the main loop that's doing
the writes and the ISR needs to be able to read.

So I thought I'd ask - what do the rest of you do in this general situation? Is there any obvious (but not to me) solution?

Cheers,
Alun.


Oliver Seitz

unread,
Jan 7, 2013, 9:50:21 AM1/7/13
to jal...@googlegroups.com
Hi!

I'd double the variables, so there's a pair for each value. Plus a flag, which indicates which one of the pair is stable. When updating, I'd write to the "unstable" variable, and toggle the flag afterwards.

Greets,
Kiste
 


Von: Alun Jones <alun....@ty-penguin.org.uk>
An: jal...@googlegroups.com
Gesendet: 15:02 Montag, 7.Januar 2013
Betreff: [jallib] Advice regarding variable access from interrupt routines

--
You received this message because you are subscribed to the Google Groups "jallib" group.
To view this discussion on the web visit https://groups.google.com/d/msg/jallib/-/UzAaRlyhNnIJ.
To post to this group, send email to jal...@googlegroups.com.
To unsubscribe from this group, send email to jallib+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/jallib?hl=en.


Alun Jones

unread,
Jan 7, 2013, 11:54:26 AM1/7/13
to jal...@googlegroups.com, Oliver Seitz


On Monday, 7 January 2013 14:50:21 UTC, Kiste wrote:
Hi!

I'd double the variables, so there's a pair for each value. Plus a flag, which indicates which one of the pair is stable. When updating, I'd write to the "unstable" variable, and toggle the flag afterwards.

This is what I thought originally, and it would work in my specific case. But I'm trying to keep things general (the idea being to submit a new library and save me ever having to think it through again). It doesn't work if, for example, you have two interrupt routines which both decide to write to a variable (one after the other) while it's being read.

I think we probably need two variables, an "interruptible access locked" flag and an "I'm the most recently updated" flag. Then we have a read function and a write procedure, both of which take a flag saying "I'm being called from an interruptible context". A bunch of logic could then choose which instance is safe to access and, hopefully, do it without race conditions.

It was about this point where I thought I'd ask :-)

If nobody else jumps in with the blinding bit of inspiration, I'll have a bash at writing this...

Cheers,
Alun.

Oliver Seitz

unread,
Jan 7, 2013, 1:06:52 PM1/7/13
to jal...@googlegroups.com
Accidentally sent this private, sorry. Here for the list again ;-)


This is what I thought originally, and it would work in my specific case. But I'm trying to keep things general (the idea being to submit a new library and save me ever having to think it through again). It doesn't work if, for example, you have two interrupt routines which both decide to write to a variable (one after the other) while it's being read.

If two routines write to the same location, and there's no coordination of which has to write when, written data can be overwritten at any time. Just imagine, routine 2 always writes shortly after routine 1 does. The value of routine 1 will never be read back, the easiest way then would be not to implement routine 1 at all.





If nobody else jumps in with the blinding bit of inspiration, I'll have a bash at writing this...

I wish you success! :-)

Greets,
Kiste



Reply all
Reply to author
Forward
0 new messages