C's volatile keyword is a qualifier that is applied to a variable when it is declared. It tells the compiler that the value of the variable may change at any time--without any action being taken by the code the compiler finds nearby. The implications of this are quite serious. However, before we examine them, let's take a look at the syntax.
Barr Group Principal Engineer Dan Smith offers important tips for how to best use the volatile keyword in Embedded C.
Related Articles
Related Courses
- Embedded Software Boot Camp
- Hardware Interfacing with C
- Firmware Defect Prevention for Safety-Critical Systems
- Top 10 Ways to Design Safer Embedded Software
- Best Practices for Designing Safe & Secure Embedded Systems
- Best Practices for Designing Safe Embedded Systems
- Debugging Embedded Software on the Target
Transcript
Andrew Girson: Hi. I’m here today with Dan Smith, Principal Engineer with Barr Group. And we’re here to talk about the use of the volatile keyword in embedded C. So Dan, to start with, what does the volatile keyword tell a compiler? What does it – what is it telling the compiler?
Dan Smith: The volatile keyword, which is part of both the C programming language and the C++ programming language, and I’m greatly oversimplifying things here, but it effectively tells the compiler to inhibit optimizations around read or write accesses.
Andrew: Compiler optimization.
Dan: Yeah, compiler optimizations, code generation optimizations pertaining to read or write accesses to that variable that object that are with.
Andrew: Okay, all right. So, what’s the purpose of that? When should the volatile keyword be used in – because of what it tells the compiler?
Dan: Right. Well, so in embedded systems, not everybody is using an RTOS but almost every embedded system for example, has interrupts. So, if you have a data that’s shared between an interrupt, which we often called the foreground code and the background code, or getting back to my RTOS reference, if you have data that’s shared between two threads, it’s very possible for data to be changed right out from underneath the code that’s looking at it. So, if I have a variable that I’m reading in background code and it interchanges it, the compiler is not aware of that, or if I have data that one thread is changing while another thread is accessing it. So that’s one example. Another example which is very familiar to all of us in embedded systems is when you’re reading or writing from hardware. So, coding from device registers and hardware registers are not like your memory, we read and write to them as if they are memory, they have addresses, but their behaviors are very different.
Andrew: Right.
Dan: And it’s those subtle differences that make all the difference. So those are the most common cases where you want to use volatile.
Andrew: So by disabling the optimizations, you ensure that if hardware writes, they will register but it’s not definitely doing anything like that but you won’t miss it so to speak or anything like that.
Dan: Yes, exactly. For example, we’re all familiar with peripherals that typically have status registers.
Andrew: Right.
Dan: And they’re typically read on, typically you read from them to see what’s going on. And the very fact that they are modified by hardware means you could read it 10 times in a row and read 10 different values if the compiler is not optimizing away those reads. But if you forget the volatile keyword, it could be that the compiler generates code to read the register one time instead of 10 times in a row, and then it uses that same value 10 times.
Andrew: Right. Well, one things I’ve seen like sometimes with some of our consulting customers, it seems like sometimes they overuse the volatile keyword. And sometimes I get this comment like, “Well, why not just use it all the time?”
Dan: Right.
Andrew: And why don’t you want to use it all the time?
Dan: Right. And that is – I’ve been asked that very question; is it safe, should we just mark everything as volatile, nobody might have this problem. And you know, as an embedded engineer who is always trying to optimize and deal with limited resources, it’s kind of hard to hear that because volatile is used, and its purpose is pretty well-defined. And so, to overuse it, it can have implications. So, for one thing, the one reason that people don’t often think about is that it’s misleading. So, you know, code is a form of documentation.
Andrew: Right.
Dan: And so if I’m reading code and I see something marked as volatile it doesn’t need to be – it slows down my understanding of that code because now I’m trying to understand why is this volatile in terms of –
[Crosstalk]
Andrew: From the application perspective.
Dan: Right. So, it just takes longer to understand. So that’s just kind of unfair to get foul on developers; it’s not a good practice. And then the second reason is, and it’s kind of obvious from the things we’ve been talking about, what you’re really doing is inhibiting the compiler from optimizing the code in cases where it could.
Andrew: From doing its job.
Dan: Exactly. So, you’re actually handcuffing the compiler, so you might have bigger installer code in places where otherwise you wouldn’t. So, for those reasons, you really want to use it everywhere where you need to but nowhere where you don’t need to.
Andrew: Right. And I’m guessing also from this perspective that if an engineer is debugging a nasty hardware interface about the embedded code, probably one of the first places to look is to see how they are or not using volatile keyword around that code.
Dan: Absolutely. So, we teach that in Embedded Software Boot Camp, we say that. And I’ve seen it happen over and over again on products. I’ve been burned by that myself. It’s a real thing. And I bet half the people watching this video are shaking their heads like, “Yup, I’ve seen that as well.”
Andrew: So always look – always look for the use of the volatile keyword when you’re trying to debug hardware interface code.
Dan: Absolutely. And one other quick thing I’d like to say about this, and this goes way back to when I first met Michael Barr talking about interviewing engineers for embedded systems positions, and Michael has always said many of us use this is when you’re interviewing somebody who claims to know the C programming language well, ask them about the volatile keyword because if they haven’t done embedded C, they’re not really going to know what volatile means. And so that’s a good way to distinguish the embedded suitability of that candidate, so keep that in mind as well.
Andrew: Okay, all right, great. Well, thank you.