I'm using a lot of volatile variables in my embedded firmware, but most of the time there is only one point in a function where I need to be sure the value is recent (at the start). But the rest of the function is referring to the same variable-name, and the value can be changed in the mean time, producing very unexpected code flow / results. I know this can be solved by using a temporary variable inside the function, but I was looking for a better solution.
Now I was wondering, instead of marking the whole variable as volatile, is there a way I could instruct the compiler (gcc) with a special keyword that I want to read the variable as if it was marked volatile, so I can use that keyword only once at the beginning of the function?
I'm a little confused about the scenario - if it's that you want one particular access to a variable to be treated as volatile, use
dest = *(volatile TYPE *)&src;
where TYPE is the type of src. You may also need
asm volatile ("" ::: "memory");
in carefully controlled locations, to prevent the compiler from moving loads/stores of other memory locations across the volatile read.
Also investigate C11's _Atomic types. (I'm not sure if GCC supports these yet.)
If your variable is in memory and your embedded system supports it you could use memory barriers. To make sure that nothing accesses the memory while you are reading the value out.
Related
As I know, "volatile" keyword is used to prevent compiler to optimize an unused variable. I am working with an STM32 board and I declare and initialise a variable as follows;
volatile uint32_t errorCallbackCounter = 24 ;
And never use it again.
While debugging, this variable is not seen. I am checking it with STMStudio( a real time variable watcher ) and when I want to import variables, the adress of errorCallbackCounter is seen as 0x0.
But when I use it in anywhere, it becomes visible.
So volatile keyword is not doing its job or -more probably- I know something wrong about it.
Thanks in advance.
Variables that are never used can be dropped by the linker
The volatile keyword affects the code that accesses the variable, preventing the access from being rearranged or dropped by the compiler. The line above is a variable definition with an initializer, that doesn't count as an access, it gets arranged before main() starts. But if it isn't referenced by accessible program code, isn't accessed at all, the linker thinks that it's safe to remove it, no one would notice.
You can however mark the variable as "it's needed no matter what" with
__attribute__((used))
placed at the end of the definition. This works with gcc, other compilers might have another directive for it. There is also a linker option that I can't recall right now to include all unused data sections in the executable.
volatile means the system will load this variable from memory each time it is accessed.
The compiler is not allowed to store the data directly into an register.
The volatile keyword prevents the compiler from performing optimization on code involving volatile objects, thus ensuring that each volatile variable assignment and read has a corresponding memory access. Without the volatile keyword, the compiler knows a variable does not need to be reread from memory at each use, because there should not be any writes to its memory location from any other thread or process.
Does gcc have an option to disable read/write optimizations for global variables not explicitly defined as volatile?
My team is running out of program memory in our embedded C project, built using gcc. When I enable optimizations to reduce code size, the code no longer works as expected because we have not been using the volatile keyword where we ought to have been. That is, I was able to resolve the presenting problem by declaring a few variables accessed in ISRs volatile. However, I don't have any level of certainty that those are the only variables I need to declare volatile and I just haven't noticed the other bugs yet.
I have heard that "some compilers" have a flag to implicitly declare everything volatile, but that I should resist the temptation because it is a "substitute for thought" (see https://barrgroup.com/Embedded-Systems/How-To/C-Volatile-Keyword).
Yes, but thought is expensive. Feel free to try to talk me out of it in the comments section, but I'm hoping for a quick fix to get the code size down without breaking the application.
You mean something besides -O0?
I expect that it's not too difficult to hack GCC for a quick experiment. This place in grokdeclarator in gcc/c/c-decl.c is probably a good place to unconditionally inject a volatile qualifier for the interesting storage_class values (probably csc_none, csc_extern, csc_static in your case).
/* It's a variable. */
/* An uninitialized decl with `extern' is a reference. */
int extern_ref = !initialized && storage_class == csc_extern;
type = c_build_qualified_type (type, type_quals, orig_qual_type,
orig_qual_indirect);
The experiment should tell you whether this is feasible from a performance/code size point of view and if it is, you might want to submit this as a proper upstream patch.
It's possible to do it by for example redefining all basic types as the same but with volatile specifier. Anyway if all variables in your code will be volatile I expect that size of your application will be larger than before optimizations.
My solution is: enable optimizations for part of the code. If your application got some functional architecture you can start enabling optimizations and test if this functionality works properly. It's much easier than optimize everything and analyze why nothing works.
While reading from a site a read that you can not make a global variable of type register.Why is it so?
source:
http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=/com.ibm.xlcpp8l.doc/language/ref/regdef.htm
In theory, you could allocate a processor register to a global scope variable - that register would simply have to remain allocated to that variable for the whole life of the program.
However, C compilers don't generally get to see the entire program during the compile phase - the C standard was written so that each translation unit (roughly corresponding to each .c file) could be compiled independently of the others (with the compiled objects later linked into a program). This is why global scope register variables aren't allowed - when the compiler is compiling b.c, it has no way to know that there was a global variable allocated to a register in a.c (and that therefore functions in b.c must preserve the value in that register).
Actually, GCC allows this. A declaration in global scope in the form:
register int foo asm ("r12");
Allocates the register "r12" (on x86_64) for the global "foo". This has a number of limitations and the corresponding manual page is probably the best reference to all the hassle global register variables would make:
http://gcc.gnu.org/onlinedocs/gcc/Explicit-Reg-Vars.html
Because it would be senseless. Global variables exist all the time the application is working. There surely is no free processor register for such a long time ;)
The register keyword has a different meaning than what its name seems to indicate, nowadays it has not much to do with a register of the processing environment. (Although it probably once was chosen for this.) The only text that constrains the use of a variable that is declared with register is this
The operand of the unary & operator
shall be either a function designator,
the result of a [] or unary *
operator, or an lvalue that designates
an object that is not a bit-field and
is not declared with the register
storage-class specifier
So it implements a restriction to automatic variables (those that you declare in a function) such that it is an error to take the address of such a variable. The idea then is that the compiler may represent this variable in whatever way pleases, as a register or as an immediate assembler value etc. You as a programmer promise that you wouldn't take an address of it. Usually this makes not much sense for global variables (they have an address, anyhow).
To summarize:
No, the register keyword is not
ignored.
Yes, it can only be used for stack
variables if you want to be standard conformant
Originally, register variables were meant to be stored in processor registers, but global variables have to be stored in the data or the BSS section to be accessible from every function. Today, compilers don't interpret the register storage class strictly, so it remains largely for compatibility reasons.
The register word is used in C/C++ as request to the compiler to use registers of processor like variables. A register is a sort of variable used by CPU, very very fast in access because it isn't located in memory (RAM). The use of a register is limited by the architecture and the size of the register itself (this mean that some could be just like memory pointers, other to load special debug values and so on).
The calling conventions used by C/C++ doesn't use general registers (EAX, EBX and so on in 80x86 Arch) to save parameters (But the returned value is stored in EAX), so you could declare a var like register making code faster.
If you ask to make it global you ask to reserve the register for all the code and all your source. This is impossible, so compiler give you an error, or simply make it a usual var stored in memory.
Some compilers provide a means of dedicating a register permanently to a variable. The register keyword, however, is insufficient. A compiler's decision to allocate the local variables for a routine in registers generally does not require coordination with anything in other source modules (while some development systems do register optimization between routines, it's far more common to simply define the calling convention so that all routines are allowed to freely alter certain registers (so a caller is responsible for saving the contents if they're needed after the function call) but must not alter others (so the called routine is responsible for saving and restoring the contents if the registers are needed in the function). Thus, a linker doesn't need to concern itself with register usage.
Such an approach is fine for local register variables, but useless for global ones. For global register variables to be useful, the programmer must generally tell the compiler which register is to be used for what variable, and make sure that such reservations are known to the compiler when compiling all modules--even those that don't use the register otherwise. This can be useful in embedded systems, especially with variables that are used by interrupts, but there's usually a very limited number (e.g. 2 or so) of such variables allowed in a system.
So do we all agree now? Do we all see that making a global variable a register variable would be a really, really bad idea? If the original C definition did not forbid it, it was probably because nobody thought anyone would actually implement it that way -- as they should not have especially back in CISC days.
Besides: modern optimizing compilers do a better job of deciding when to keep variables in registers than humans can do. If yours can't do it, then you really, REALLY need to get a better compiler.
Because they're in registers. It's a contradiction in terms.
Where is a volatile variable stored in the program memory (in which section)?
volatile is a type qualifier not a storage class specifier, so it does not determine storage location at all; it affects the definition of a variable's type, not its storage.
It simply forces the compiler to explicitly read a variable whose type is volatile from the variable's storage location (wherever that may be) rather than assuming that some previously read value in a register for example remains valid.
In C volatile just tells the compiler - "You don't have enough knowledge to assume the value of this variable hasn't changed". There is no "section" eg BSS, CSS for it.
Consider it a flag to the compiler to prevent certain types of optimisations. Its very handy in embedded programming, where memory at a certain address may "change" due to a hardware device input.
Here's a good explanation: http://www.embedded.com/columns/programmingpointers/174300478?_requestid=137658
The volatility of a variable does not change the place in which a variable is stored. What it changes is the semantics around how it is accessed with respect to reads and writes.
I do not believe the C standard says anything about the implementation of volatile. But typically, volatile guarantees release semantics for write operations on a variable and aquire semantics on read operations of a variable. This will not be true for every implementation though and you should read up on what your specific compiler guarantees
volatile has nothing to deal with storage class.
volatile just tells the compiler or force the compiler to "not to do the optimization" for that variable.
so compiler would not optimize the code for that variable and reading the value from the specified location, not through interal register which holds the previous value.
So, by declaring variable as volatile.. it gives garrantee that you will get the latest value, which may be alterred by an external event.
your code may be work fine if haven't declare that variable as volatile, but there may be chance of not getting correct value sometimes..
so to avoid that we should declare variable as volatile.
volatile is generally used when dealing with external events, like interrupts of hardware related pins.
example.
reading adc values.
const voltile means
you can not modify or alter the value of that variable in code. only external event can change the value.
controller pins are generally defines as volatile.
may be by declaring variable as volatile controller will do "read by pin" not "read by latch"... this is my assumtion. may be wrong...
but still there is lots of confusion when to choose variable as volatile..
A variable should be declared volatile whenever its value could change unexpectedly. In practice, only three types of variables could change:
Memory-mapped peripheral registers
Global variables modified by an interrupt service routine
Global variables within a multi-threaded application
Link : http://eetimes.com/discussion/beginner-s-corner/4023801/Introduction-to-the-Volatile-Keyword
So It is proffered to variable as volatile in such cases.
There's no reason for a volatile variable to be stored in any "special" section of memory. It is normally stored together with any other variables, including non-volatile ones. If some compiler decides to store volatile variables in some special section of memory - there's nothing to prevent it from doing so. But at the language level there's absolutely no reason for this.
Why are you asking such a question? What made you think that it should be stored in some special section of memory?
"Volatile" was used in C/C++ specifications to allow use of memory mapped devices. It directs the compiler not to optimize the variable defined with this keyword, just because the variable doesn't seem to change its state in compiler-visible code.
Consider the following:
volatile uint32_t i;
How do I know if gcc did or did not treat i as volatile? It would be declared as such because no nearby code is going to modify it, and modification of it is likely due to some interrupt.
I am not the world's worst assembly programmer, but I play one on TV. Can someone help me to understand how it would differ?
If you take the following stupid code:
#include <stdio.h>
#include <inttypes.h>
volatile uint32_t i;
int main(void)
{
if (i == 64738)
return 0;
else
return 1;
}
Compile it to object format and disassemble it via objdump, then do the same after removing 'volatile', there is no difference (according to diff). Is the volatile declaration just too close to where its checked or modified or should I just always use some atomic type when declaring something volatile? Do some optimization flags influence this?
Note, my stupid sample does not fully match my question, I realize this. I'm only trying to find out if gcc did or did not treat the variable as volatile, so I'm studying small dumps to try to find the difference.
Many compilers in some situations don't treat volatile the way they should. See this paper if you deal much with volatiles to avoid nasty surprises: Volatiles are Miscompiled, and What to Do about It. It also contains the pretty good description of the volatile backed with the quotations from the standard.
To be 100% sure, and for such a simple example check out the assembly output.
Try setting the variable outside a loop and reading it inside the loop. In a non-volatile case, the compiler might (or might not) shove it into a register or make it a compile time constant or something before the loop, since it "knows" it's not going to change, whereas if it's volatile it will read it from the variable space every time through the loop.
Basically, when you declare something as volatile, you're telling the compiler not to make certain optimizations. If it decided not to make those optimizations, you don't know that it didn't do them because it was declared volatile, or just that it decided it needed those registers for something else, or it didn't notice that it could turn it into a compile time constant.
As far as I know, volatile helps the optimizer. For example, if your code looked like this:
int foo() {
int x = 0;
while (x);
return 42;
}
The "while" loop would be optimized out of the binary.
But if you define 'x' as being volatile (ie, volatile int x;), then the compiler will leave the loop alone.
Your little sample is inadequate to show anything. The difference between a volatile variable and one that isn't is that each load or store in the code has to generate precisely one load or store in the executable for a volatile variable, whereas the compiler is free to optimize away loads or stores of non-volatile variables. If you're getting one load of i in your sample, that's what I'd expect for volatile and non-volatile.
To show a difference, you're going to have to have redundant loads and/or stores. Try something like
int i = 5;
int j = i + 2;
i = 5;
i = 5;
printf("%d %d\n", i, j);
changing i between non-volatile and volatile. You may have to enable some level of optimization to see the difference.
The code there has three stores and two loads of i, which can be optimized away to one store and probably one load if i is not volatile. If i is declared volatile, all stores and loads should show up in the object code in order, no matter what the optimization. If they don't, you've got a compiler bug.
It should always treat it as volatile.
The reason the code is the same is that volatile just instructs the compiler to load the variable from memory each time it accesses it. Even with optimization on, the compiler still needs to load i from memory once in the code you've written, because it can't infer the value of i at compile time. If you access it repeatedly, you'll see a difference.
Any modern compiler has multiple stages. One of the fairly easy yet interesting questions is whether the declaration of the variable itself was parsed correctly. This is easy because the C++ name mangling should differ depending on the volatile-ness. Hence, if you compile twice, once with volatile defined away, the symbol tables should differ slightly.
Read the standard before you misquote or downvote. Here's a quote from n2798:
7.1.6.1 The cv-qualifiers
7 Note: volatile is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation. See 1.9 for detailed semantics. In general, the semantics of volatile are intended to be the same in C++ as they are in C.
The keyword volatile acts as a hint. Much like the register keyword. However, volatile asks the compiler to keep all its optimizations at bay. This way, it won't keep a copy of the variable in a register or a cache (to optimize speed of access) but rather fetch it from the memory everytime you request for it.
Since there is so much of confusion: some more. The C99 standard does in fact say that a volatile qualified object must be looked up every time it is read and so on as others have noted. But, there is also another section that says that what constitutes a volatile access is implementation defined. So, a compiler, which knows the hardware inside out, will know, for example, when you have an automatic volatile qualified variable and whose address is never taken, that it will not be put in a sensitive region of memory and will almost certainly ignore the hint and optimize it away.
This keyword finds usage in setjmp and longjmp type of error handling. The only thing you have to bear in mind is that: You supply the volatile keyword when you think the variable may change. That is, you could take an ordinary object and manage with a few casts.
Another thing to keep in mind is the definition of what constitutes a volatile access is left by standard to the implementation.
If you really wanted different assembly compile with optimization