How to safely convert/copy volatile variable? How to safely convert/copy volatile variable? c c

How to safely convert/copy volatile variable?


There is no such thing like a "built in" Workaround in C. Volatile tells the compiler, that the contents of a variable (or in your case the memory the variable is pointing at) can change without the compiler noticing it and forces the compiler to read the data direct from the data bus rather than using a possibly existing copy in the registers. Therefore the volatile keyword is used to avoid odd behaviour induced through compiler optimizations. (I can explain this further if you like)

In your case, you have a character buffer declared as volatile. If your program changes the contents of this buffer in a different context like an ISR for example, you have to implement sort of a synchronisation mechanism (like disabling the particular interrupt or so) to avoid inconsistency of data. After aquiring the "lock" (disabling the interrupt) you can copy the data byte by byte to a local (non-volatile) buffer and work on this buffer for the rest of the routine.

If the buffer will not change "outside" of the context of your read accesses I suggest to omit the volatile keyword as there is no use for it.

To judge the correct solution, a little bit more information about your exact use case would be needed.


Standard library routines aren't designed to work on volatile objects. The simplest solution is to read the volatile memory into normal memory before operating on it:

void ss_load_char(volatile char *digits) {  char buf[BUFSIZE];  int i = 0;  for (i = 0; i < BUFSIZE; ++i) {    buf[i] = digits[i];  }  int l=strlen(buf);  ...}

Here BUFSIZE is the size of the area of volatile memory.

Depending on how the volatile memory is configured, there may be routines you are supposed to call to copy out the contents, rather than just using a loop. Note that memcpy won't work as it is not designed to work with volatile memory.


The compiler warning only means that strlen() will not treat your pointer as volatile, i.e. it will maybe cache the pointer in a register when computing the length of your string. I guess, that's ok with you.

In general, volatile means that the compiler will not cache the variable. Look at this example:

extern int flag;while (flag) { /* loop*/ }

This would loop forever if flag != 0, since the compiler assumes that flag is not changed "from the outside", like a different thread. If you want to wait on the input of some other thread, you must write this:

extern volatile int flag;while (flag) { /* loop*/ }

Now, the compiler will really look at flag each time the loop loops. This may be must more what we intended in this example.

In answer to your question: if you know what you're doing, just cast the volatile away with int l=strlen((char*)digits).