Archive for the ‘Coding Standards’ Category

Proposed Rule Changes for Embedded C Coding Standard

Wednesday, June 20th, 2018 Michael Barr

My book Embedded C Coding Standard began as an internal coding standard of a consulting company and was first published in 2008 by that company (Netrino). In 2013, the book’s cover was given a new look and the standard became known as “Barr Group‘s Embedded C Coding Standard“. A 2018 update to the book will be released soon and this will be the first time the substance of the standard has changed in over a decade.

The primary motivation for making changes is to better harmonize the rules with the MISRA-C Guidelines. The older Barr Group standard made reference to MISRA C:2004, which was superseded by MISRA C:2012. The few known direct conflicts between BARR-C:2013 and MISRA C (stemming from our earlier embrace of ISO C99) were effectively eliminated with their 2012 update. But we wanted to do more than just remove those noted conflicts and push even further in our embrace of harmonization.

In a sentence, MISRA C is a safer subset of the C language plus a set guidelines for using what is left of the language more safely. In about as many words, BARR-C is a style guide for the C language that reduces the number of defects introduced during the coding phase by increasing readability and portability. It turns out there is quite a bit of value in combining rules from both standards. For example, MISRA’s guidelines do not provide stylistic advice and applying BARR-C’s stylistic rules to the C subset further increases safety.

The rest of this post is a preview of the specific rule changes and additions we will make in BARR-C:2013. (Omitted from this list are rules reworded simply for greater clarity.)

Rule 1.1.d (new)

The following rule will be added:

Preprocessor directive #define shall not be used to alter or rename any keyword or other aspect of the programming language.

Rule 1.6.b (new)

The following rule will be added:

Conversion from a pointer to void to a pointer to another type shall be cast.

Rule 1.7.c (change)

The earlier rule:

The goto keyword shall not be used.

will be replaced with:

It is a preferred practice to avoid all use of the goto keyword. If goto is used it shall only jump to a label declared later and in the same or an enclosing block.

This is being done so that the BARR-C standard does not restrict uses of goto that are permissible under MISRA C.

Rule 1.7.d (change)

The earlier rule:

The continue keyword shall not be used.

will be replaced with:

It is a preferred practice to avoid all use of the continue keyword.

This is being done so that the BARR-C standard does not restrict uses of continue that are permissible under MISRA C.

Rule 1.7.e (eliminated)

There will no longer be any restriction on the use of the break keyword. This is being done so that the BARR-C standard does not restrict uses of break that are permissible under MISRA C.

Rule 4.2.d (change)

The earlier rule:

No header file shall contain a #include statement.

will be replaced with:

No public header file shall contain a #include of any private header file.

This is being done because apparently no one (other than me) actually valued the old rule. 🙂

Rule 5.1.c (new)

The following rule will be added:

The name of all public data types shall be prefixed with their module name and an underscore.

Rule 5.4.b.v (new)

The following rule will be added:

Always invoke the isfinite() macro to check that prior calculations have resulted in neither infinity nor NaN.

Rule 5.6.a (new)

The following rule will be added:

Boolean variables shall be declared as type bool.

Rule 5.6.b (new)

The following rule will be added:

Non-Boolean values shall be converted to Boolean via use of relational operators (e.g., < or !=), not via casts.

Rule 6.2.c (changed)

The earlier rule:

All functions shall have just one exit point and it shall be at the bottom of the function. That is, the keyword return shall appear a maximum of once.

will be replaced with:

It is a preferred practice that all functions shall have just one exit point and it shall be via a return at the bottom of the function.

Rule 6.3.b.iv (new)

The following rule will be added:

Never include a transfer of control (e.g., return keyword).

Rule 7.1.n (new)

The following rule will be added:

The names of all variables representing non-pointer handles for objects, e.g., file handles, shall begin with the letter ‘h’.

Rule 7.1.o (new)

The following rule will be added:

In the case of a variable name requiring multiple of the above prefixes, the order of their inclusion before the first underscore shall be [g][p|pp][b|h].

Rule 7.2.c (new)

The following rule will be added:

If project- or file-global variables are used, their definitions shall be grouped together and placed at the top of a source code file.

Rule 7.2.d (new)

The following rule will be added:

Any pointer variable lacking an initial address shall be initialized to NULL.

Rule 8.2.a (changed)

The earlier rule:

The shortest (measured in lines of code) of the if and else if clauses should be placed first.

will be replaced with:

It is a preferred practice that the shortest (measured in lines of code) of the if and else if clauses should be placed first.

Rule 8.3.c (new)

The following rule will be added:

Any case designed to fall through to the next shall be commented to clearly explain the absence of the corresponding break.

Rule 8.5.b (new)

The following rule will be added:

The C Standard Library functions abort(), exit(), and setjmp()/longjmp() shall not be used.

