Archive for November, 2012

How to Combine Volatile with Struct

Friday, November 9th, 2012 Michael Barr

C’s volatile keyword is a qualifier that can be used to declare a variable in such a way that the compiler will never optimize away any of the reads and writes. Though there are several important types of variables to declare volatile, this obscure keyword is especially valuable when you are interacting with hardware peripheral registers and such via memory-mapped I/O.

Sometimes a memory-mapped I/O device could be as simple as just having a single 8-bit control register at a fixed address. In that case, the placement of volatile should be to the left of the * operator in the declaration of the pointer to that address, as in:

uint8_t volatile * p_ledreg = 0x10000000;

In the above code, the variable p_legreg is a pointer to a volatile 8-bit unsigned register located at address 0x10000000.

However, it is far more common that memory-mapped peripherals have at least a half dozen registers. In this more complicated scenario, a C struct can be defined to encapsulate these registers as a set and a pointer to said data structure can be declared. Here’s an example of such a declaration that does not feature the volatile keyword at all:

typedef struct
uint8_t reg1;
uint8_t reg2;
uint8_t _reserved;
uint8_t reg3;

} mydevice_t;

mydevice_t * p_mydevice = 0x10000000;

In this scenario, there are three possible places for the volatile keyword. First, the first line could be modified so that the new type “mydevice_t” always contains the volatile keyword, as in:

typedef volatile struct

Or the last line could be modified so that the pointer “p_mydevice” is a pointer to a volatile mydevice_t:

mydevice_t volatile * p_mydevice = 0x10000000;

Note that the difference between these first two volatile placements is whether all instances of said struct are volatile or only the pointer’s instance is volatile. If there is only one instance of the struct in the whole program and it is the pointer p_mydevice, then that difference is immaterial.

Finally, the third option is to place one or more volatile keywords within the struct definition itself. With this placement, only the specific registers within the struct that are declared volatile will be treated, by the compiler, as subject to asynchronous change. Reads and writes from or to other, non-volatile-declared, registers in the struct may potentially be optimized away. Here’s an example:

typedef struct
uint8_t volatile reg1;
uint8_t volatile reg2;
uint8_t const _reserved;
uint8_t reg3;

mydevice_t * p_mydevice = 0x10000000;

Given that there are multiple choices for the placement of volatile, where is the best place to put the volatile keyword in practice? My preferred placement is typically in the pointer declaration. That way, all of the registers in the struct will be treated, by the compiler, as volatile and yet it is possible to have other (e.g. RAM-based shadows) instances of said struct that are not volatile because they are not actually hardware registers underneath.

Where in the World is Michael Barr?

Friday, November 9th, 2012 Michael Barr

Dear reader, it has been over six months since my last blog post. My apologies for being absent without leave from this blog and from my Firmware Update e-newsletter. I have never been as busy, professionally, as over the past 14 months.

I recognize I have been quiet for too long for many of you and note that several readers have written to ask if I am okay or what is keeping me so busy. I am thankful for your concern and also for your patience. I hope this will be the first of several blog posts I will write in coming weeks and that I will resume a normal pace in coming months. I have quite a backlog of ideas.

In addition to launching the new company, Barr Group, and bringing on CEO Andrew Girson earlier this year here’s a quick summary of just some of what’s been keeping me so busy:

  • Toyota Unintended Acceleration. You may be aware of the NHTSA investigation and associated NASA Report on software. About a year ago, I was retained by plaintiffs in the consolidated personal injury and economic loss claims against Toyota in U.S. District Court (note: I am not involved in any of the state court cases). I am honored to have had the chance to review Toyota’s engine control source code with the assistance of a very talented team of Barr Group and other engineers. We were able to push the source code analysis deeper than NASA and also across many more vehicle years and models
  • Smartphone vs Apple (and LG). I have also been working as an expert witness in the smartphone wars. In this matter, Barr Group’s client, Smartphone, is the holder of a number of patents originally awarded to now-defunct Palm as it first added cellular phone capabilities to its popular handheld PDA products. My team has been working the infringement side of this patent dispute, which has required me to review Apple’s iOS source code as well as LG’s Android source code.
  • Madden Football. Another client is the original author of the popular Madden football games for Apple II, Commodore 64, and IBM PC. He is suing the game’s publisher (a little company called Electronic Arts) for breach of contract and past royalties. In a nutshell, the issue is whether the move of the early PC game’s code to consoles like Sega Genesis and Super Nintendo was cleanroom or a port. Reviewing so much assembly code for decades old 8- and 16-bit CPUs has reminded me how wonderful it is to program even in the “relatively low-level high-level language” of C.
  • Printers and Set-Top Boxes. Lest the above give you the impression I only work with plaintiffs, in this time I have also been helping: Samsung defend against allegations that it misused a former partner’s software in its printers; Motorola Mobility (now Google) defend against allegations that its cable TV set-top boxes infringe a pair of Microsoft patents; and a Canadian satellite TV company defend against allegations that it allowed its service to be pirated to the detriment of a rival cable TV company’s business.

Fun stuff!

While I never expected or planned to work with so many lawyers when I majored in electrical engineering and practiced embedded software, I do very much enjoy working as an expert witness. For one thing, I enjoy the required range of having to understand the technical issues as well as find ways to explain them to less technical audiences, including judges and juries. For another, reading so much source code written by others and doing related forms of reverse engineering has continued to inform my view on best practices in embedded software process and architecture. As these and other cases wind down in coming months and years, I expect to be able to share some of these lessons with you in this blog and in my other work as a consultant and trainer.