embedded software boot camp

Proposed Rule Changes for Embedded C Coding Standard

June 20th, 2018 by 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?

June 6th, 2018 by 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?

The Rise of the Full Stack Developers

May 28th, 2018 by Michael Barr

I’m a connector within our embedded systems design community and, so, my LinkedIn account has more than 15,000 connections. Which is where I recently started to spot what appears to be an emerging industry trend: so-called “full stack developers” have begun to enter the embedded software realm.

While many self-identified firmware developers and embedded programmers have come up to the field from the electronics side, often cutting their teeth in electrical engineering and digital design first, a full stack developer is a software engineer who works at all layers of a complex software system. For example, many full stack developers create websites that connect to relational databases and/or cloud-hosted APIs. In the process a single such developer might write code in languages ranging from JavaScript and Ruby to Python, C, and shell scripts to SQL and C#. All in the same month!

To accomplish this, a full stack developer need not be an expert in all of those languages nor software layers. Rather, he or she should be an adaptable sort who is able to copy and paste then tweak the necessary bits of “glue code” to connect together various commercial, open-source, and bespoke software packages running on a variety of operating systems across what is effectively a distributed computing platform. By necessity, things may not always work right the first or even second time; but the full stack developer chips away at all of those interfaces iteratively until the requirements are met–more or less.

What seems to be changing now is that embedded systems are being added to the “full stack” mix. Other software developers are no longer afraid to interface with or alter our systems and increasingly view IoT and other connected embedded systems as just another part of their project to be integrated as quickly as possible. I’m seeing evidence of this in the increase of developers with “full stack” in their job titles and expertise summaries within my network and communicating with us over at Barr Group.

Of course, when a full stack developer is not an expert in uniquely embedded systems challenges (e.g., the Top 10 Causes of Nasty Embedded Software Bugs) or does not exercise due care, this could increase the risks of failures of safety- and mission-critical systems.

What do you think? Are you a full stack developer working with embedded systems? Comment below.

Survey Says: The Commercial RTOS Business is Doomed

February 22nd, 2018 by Michael Barr

Nearly two decades years ago I was the moderator of an interesting Embedded Systems Conference panel discussion titled “The Great RTOS Debate: Buy or Roll Your Own?” At that time, near the turn of the century, the market for commercial real-time operating systems (RTOSes) was growing rapidly year over year.

The big trend then was away from custom-written “proprietary” kernels toward commercial RTOSes typically licensed with a per unit royalty. From 1997 until their merger in 2000, Wind River and Integrated System together dominated this part of the market. According to surveys taken at the time, either VxWorks or pSOS was the operating system of choice for about 1 in 4 new embedded systems designs.

As embedded Linux entered the market in full and that merger took place, the market was divided roughly as follows: 39% no OS, 31% commercial RTOS, 18% proprietary OS, and 12% Linux.

The selection of operating systems by embedded systems designers has changed considerably since then. According to a preliminary analysis of data collected in Barr Group’s 2018 Embedded Systems Safety & Security Survey there are still quite a few new systems that run “no operating system” on their primary processor. However, this is down from 39% to just 22%. Use of proprietary operating systems is also down about half over the intervening 18 years, from 18% to just 8%.

The most popular category of actual operating system is now Linux at 22%, which is a change from prior years when “RTOS” (an aggregate of those paying for a commercial RTOS and those provided an operating system from chip vendor, which now ranks behind Linux at 19%) was most popular. Following ever more closely on the heels of those “commercial” RTOSes are the open source operating systems (e.g., FreeRTOS) that lack licensing fees.

We can get some sense of the range in the architecture of embedded systems by comparing the rankings of the five most popular operating system choices on the primary processor as the total number of processors goes up. As shown in the table below, the percentage of designers writing their own “proprietary” operating system is about the same (7-9%) regardless of processor count. But Linux clearly becomes a much more popular choice (climbs from 11% to 32%) as the number of processors increases, while “open source” and “no operating system” drop in popularity.

rtos_use_by_cpu_count

But it’s also worth looking at the timeline trend over these years, as I have assembled in the following graph from survey data compiled from 2005-2014 by Embedded.com and in the last three years by Barr Group.

rtos_use_trend_long_term

What I make of all of this is that those who depend for their livelihood on operating system licensing fees from designers of embedded systems should start looking for other sources of income.

What other trends do you see?

C: The Immortal Programming Language

February 22nd, 2018 by Michael Barr

Barr Group’s 2018 Embedded Systems Safety & Security Survey is now closed and I am in the midst of analyzing the data. This year a portion of my analysis is focused on multi-year trends. One trend that really stands out to me is that the C programming language refuses to give up the ghost.

A longitudinal study of survey data spanning almost a decade and a half shows that C remains the primary programming language of embedded software. Remarkably, in that time C has actually gained market share from 50% to about 70%–at the expense of assembly, C++, and Java.

The graph below shows the relevant data from 2005 through 2018. The first decade of this data is drawn from annual surveys published by the publishers of Embedded.com with the most recent data coming from Barr Group’s annual survey. Each of these surveys of embedded systems designers phrased the relevant question similarly, either “My current embedded project is programmed mostly in [pick one]” or “What is the primary programming language for your current project? [pick one]”.

Language Use Trend Plot

It makes total sense that the use of assembly language as a primary programming language is falling. The last time I wrote an embedded program mostly in assembly was about twenty years ago. Of course, there will always be some low level code that needs to be written in the native language of the machine–if only to bring up the higher-level language execution and for drivers and kernel code. But with inexpensive (and mostly 32-bit ARM-based) microcontrollers increasingly at the heart of our systems there’s no sense wasting time coding the application code in assembly.

We can attribute about 7 percentage points of the growth in use of C to the reduction in use of assembly during these years. This trend has helped use of C grow to about 60%.

But what’s also been happening in this time is that C++ has failed to capitalize on earlier gains. The peak year for C++ use was apparently 2006, when it had 33% share. Use of C++ as the primary language has since fallen and thus added about 10 percentage points to use of C.

I didn’t include Java in the graph, but it’s use has been less common than assembly in every survey year, with high points of 3% and now down around 1% the last three years. And no other language has emerged to maintain greater than 1% share.

What I make of all of this is that C remains the most cost-effective way to write embedded software. In hindsight, object-oriented languages have been tried but failed to establish their value to most programmers. C++ is a player but looks unlikely to ever eclipse its namesake.

What do you see in the data?