If you have questions about any of these draft changes or suggestions for better or other changes, please comment below.

C’s goto Keyword: Should we Use It or Lose It?

Wednesday, June 6th, 2018 Michael Barr

In the 2008 and 2013 editions of my bug-killing Embedded C Coding Standard, I included this rule:

Rule 1.7.c. The goto keyword shall not be used.

Despite this coding standard being followed by about 1 in 8 professional embedded systems designers, none of us at Barr Group have heard any complaints that this rule is too strict. (Instead we hear lots of praise for our unique focus on reducing intra-team stylistic arguments by favoring above all else C coding rules that prevent bugs.)

However, there exist other coding standards with a more relaxed take on goto. I’ve thus been revisiting this (and related) rules for an updated 2018 edition of the BARR-C standard.

Specifically, I note that the current (2012) version of the MISRA-C Guidelines for the Use of the C Programming Language in Critical Systems merely advises against the use of goto:

Rule 15.1 (Advisory): The goto statement should not be used

though at least the use of goto is required to be appropriately narrowed:

Rule 15.2 (Required): The goto statement shall jump to a label declared later in the same function

Rule 15.3 (Required): Any label referenced by a goto statement shall be declared in the same block, or in any block enclosing the goto statement

Generally speaking, the rules of the MISRA-C:2012 standard are either the same as or stricter than those in my BARR-C standard. In addition to overlaps, they have more and stricter coding rules and we add stylistic advice. It is precisely because MISRA-C’s rules are stricter and only BARR-C includes stylistic rules that these two most popular embedded programming standards frequently and easily combined.

Which all leads to the key question:

Should the 2018 update to BARR-C relax the prior ban on all use of goto?

According to the authors of the C programming language, “Formally, [the goto keyword is] never necessary” as it is “almost always easy to write code without it”. They go on to recommend that goto “be used rarely, if at all.”

Having, in recent days, reviewed the arguments for and against goto across more than a dozen C programming books as well as other C/C++ coding standards and computer science papers, I believe there is just one best bug-killing argument for each side of this rule. And I’ll have to decide between them this week to keep the new edition on track for a June release.

Allow goto: For Better Exception Handling

There seems to be universal agreement that goto should never be used to branch UP to an earlier point in a function. Likewise, branching INTO a deeper level of nesting is a universal no-no.

However, branching DOWN in the function and OUT to an outer level of nesting are often described as powerful uses of the goto keyword. For example, a single goto statement can be used to escape from two or more levels of nesting. And this is not a behavior that can be done with a single break or continue. (To accomplish the same behavior without using goto, one could, e.g., set a flag variable in the inner block and check it in each outer block.)

Given this, the processing of exceptional conditions detected inside nested blocks is a potentially valuable application of goto that could be implemented in a manner compliant with the three MISRA-C:2012 rules quoted above. Such a jump could even proceed from two or more points in a function to a common block of error recovery code.

Because good exception handling is a property of higher reliabilty software and is therefore a potential bug killer, I believe I must consider relaxing Rule 1.7.c in BARR-C:2018 to permit this specific use of goto. A second advantage of relaxing the rule would be increasing the ease of combining rules from MISRA-C with those from BARR-C (and vice versa), which is a primary driver for the 2018 update.

Ban goto: Because It’s Even Riskier in C++

As you are likely aware, there are lots of authors who opine that use of goto “decreases readability” and/or “increases potential for bugs”. And none other than Dijkstra (50 years ago now!) declared that the “quality of programmers is [inversely proportional to their number] of goto statements”.

But–even if all true–none of these assertions is a winning argument for banning the use of goto altogether vs. the above “exception handling exception” suggested by the above.

The best bug-killing argument I have heard for continued use of the current Rule 1.7.c is that the constructors and destructors of C++ create a new hazard for goto statements. That is, if a goto jumps over a line of code on which an object would have been constructed or destructed then that step would never occur. This could, for example, lead to a very subtle and difficult type of bug to detect–such as a memory leak.

Given that C++ is a programming language intentionally backward compatible with legacy C code and that elsewhere in BARR-C there is, e.g., a rule that variables (which could be objects) should be declared as close as possible to their scope of use, relaxing the existing ban on all use of goto could forseeably create new hazards for the followers of the coding standard who later migrate to C++. Indeed, we already have many programmers following our C coding rules while crafting C++ programs.

So what do you think? What relevant experiences can bring to bear on this issue in the comments area below? Should I relax the ban on goto or maintain it? Are there any better (bug-killing) arguments for or against goto?

Apple’s #gotofail SSL Security Bug was Easily Preventable

Monday, March 3rd, 2014 Michael Barr

