Warning when using "volatile"

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello

I've got an issue with the usage of "volatile"
I know, that it's necessary to declare a global variable "volatile", if that variable is used in an ISR as well as in the main(). I also know that if that variable is >8Bit the access has to be atomic in the main() (i.e. sei(), cli(),  save SREG etc).
So far so good.

 

I also think, that a global variable which is used in an ISR in another file and acccessed in a second one (the "main-file") that variable should be declared "volatile" - i.e. there's a buffer, which is filled in an RECEIVE ISR of an USART in one file and when that buffer is accessed in the second "main-file" it has to be declared "volatile".

However I do get a warning when I compile:
"warning: passing argument 1 of 'strlen' discards qualifiers from pointer target type " (see "main-file" => "while(zahl < strlen(rec_buf){...)
- when i declare that buffer "char rec_buf[BUF]" "volatile" (= extern volatile char rec_buf[BUF])

- no warning, when "char rec_buf[BUF] is NOT "volatile"

see my example:

in *.h file
#define BUF 80						/* length of buffer*/
extern char rec_buf[BUF];			/* Char-Buffer for USART RECEIVE */

in lib:
char rec_buf[BUF];					/* Char-Buffer for USART RECEIVE */			

/* ISR - receiving data  - USART RX Interrupt */
extern ISR(UART0_RECEIVE_INTERRUPT) {
	c = UART0_DATA;							/* BUF = 80 => 0.. 79 */
	if((rec_count < BUF)||(c !='e')) {		/* i.e rec_count = 78 */
		rec_buf[rec_count] = c;
		rec_count++;						/* rec_count = 79 => END!!! */
	}
	if((rec_count == (BUF-1))||(c== 'e')) {	/* rec_count == 80-1 or c = e */
		rec_buf[rec_count] = '\0';			/* terminating end of string */
		rec_flag = 1;						/* receive finished - set rec_flag = 1*/
		rec_count = 0;
	}
}

in "main-file":
while(zahl < strlen(rec_buf)) {
			if(rec_buf[zahl] !='#') {
				temp_buf[temp_count] = rec_buf[zahl];
				temp_count++;
				zahl++;
			}

so: 
"extern volatile char rec_buf[BUF]"  => warning 
"extern char rec_buf[BUF]" => no warning

My system: WIN7 32Bit, WINAVR 20100110, AVRStudio 4.18 SP3
            
perhaps someone has an idea why that warning occurs and how to modify my programme so that's compiling without warning

 

thanks in advance

best regards

Hero_123

This topic has a solution.
Last Edited: Tue. Oct 15, 2019 - 02:34 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

But the warning tells you EXACTLY why this is happening. It says:

 passing argument 1 of 'strlen' discards qualifiers from pointer target type 

If you look up strlen() in any C manual you will find:

 

size_t strlen ( const char * str );

 

So this expect you to pass something of type char * (or, preferably, const char *) but if you have:

 

extern volatile char rec_buf[BUF]

 

then the pointer is not "char *" but "volatile char *" so the warning you that strlen() is going to treat this as a pointer to non-volatile char rather than as a pointer to volatile char (which it is).

 

if (as you know) this warning is benign you can tell the C compiler not to worry with:

N = strlen((char *)rec_buf);

The (char *) cast here says "yeah, I know it has a volatile qualifier but you don't need to worry about that, just treat it as a plain char *"

 

One question all this raises is why on earth you would ever want to make an entire buffer "volatile" anyway? I can't help thinking you are trying to fix a problem you should not have in the first place !

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

clawson wrote:
One question all this raises is why on earth you would ever want to make an entire buffer "volatile" anyway?

+1

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello clawson

 

Thanks a lot for your fast reply yes

 

Yeah, I should have known that (char *).

 

That buffer "volatile" - the ISR (RECEIVE - ISR) fills that buffer (i.e. a user enters values via hTerm), and only when a button's pushed those values of the buffer will be read & processed then. 

And it's possible that while receiving (and thus filling the buffer) the buffer is also read.

 

Hero_123

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Normally, you'd do the buffering via a Ring Buffer, where only the pointers need to be volatile - not the entire buffer

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello awneil

 

Thanks for that hint yes

 

Me being a newbie - I was quite happy to get that to work (USART etc) - now I'll try to make the next steps - ring buffer etc wink

 

best regards

 

Hero_123