Usage of C "volatile" Keyword in Embedded Development

Microcontroller Topics
Post Reply
User avatar
Herath
Major
Major
Posts: 417
Joined: Thu Aug 05, 2010 7:09 pm

Usage of C "volatile" Keyword in Embedded Development

Post by Herath » Fri Jul 29, 2011 10:50 pm

I have read about importance of "volatile" keyword for embedded development in some places. But do not have a insight in to more details and how to use it properly. So, I hope that I can get a good explanation. :)

I am writing a circullar buffer which will be used by USART RX Complete ISR to write and by a NMEA parser to read. Therefore, I have declared the array holding the buffer data as "volatile". Is this necessary?. Thanks.

buffer.h

Code: Select all

//Buffer for UART
#ifndef BUFFER_H
#define BUFFER_H
#include<stdint.h>
#define BUFFER_SIZE 128

	extern void writeToBuffer(uint8_t data);
	//extern uint8_t readFromBuffer();
	extern int isFull();
	extern int isEmpty();
	extern void emptyBuffer();

#endif

buffer.c

Code: Select all

#include "buffer.h"
#include<stdlib.h>

short writePointer=0;
short readPointer=0;
short currentSize=0;

volatile uint8_t data[BUFFER_SIZE];//data

     
uint8_t readFromBuffer(){
        uint8_t ret=0;
		if(!isEmpty()){
	        ret = data[readPointer];
			currentSize--;
	        readPointer = (readPointer + 1) & (BUFFER_SIZE-1); // This is the useful point is choosing the array length to be a power of two
		}
		return ret;
}
 
void writeToBuffer(uint8_t newByte){
 		if(!isFull()){
	        data[writePointer] = newByte;
			currentSize++;
	        writePointer = (writePointer + 1) & (BUFFER_SIZE-1); // This is the useful point is choosing the array length to be a power of two
		}
}


void flushBuffer(){}
int isFull(){return (currentSize==BUFFER_SIZE);}
int isEmpty(){return (currentSize==0);}

ISR for USART_RXC_vect

Code: Select all

ISR(USART_RXC_vect){
//copy data into buffer
      writeToBuffer((uint8_t)UDR);
}
User avatar
Neo
Site Admin
Site Admin
Posts: 2642
Joined: Wed Jul 15, 2009 2:07 am
Location: Colombo

Re: Usage of C "volatile" Keyword in Embedded Development

Post by Neo » Sat Jul 30, 2011 9:34 am

I know two significant differences in embedded applications.
  1. Compiler will not optimise the functions that uses variables that are defined with volatile keyword
    Example: See the optimizer has completely removed the code of myDelayFucntion1where as the code of myDelayFucntion2 is there (You need to view the ASM code to see the difference).

    myDelayFucntion1.c

    Code: Select all

    void myDelayFucntion1(){
    	int i;
    	for (i=0; i < 100000; i++);
    }
    
    myDelayFucntion1.asm

    Code: Select all

    ;----------------------------------------------------------------------
    ; 111 | void myDelayFucntion2(){
    ;----------------------------------------------------------------------
    ;----------------------------------------------------------------------
    ; 112 | volatile int i;
    ;----------------------------------------------------------------------
    ADDB	SP,#2
    ;----------------------------------------------------------------------
    ; 113 | for (i=0; i < 100000; i++);
    ;----------------------------------------------------------------------
    MOV		*-SP[1],#0			; |113|
    MOV		AL,*-SP[1]			; |113|
    $C$L1:
    INC		*-SP[1]				; |113|
    MOV		AL,*-SP[1]			; |113|
    B		$C$L1,UNC			; |113|
    ; branch occurs ; |113|
    
    myDelayFucntion2.c

    Code: Select all

    void myDelayFucntion2(){
    	volatile int i;
    	for (i=0; i < 100000; i++);
    }
    myDelayFucntion2.asm

    Code: Select all

    ;----------------------------------------------------------------------
    ; 105 | void myDelayFucntion1(){
    ;----------------------------------------------------------------------
    ;----------------------------------------------------------------------
    ; 106 | int i;
    ;----------------------------------------------------------------------
    $C$L2:
    ;----------------------------------------------------------------------
    ; 107 | for (i=0; i < 100000; i++);
    ;----------------------------------------------------------------------
    B		$C$L2,UNC			; |107|
    ; branch occurs ; |107|
    
  2. Is used to access exact memory locations in RAM, ROM, etc... This is used more often to control memory-mapped devices, access CPU registers and locate specific memory locations.
    Example: Points to a single byte in memory and set 0x01 there.

    Code: Select all

    #define SEC_CNT_REG	0xBA008216
    *((volatile unsigned char*) SEC_CNT_REG) = 0x01;
Since there isn't any requirement as such, you have no benefit in declaring the circular array with volatile.
SukhdeepMankoo
Lieutenant
Lieutenant
Posts: 92
Joined: Tue Oct 27, 2009 7:50 pm

Re: Usage of C "volatile" Keyword in Embedded Development

Post by SukhdeepMankoo » Wed Aug 17, 2011 4:54 pm

volatile is used to avoid the compiler to make optimization for the variable.

Advantage:
suppose you are using the variable in interrupt routine as well as in main routine. it means interrupt can change the variable at any time depending upon the interrupt. second thing check what kind of optimization, you have selected for your code, you are optimization, you should always declared the variable is volatile. you have disabled the optimization of compiler, then you do not need to declare the variable as volatile. optimization is also compiler dependent.

e.g

#include................
volatile unsigned char var;
ISR()
{ .........
var++;
..........
}


int main()
{ ..........
while(1)
{ .............
get_value_of_var
.............
}
}
Post Reply

Return to “Microcontrollers”