If programmers at Apple had simply followed a couple of the rules in the Embedded C Coding Standard, they could have prevented the very serious `Gotofail` SSL bug from entering the iOS and OS X operating systems. Here’s a look at the programming mistakes involved and the easy-to-follow coding standard rules that could have easily prevent the bug.

In case you haven’t been following the computer security news, Apple last week posted security updates for users of devices running iOS 6, iOS 7, and OS X 10.9 (Mavericks). This was prompted by a critical bug in Apple’s implementation of the SSL/TLS protocol, which has apparently been lurking for over a year.

In a nutshell, the bug is that a bunch of important C source code lines containing digital signature certificate checks were never being run because an extraneous goto fail; statement in a portion of the code was always forcing a jump. This is a bug that put millions of people around the world at risk for man-in-the-middle attacks on their apparently-secure encrypted connections. Moreover, Apple should be embarrassed that this particular bug also represents a clear failure of software process at Apple.

There is debate about whether this may have been a clever insider-enabled security attack against all of Apple’s users, e.g., by a certain government agency. However, whether it was an innocent mistake or an attack designed to look like an innocent mistake, Apple could have and should have prevented this error by writing the relevant portion of code in a simple manner that would have always been more reliable as well as more secure. And thus, in my opinion, Apple was clearly negligent.

Here are the lines of code at issue (from Apple’s open source code server), with the extraneous goto in bold:

static OSStatus
SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams, ...)
{
    OSStatus  err;
    ...

    if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
        goto fail;
    if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
        goto fail;
        goto fail;
    if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
        goto fail;
    ...

fail:
    SSLFreeBuffer(&signedHashes);
    SSLFreeBuffer(&hashCtx);
    return err;
}

The code above violates at least two rules from Barr Group‘s Embedded C Coding Standard book. Importantly, had Apple followed at least the first of these rules, in particular, this dangerous bug should almost certainly have been prevented from ever getting into even a single device.

Rule 1.3.a

Braces shall always surround the blocks of code (a.k.a., compound statements), following if, else, switch, while, do, and for statements; single statements and empty statements following these keywords shall also always be surrounded by braces.

Had Apple not violated this always-braces rule in the SSL/TLS code above, there would have been either just one set of curly braces after each if test or a very odd looking hard-to-miss chunk of code with two sets of curly braces after the if with two gotos. Either way, this bug was preventable by following this rule and performing code review.

Rule 1.7.c

The goto keyword shall not be used.

Had Apple not violated this never-goto rule in the SSL/TLS code above, there would not have been a double goto fail; line to create the unreachable code situation. Certainly if that forced each of the goto lines to be replaced with more than one line of code, it would have forced programmers to use curly braces.

On a final note, Apple should be asking its engineers and engineering managers about the failures of process (at several layers) that must have occurred for this bug to have gone into end user’s devices. Specifically:

  • Where was the peer code review that should have spotted this, or how did the reviewers fail to spot this?
  • Why wasn’t a coding standard rule adopted to make such bugs easier to spot during peer code reviews?
  • Why wasn’t a static analysis tool, such as Klocwork, used, or how did it fail to detect the unreachable code that followed? Or was it users of such a tool, at Apple, who failed to act?
  • Where was the regression test case for a bad SSL certificate signature, or how did that test fail?

Dangerous bugs, like this one from Apple, often result from a combination of accumulated errors in the face of flawed software development processes. Too few programmers recognize that many bugs can be kept entirely out of a system simply by adopting (and rigorously enforcing) a coding standard that is designed to keep bugs out.

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.

Combining C’s volatile and const Keywords

Tuesday, January 24th, 2012 Michael Barr

Does it ever make sense to declare a variable in C or C++ as both volatile (i.e., “ever-changing”) and const (“read-only”)? If so, why? And how should you combine volatile and const properly?

One of the most consistently popular articles on the Netrino website is about C’s volatile keyword. The volatile keyword, like const, is a type qualifier. These keywords can be used by themselves or together in variable declarations.

I’ve written about volatile and const individually before. If you haven’t previously used the volatile keyword, I recommend you read How to Use C’s volatile Keyword before going on. As that article makes plain:

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.

How to Use C’s volatile Keyword

By declaring a variable volatile you are effectively asking the compiler to be as inefficient as possible when it comes to reading or writing that variable. Specifically, the compiler should generate object code to perform each and every read from a volatile variable and each and every write to a volatile variable–even if you write it twice in a row or read it and ignore the result. No read or write can be skipped. Effectively no optimizations are allowed with respect to volatile variables.

The use of volatile variables also creates additional sequence points in C and C++ programs. The order of accesses of volatile variables A and B in the object code must be the same as the order of those accesses in the source code. The compiler is not allowed to reorder volatile variable accesses for any reason.

Here are a couple of examples of declarations of volatile variables:

int volatile g_flag_shared_with_isr;

