avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] About context saving in Vectors


From: dlc
Subject: Re: [avr-gcc-list] About context saving in Vectors
Date: Wed, 14 Jan 2009 12:06:54 -0700
User-agent: Thunderbird 2.0.0.18 (Macintosh/20081105)



David Kelly wrote:
On Wed, Jan 14, 2009 at 09:14:20AM -0700, dlc wrote:
The solution is to NOT call functions from within your ISR. That is just evil. Get your data in the ISR, put it in a mailbox or buffer
and have a regularly scheduled function handle the details from
outside the ISR.  I like to use ring buffers to store data from an
ISR.  When using the ring buffer the ISR modifies the "write" pointer,
not the read pointer and the processing function outside the ISR
modifies the read pointer and not the write pointer.  This means that
those pointers don't need "push/popped" in the ISR either.

Pointers, or indexes?

My bad, indexes. A pointer would be overkill and not as simple. I'm being a bit loose with my descriptions, mea culpa - Good catch.

Don't quite understand the push/popped reference, but if a variable is
accessed in both interrupt space and "user" space it needs to be
protected so that its uses "atomically".

Here is where I disagree with the gcc implementation. If you have an index to an array that is updated in an ISR and not even looked at outside of that ISR then you need to do nothing with that index variable when you enter the ISR. Conversely, if you have an index (variable) that is updated outside of the ISR and not used in the ISR then you don't need to do anything to the variable/register/memory when you enter/leave the ISR. You also don't need to be saving/restoring the data in the array when you enter the ISR since it won't be accessed until after it is written and the ISR exits.

When reading a ring buffer from outside the interrupt one generally
compares the head index to the tail index to know if there is data in
the buffer. An "atom" in an AVR is 8 bits so if one uses 8 bit indexes
then no special care is needed. But if 16 bit pointer that may span
multiple 256 byte pages one must block the interrupt before reading the
variable that the interrupt might modify.

But this is something warranting further study of your specific code. If
instructions are used that read the whole 16 bits without possibility of
an interrupt between the bytes then no protection is necessary.


Indeed. If the data is 8 bytes there is _really_ no issue. But even in the case of a 16 bit read/write, if you will not be reading a variable at the same time that you are writing to it, there is no issue. I have used ring buffers in ISR's where I specifically do not let overlapping operations occur (by design) then this programming technique works just fine. I typically use this for UART interrupts and the like where I am using 8 bit data in the array. Obviously if you are doing something different than (one writes, another one reads) where indexes aren't shared then more care is needed.

DLC
--
-------------------------------------------------
Dennis Clark          TTT Enterprises
www.techtoystoday.com
-------------------------------------------------




reply via email to

[Prev in Thread] Current Thread [Next in Thread]