This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

volatile keyword

The application note suggests to wrap a timer tick variable in a function which disables all interrupts, reads and copies the variable into a temp, re-enables interrupts, then returns the temp.

Can the variable be accessed directly outside of the ISR without disabling interrupts if the timer tick variable is declared as "volatile?"

Parents

  • The hidden assumption with this second fix is that the counter variable changes at a much slower rate than you can sample with the assign-test-assign sequence. For typical slow timer ticks and their rollover, this may often be true.

    Note that if you write a loop, you'd better be sure that the update frequency of the counter doesn't alias with your time to execute the loop, or your code will get stuck.

    In general, the second assignment has all the potential problems of the first; if the value can change while you do the first assignment, what stops it from changing while you do the second? In the case of the timer tick, the reason it "stops" changing is because the tick rate is slow compared to the sampling rate.

    Masking interrupts also assures that the counter can't change in the original instance, because it's the interrupt routine that changes it. Stopping the interrupt stops the counter. Compare with a free-running 16-bit hardware timer; it will change even though there's no interrupt, so masking interrupts in this case wouldn't help.

    Then consider something like another processor updating shared memory, or a 16-bit A/D converter sampling fluctuating values. In this case, there's no guarantee that the value doesn't change during the second assignment any more than in the first; adding the test and re-read doesn't make the code any more correct. A double assignment isn't a general solution to the problem of atomic access to a value wider than your data bus.

    Ultimately, you have to be sure the value you're trying to read doesn't change while you read it over multiple bus cycles and/or instructions. The method for ensuring that lack of change will depend on exactly what you're trying to read and how it gets updated. You might be able to detect bogus values and re-read, you might have to mask interrupts, you might have to synchronize with another processor, you might even need hardware to latch a value for you to keep it constant while you read it.

Reply

  • The hidden assumption with this second fix is that the counter variable changes at a much slower rate than you can sample with the assign-test-assign sequence. For typical slow timer ticks and their rollover, this may often be true.

    Note that if you write a loop, you'd better be sure that the update frequency of the counter doesn't alias with your time to execute the loop, or your code will get stuck.

    In general, the second assignment has all the potential problems of the first; if the value can change while you do the first assignment, what stops it from changing while you do the second? In the case of the timer tick, the reason it "stops" changing is because the tick rate is slow compared to the sampling rate.

    Masking interrupts also assures that the counter can't change in the original instance, because it's the interrupt routine that changes it. Stopping the interrupt stops the counter. Compare with a free-running 16-bit hardware timer; it will change even though there's no interrupt, so masking interrupts in this case wouldn't help.

    Then consider something like another processor updating shared memory, or a 16-bit A/D converter sampling fluctuating values. In this case, there's no guarantee that the value doesn't change during the second assignment any more than in the first; adding the test and re-read doesn't make the code any more correct. A double assignment isn't a general solution to the problem of atomic access to a value wider than your data bus.

    Ultimately, you have to be sure the value you're trying to read doesn't change while you read it over multiple bus cycles and/or instructions. The method for ensuring that lack of change will depend on exactly what you're trying to read and how it gets updated. You might be able to detect bogus values and re-read, you might have to mask interrupts, you might have to synchronize with another processor, you might even need hardware to latch a value for you to keep it constant while you read it.

Children
No data