uint8_t volatile * p_led_reg = (uint8_t *) 0x00080000;

The first example declares a global flag that can be shared between an ISR and some other part of the code (e.g., a background processing loop in main() or an RTOS task) without fear that the compiler will optimize (i.e., “delete”) the code you write to check for asynchronous changes to the flag’s value. It is important to use volatile to declare all variables that are shared by asynchronous software entities, which is important in any kind of multithreaded programming. (Remember, though, that access to global variables shared by tasks or with an ISR must always also be controlled via a mutex or interrupt disable, respectively.)

The second example declares a pointer to a hardware register at a known physical memory address (80000h)–in this case to manipulate the state of one or more LEDs. Because the pointer to the hardware register is declared volatile, the compiler must always perform each individual write. Even if you write C code to turn an LED on followed immediately by code to turn the same LED off, you can trust that the hardware really will receive both instructions. Because of the sequence point restrictions, you are also guaranteed that the LED will be off after both lines of the C code have been executed. The volatile keyword should always be used with creating pointers to memory-mapped I/O such as this.

[See Coding Standard Rule #4: Use volatile Whenever Possible for more on the use of volatile by itself.]

How to Use C’s const Keyword

The const keyword is can be used to modify parameters as well as in variable declarations. Here we are only interested in the use of const as a type qualifier, as in:

uint16_t const max_temp_in_c = 1000;

This declaration creates a 16-bit unsigned integer value of 1,000 with a scoped name of max_temp_in_c. In C, this variable will exist in memory at run-time, but will typically be located, by the linker, in a non-volatile memory area such as ROM or flash. Any reference to the const variable will read from that location. (In C++, a const integer may no longer exist as an addressable location in run-time memory.)

Any attempt the code makes to write to a const variable directly (i.e., by its name) will result in a compile-time error. To the extent that the const variable is located in ROM or flash, an indirect write (i.e., via a pointer to its address) will also be thwarted–though at run-time, obviously.

Another use of const is to mark a hardware register as read-only. For example:

uint8_t const * p_latch_reg = 0x10000000;

Declaring the pointer this way, any attempt to write to that physical memory address via the pointer (e.g., *p_latch_reg = 0xFF;) should result in a compile-time error.

[See Coding Standard Rule #2: Use const Whenever Possible for more on the use of const by itself.]

How to Use const and volatile Together

Though the essence of the volatile (“ever-changing”) and const (“read-only”) decorators may seem at first glance opposed, there are some times when it makes sense to use them both to declare one variable. The scenarios I’ve run across have involved pointers to memory-mapped hardware registers and shared memory areas.

(#1) Constant Addresses of Hardware Registers

The following declaration uses both const and volatile in the frequently useful scenario of declaring a constant pointer to a volatile hardware register.

uint8_t volatile * const p_led_reg = (uint8_t *) 0x00080000;

The proper way to read a complex declaration like this is from the name of the variable back to the left, as in:

p_led_reg IS A constant pointer TO A volatile 8-bit unsigned integer.

Reading it that way, we can see that the keyword const modifies only the pointer (i.e., the fixed address 80000h), which does not change at run-time. Whereas the keyword volatile modifies only the type of integer. This is actually quite useful and is a much safer version of the declaration of a p_led_reg that appears at the top of this article. In particular, adding const means that the simple typo of a missed pointer dereference (‘*’) will be caught at compile time. That is, the mistaken code p_led_reg = LED1_ON; won’t overwrite the address with the non-80000h value of LED1_ON. The compiler error leads us to correct this to *p_led_reg = LED1_ON;, which is almost certainly what we meant to write in the first place.

(#2) Read-Only Shared-Memory Buffer

Another use for a combination of const and volatile is where you have two processors communicating via a shared memory area and you are coding the side of this communications that will only be reading from a shared memory buffer. In this case you could declare variables such as:

int const volatile comm_flag;

uint8_t const volatile comm_buffer[BUFFER_SIZE];

Of course, you’d usually want to instruct the linker to place these global variables at the correct addresses in the shared memory area or to declare the above as pointers to specific physical memory addresses. In the case of pointers, the use of const and volatile may become even more complex, as in the next category.

(#3) Read-Only Hardware Register

Sometimes you will run across a read-only hardware register. In addition to enforcing compile-time checking so that the software doesn’t try to overwrite the memory location, you also need to be sure that each and every requested read actually occurs. By declaring your variable IS A (constant) pointer TO A constant and volatile memory location you request all of the appropriate protections, as in:

uint8_t const volatile * const p_latch_reg = (uint8_t *) 0x10000000;

As you can see, the declarations of variables that involve both the volatile and const decorators can quickly become complicated to read. But the technique of combining C’s volatile and const keywords can be useful and even important. This is definitely something you should learn to master to be a master embedded software engineer.