Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

How to avoid read and write at same time from different processes

Status
Not open for further replies.
I am confused with the following issue. I want to read some variable like adccount from the main but it will get updated in the interrupt routine. How should i make sure that while i am reading the variable in the main it is not simultaneously getting updated in the interrupt routine. Please help the methodology i need to implement to avoid such problems.
 
It won't matter!! there is no "simultaneous" variable access on a normal micro... There isn't threads like multitasking processors..

If the variable is being updated in the ISR, your main will wait until it's finished... In other words... Main has been interrupted..
 
If the variable is being updated in the ISR, your main will wait until it's finished... In other words... Main has been interrupted..

(assuming 8 bit device) If you are reading 16 bit or 32 bit variable in main, it is possible to interrupt in the middle of that operation.. update the variable and return to main. Then part of the bytes read will be from the old value and some will be from the updated value.

What you need to do is declare the variable "volatile" and disable interrupts when you are using the variable (this is called atomic operation).

C:
volatile uint32_t addcount;

int main(void)
{
    uint32_t copyOfAddcount;
   
    while(1)
    {
        /* Atomic operation */
        cli(); /* Disable global interrupts */
        copyOfAddcount = addcount;
        sei(); /* Enable global interrupts */
    }
}

More robust way would be to first save the state of global interrupts, disable them and after atomic operation is done, restore the state of global interrupts.
 
Last edited:
(assuming 8 bit device) If you are reading 16 bit or 32 bit variable in main, it is possible to interrupt in the middle of that operation.. update the variable and return to main. Then part of the bytes read will be from the old value and some will be from the updated value.

What you need to do is declare the variable "volatile" and disable interrupts when you are using the variable (this is called atomic operation).

C:
int main(void)
{
    volatile uint32_t addcount;
    uint32_t copyOfAddcount;
   
    while(1)
    {
        /* Atomic operation */
        cli(); /* Disable global interrupts */
        copyOfAddcount = addcount;
        sei(); /* Enable global interrupts */
    }
}

More robust way would be to first save the state of global interrupts, disable them and after atomic operation is done, restore the state of global interrupts.
True!! But in all the years I have been doing this, it has never been a problem, as the very next read will be correct... Even if the variable was updated in the ISR the difference would be minimal... If on the other hand the OP has a really fast moving analogue signal, then reading the variable whilst the ISR is disabled would be the way to go... I would very much doubt this to be the case though!!
 
I program safety products (stove guard), so I have to get those kind of details correct, even if the chance of something bad happening is only theoretical.
 
I program safety products (stove guard), so I have to get those kind of details correct, even if the chance of something bad happening is only theoretical.
I fully understand.... But the questions the OP has been asking, are the normal neewby questions...

I very rarley have an ISR that does anything but raise an aware flag!!
 
Even if the variable was updated in the ISR the difference would be minimal.
example of two byte variable (in dec because that is how I think)
var=49 and is being changed to 51.
The program reads the 9 then is interrupted.
The interrupt changes the data from 49 to 51.
The program reads the 5.
The data is 59 by error.

This could turn your furnace on for 1 minute.
This could be a timer for you pacemaker.
Not good for a data logger.

I agree, turn off interrupts during read.
or
If the interrupts are time critical, then within the read process, test if interrupt happened and re-read.
 
I'm no micro/programing expert, but I have worked on safety critical, and mission critical, real time systems where handling this aspect is fundamental. In fact, this aspect is universal in software, hardware, documentation, and other areas.

In general, you need an access flag:

Any process, wishing to read or modify the data first checks the access flag. If the access flag is true, access is allowed. If it is false access is denied.

The first duty of any process accessing the data, for reading or writing, is to set the access flag to false.

It is the responsibility of any process modifying the data to ensure that the data is in a good state before it sets the access flag to true, and exits.

All that remains is to employ contention resolution for reading and altering the access flag. But that is another subject and not normally difficult: the bus contention algorithm used on Ethernet is one possibility.

All this may sound complex, but in practice, the code/design is pretty straightforward.:)

spec
 
example of two byte variable (in dec because that is how I think)
var=49 and is being changed to 51.
The program reads the 9 then is interrupted.
The interrupt changes the data from 49 to 51.
The program reads the 5.
The data is 59 by error.

This could turn your furnace on for 1 minute.
This could be a timer for you pacemaker.
Not good for a data logger.

I agree, turn off interrupts during read.
or
If the interrupts are time critical, then within the read process, test if interrupt happened and re-read.
I was speaking figuratively!!! Like I said I very much doubt this is the case BUT!! If the ADC result could cause a major issue, then you would probably run an RTOS or something....
 
Thanks for all replies. Can someone please provide me link for designing layered architecture document for embedded system. It will be of great help for me. I want to separate the driver layer from application. It has communication channels like can and other peripherals.
 
If the interrupts can't come close together (almost overlap), another method is to compare the value to itself.

I.E.
Code:
    var=irqvar;           //get var
    if(var!=irqvar)       //has it changed
        var=irqvar;       //yes, so fetch it again

Mike.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top