|
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 bufferand 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 -------------------------------------------------
[Prev in Thread] | Current Thread | [Next in Thread] |