Usage of C "volatile" Keyword in Embedded Development

Microcontroller Topics

Usage of C "volatile" Keyword in Embedded Development

Postby Herath » Fri Jul 29, 2011 5:20 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

Syntax: [ Download ] [ Hide ]
Using C Syntax Highlighting
  1. //Buffer for UART
  2. #ifndef BUFFER_H
  3. #define BUFFER_H
  4. #include<stdint.h>
  5. #define BUFFER_SIZE 128
  6.  
  7.         extern void writeToBuffer(uint8_t data);
  8.         //extern uint8_t readFromBuffer();
  9.         extern int isFull();
  10.         extern int isEmpty();
  11.         extern void emptyBuffer();
  12.  
  13. #endif
  14.  
  15.  
Syntax parsed in 0.006 seconds


buffer.c

Syntax: [ Download ] [ Hide ]
Using C Syntax Highlighting
  1. #include "buffer.h"
  2. #include<stdlib.h>
  3.  
  4. short writePointer=0;
  5. short readPointer=0;
  6. short currentSize=0;
  7.  
  8. volatile uint8_t data[BUFFER_SIZE];//data
  9.  
  10.  
  11. uint8_t readFromBuffer(){
  12.   uint8_t ret=0;
  13.                 if(!isEmpty()){
  14.           ret = data[readPointer];
  15.                         currentSize--;
  16.           readPointer = (readPointer + 1) & (BUFFER_SIZE-1); // This is the useful point is choosing the array length to be a power of two
  17.                 }
  18.                 return ret;
  19. }
  20.  
  21. void writeToBuffer(uint8_t newByte){
  22.                 if(!isFull()){
  23.           data[writePointer] = newByte;
  24.                         currentSize++;
  25.           writePointer = (writePointer + 1) & (BUFFER_SIZE-1); // This is the useful point is choosing the array length to be a power of two
  26.                 }
  27. }
  28.  
  29.  
  30. void flushBuffer(){}
  31. int isFull(){return (currentSize==BUFFER_SIZE);}
  32. int isEmpty(){return (currentSize==0);}
  33.  
  34.  
Syntax parsed in 0.008 seconds


ISR for USART_RXC_vect

Syntax: [ Download ] [ Hide ]
Using C Syntax Highlighting
  1. ISR(USART_RXC_vect){
  2. //copy data into buffer
  3.   writeToBuffer((uint8_t)UDR);
  4. }
  5.  
Syntax parsed in 0.005 seconds
User avatar
Herath
Support Team
Support Team
 
Posts: 432
Joined: Thu Aug 05, 2010 1:39 pm
Cash on hand: 1,861.30
Bank: 96,267.80
Medals: 1
EC_Achievment (1)

Invitations sent: 1
Registered friends: 0
Highscores: 6
Reputation point: 11
Corporal

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

Postby Neo » Sat Jul 30, 2011 4:04 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
    Syntax: [ Download ] [ Hide ]
    Using C Syntax Highlighting
    1. void myDelayFucntion1(){
    2.         int i;
    3.         for (i=0; i < 100000; i++);
    4. }
    5.  
    Syntax parsed in 0.005 seconds


    myDelayFucntion1.asm
    Syntax: [ Download ] [ Hide ]
    Using ASM Syntax Highlighting
    1. ;----------------------------------------------------------------------
    2. ; 111 | void myDelayFucntion2(){
    3. ;----------------------------------------------------------------------
    4. ;----------------------------------------------------------------------
    5. ; 112 | volatile int i;
    6. ;----------------------------------------------------------------------
    7. ADDB    SP,#2
    8. ;----------------------------------------------------------------------
    9. ; 113 | for (i=0; i < 100000; i++);
    10. ;----------------------------------------------------------------------
    11. MOV             *-SP[1],#0                      ; |113|
    12. MOV             AL,*-SP[1]                      ; |113|
    13. $C$L1:
    14. INC             *-SP[1]                         ; |113|
    15. MOV             AL,*-SP[1]                      ; |113|
    16. B               $C$L1,UNC                       ; |113|
    17. ; branch occurs ; |113|
    18.  
    Syntax parsed in 0.011 seconds


    myDelayFucntion2.c
    Syntax: [ Download ] [ Hide ]
    Using C Syntax Highlighting
    1. void myDelayFucntion2(){
    2.         volatile int i;
    3.         for (i=0; i < 100000; i++);
    4. }
    Syntax parsed in 0.005 seconds


    myDelayFucntion2.asm
    Syntax: [ Download ] [ Hide ]
    Using ASM Syntax Highlighting
    1. ;----------------------------------------------------------------------
    2. ; 105 | void myDelayFucntion1(){
    3. ;----------------------------------------------------------------------
    4. ;----------------------------------------------------------------------
    5. ; 106 | int i;
    6. ;----------------------------------------------------------------------
    7. $C$L2:
    8. ;----------------------------------------------------------------------
    9. ; 107 | for (i=0; i < 100000; i++);
    10. ;----------------------------------------------------------------------
    11. B               $C$L2,UNC                       ; |107|
    12. ; branch occurs ; |107|
    13.  
    Syntax parsed in 0.009 seconds

  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.
    Syntax: [ Download ] [ Hide ]
    Using C Syntax Highlighting
    1. #define SEC_CNT_REG     0xBA008216
    2. *((volatile unsigned char*) SEC_CNT_REG) = 0x01;
    Syntax parsed in 0.005 seconds

Since there isn't any requirement as such, you have no benefit in declaring the circular array with volatile.
User avatar
Neo
Site Admin
Site Admin
 
Posts: 2591
Joined: Tue Jul 14, 2009 8:37 pm
Cash on hand: 219,868.20
Bank: 15,536,454.00
Location: Colombo/London
Medals: 2
EC_Bronze_Star (1) EC_Achievment (1)

Invitations sent: 94
Registered friends: 12
Highscores: 13
Reputation point: 72
Lieutenant

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

Postby SukhdeepMankoo » Wed Aug 17, 2011 11:24 am

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
        .............
   }
}
User avatar
SukhdeepMankoo
 
Posts: 92
Joined: Tue Oct 27, 2009 2:20 pm
Cash on hand: 3,318.20
Medals: 1
EC_Achievment (1)

Invitations sent: 0
Registered friends: 0
Reputation point: 0
Lance Corporal


Return to Microcontrollers

Who is online

Users browsing this forum: No registered users and 3 guests