Hi, is there a general rule when it is required in MikroC or MikroC Pro to declare variables as "volatile"?
Is this only an issue when using some data structures, which the compiler uses indirect addressing?
I always thought if a variable was defined as a ram location (ie all global variables) the compiler will always reference the ram location so they are "volatile" by default?
In what situations with MikroC or MikroC Pro should I always declare vars as volatile?
When to declare variables as "Volatile"?
When to declare variables as "Volatile"?
Using; EasyPic4, EasyPIC6, BigPic4, MikroC. MPLab, MPASM.
C since 1991, PIC asm since 1998. Author of many freeware and open-source goodies; www.RomanBlack.com Designer of the www.TalkBotBrain.com talking PIC project.
C since 1991, PIC asm since 1998. Author of many freeware and open-source goodies; www.RomanBlack.com Designer of the www.TalkBotBrain.com talking PIC project.
All variables are placed in RAM (not only globals), so the distinction with qualifier volatile means more than just type of memory.
I think that help explains it pretty well:
I think that help explains it pretty well:
The qualifier volatile implies that a variable may change its value during runtime independently from the program. Use the volatile modifier to indicate that a variable can be changed by a background routine, an interrupt routine, or I/O port. Declaring an object to be volatile warns the compiler not to make assumptions concerning the value of an object while evaluating expressions in which it occurs because the value could be changed at any moment.
Thanks for that, so since the ports and hardware registers must be volatile by default the only variables I need to declare as voltatile are ram variables I modify in an inerrupt?
The compiler seems to access those ram variables by just reading the ram location (when I check the assember output). So they seem to be volatile by default too.
I suppose what would be nice to know is when the compiler does NOT access the ram variable, like if there is a particular data structure, table, struct, etc that means the compiler won't access the ram but it will access a copy of the ram. If anyone knows the rules regarding that, please inform me.
The compiler seems to access those ram variables by just reading the ram location (when I check the assember output). So they seem to be volatile by default too.
I suppose what would be nice to know is when the compiler does NOT access the ram variable, like if there is a particular data structure, table, struct, etc that means the compiler won't access the ram but it will access a copy of the ram. If anyone knows the rules regarding that, please inform me.
Using; EasyPic4, EasyPIC6, BigPic4, MikroC. MPLab, MPASM.
C since 1991, PIC asm since 1998. Author of many freeware and open-source goodies; www.RomanBlack.com Designer of the www.TalkBotBrain.com talking PIC project.
C since 1991, PIC asm since 1998. Author of many freeware and open-source goodies; www.RomanBlack.com Designer of the www.TalkBotBrain.com talking PIC project.
Mostly, yes. Declaring variable volatile switches off some optimisation - it may sometimes be used to manually optimise the code (though the optimiser gets more agressive with every version ) or to be able to safely use the processor's indirect addressing mechanism.The_RB wrote:Thanks for that, so since the ports and hardware registers must be volatile by default the only variables I need to declare as voltatile are ram variables I modify in an inerrupt?
There's no other way to access a variable, but to read/write it's RAM location . Problem arises, when value of such variable is stored in another, internal one and, for example, both are used in a block of code. This may lead to unpredictable results if an interrupt happens changing only the original variable.The compiler seems to access those ram variables by just reading the ram location (when I check the assember output). So they seem to be volatile by default too.
There's no such mechanism, I'm afraid. One has to take care about it by oneself.I suppose what would be nice to know is when the compiler does NOT access the ram variable, like if there is a particular data structure, table, struct, etc that means the compiler won't access the ram but it will access a copy of the ram. If anyone knows the rules regarding that, please inform me.
-
- Posts: 2780
- Joined: 25 Dec 2008 15:22
- Location: Scotland
Hi RB,
for me this was always something that i used to control optimisation on systems which where perhaps not designed specifically as embedded.
imagine a variable which gets changed by external influence (input pin state changes PORT register value). ok, so now you have a loop which contains test logic on that variable while no other code exists in the loop which could alter the variable! with non-specific (or badly written) compilers the optimisation run would look at this and decide nothing can change this variable in this code loop so i will code reduce here BANG doesnt work in the embedded world where variables are hardware driven.
i once came across a good wiki example of this, try wiki search with C volatile variable or something along those lines. If i find it i will PM for your reading pleasure.
for me this was always something that i used to control optimisation on systems which where perhaps not designed specifically as embedded.
imagine a variable which gets changed by external influence (input pin state changes PORT register value). ok, so now you have a loop which contains test logic on that variable while no other code exists in the loop which could alter the variable! with non-specific (or badly written) compilers the optimisation run would look at this and decide nothing can change this variable in this code loop so i will code reduce here BANG doesnt work in the embedded world where variables are hardware driven.
i once came across a good wiki example of this, try wiki search with C volatile variable or something along those lines. If i find it i will PM for your reading pleasure.
Thanks people for the replies, I appreciate it!
Mince, I read the Wiki page you told me about, thanks too for that. It said pretty much what I already knew about use of volatile.
What I was after was any specific conditions that the MikroC/PRO compilers use that would help me decide when to declare volatile.
Now I'm just back to square one, ie code it up and look at the compiler output to see what it did... As always.
I'm not sure that's true. I think in some compiler operations (some math functions etc) the compiler copies the variable to the stack and works on it there, than only saves it back to ram after the operation is complete. So the compiler is not working on the ram variable but instead works on the copy.
It would be nice to know at what times the compiler is going to work on a copy and the times when it will always work directly on the ram location.
Mince, I read the Wiki page you told me about, thanks too for that. It said pretty much what I already knew about use of volatile.
What I was after was any specific conditions that the MikroC/PRO compilers use that would help me decide when to declare volatile.
Now I'm just back to square one, ie code it up and look at the compiler output to see what it did... As always.
Code: Select all
Janni said;
... There's no other way to access a variable, but to read/write it's RAM location ....
It would be nice to know at what times the compiler is going to work on a copy and the times when it will always work directly on the ram location.
Using; EasyPic4, EasyPIC6, BigPic4, MikroC. MPLab, MPASM.
C since 1991, PIC asm since 1998. Author of many freeware and open-source goodies; www.RomanBlack.com Designer of the www.TalkBotBrain.com talking PIC project.
C since 1991, PIC asm since 1998. Author of many freeware and open-source goodies; www.RomanBlack.com Designer of the www.TalkBotBrain.com talking PIC project.
Well, it is, but I understand now that you meant reading variable's value, wherever it was stored, i.e. by accessing the variable or it's copy.The_RB wrote:I'm not sure that's true.
Naturally, compiler does that to optimise code and that's where the volatile directve is sometimes needed. Looks like my explanation wasn't clear enough .I think in some compiler operations (some math functions etc) the compiler copies the variable to the stack and works on it there, than only saves it back to ram after the operation is complete.
I think that you're looking at it from wrong side. It's possible to analyse the optimisation methods used by the compiler and look thru code fragment after code fragment to decide if one of them will be used, but it's hardly practical (especially that new methods are going to be implemented soon). Much more practical is to use the volatile directive in all cases where the optimiser just could use variable's copy or it's value at compile time with undesired effect, i.e. for variables that areIt would be nice to know at what times the compiler is going to work on a copy and the times when it will always work directly on the ram location.
- declared at some SFR address (most of them),
- changed by ISRs,
- modified by indirect addressing (using INDF or similar instructions in C).
Note, that declaring a global variable volatile will not help in 'bad conditioned' cases where it's modified in a function and both are used in the same expression, like
Code: Select all
char dummy(char bb)
{
var8++;
return bb--;
}
void main() {
var8=var8+(3*dummy(5)+var8/2);
Code: Select all
var8=var8+(var8/2+3*dummy(5));