- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello all,
What is the best way to ensure safe access to shared data between an ISR and the main code ? In my application, the ISR reads a packet from the FIFO of a custom UART and saves it in a buffer provided to it upon registration. It then asserts a "ready" flag on the data. The main code polls for this flag and processes the data when it's ready. How can I ensure that during the main code's processing the data the ISR won't jump again and override it ? It may cause corrupted data. Say the main code has read 5 out of 10 bytes and then the ISR has overwritten them. When the main code resumes it will read the remaining 5 bytes from the new message. Is disabling interrupts during the main's code reading of the data the best option ? What are the common guideline when dealing with data synchronization in ISRs for Nios ? Thanks in advance http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/cool.gifLink Copied
3 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi eliben,
> What is the best way to ensure safe access to shared data between an > ISR and the main code ? That depends on what you are trying to do -- there's usually not a single "best way". > Is disabling interrupts during the main's code reading of the data the best option ? In most cases, no. This usually leads to those "mysterious" bugs that show up when baud rates, cpu clocks, etc. change. > What are the common guideline when dealing with data synchronization > in ISRs for Nios ? Here's a good reference: http://www.xml.com/ldd/chapter/book/ch09.html#t8 (http://www.xml.com/ldd/chapter/book/ch09.html#t8) A very simple and common technique is to use a circular buffer. The size of the buffer can be adjusted to meet your requirements ... provided you have adequate memory resources. Here's a basic overview: 1. The isr reads a "put" pointer, and writes its data. Then updates the put pointer. 2. The app compares the put pointer to a "get" pointer, when unequal, there is data. 3. The app reads (copies, consumes, whatever) the data, then updates the get pointer. Regards, --Scott- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The circular buffer is indeed useful, implementing a FIFO in software. I wanted, however, to avoid it and use something simpler, as I don't need a FIFO. I can, however, use a "trivial" FIFO which has depth 1 and "loses" all subsequent packets until the old ones has been read.
Which brings me to the question - are variable assignment and test atomic in Nios ? What I mean is:int ready;
// is this atomic ?
ready = 1;
// and is this atomic
if (ready == 1)
{
...
}
I ask because I can make my main code "deassert" the 'ready' flag when it finished reading the packet, and the ISR to ignore a new packet if 'ready' is still asserted. This way no stomping occurs (overflow messages are lost, which is acceptable). So I wonder whether it's possible for the ISR to run in the middle of asserting 'ready' ? If "ready = 1" is atomic, it certainly can't.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Don't forget to specify variables as "volatile" to prevent them being optimised out.
Sometimes I do tricks such as implementing S/R Flip Flops or counters in hardware, with different memory addresses to set/reset increment/decrement/read them. For simple FIFO buffers I'll do e.g. "ISR owns write pointer", "main thread owns read pointer" as Scott says. I will also use a "main thread is using this" flag as you've suggested. So//shared
volatile int MT_Access;
//main thread
MT_Access = 1;
<do something>
MT_Access = 0;
//ISR
if (0 == MT_Access)
{
<update something>
}

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page