Posts Tagged ‘embedded’

How to Enforce Coding Standards Using PC-Lint

Thursday, June 16th, 2011 Michael Barr

In an earlier blog post, I introduced the concept of automatic enforcement of coding standards by stating that:

Enforcement of coding standards too often depends on programmers already under deadline pressure to be disciplined while they code and/or to make time to perform peer code reviews. … To ensure your selected coding standard is followed, and thus effective, your team should find as many automated ways to enforce as many of its rules as possible. And you should make such automated rule checking part of the everyday software build process.

One of the tools we have found to be indispensible for this purpose is Gimpel Software‘s PC-Lint (and the multi-platform FlexeLint). At just a few hundred dollars per seat, PC-Lint happens to also be one of the least expensive tools we own and thus a source of tremendous value to our team.

The following options can be set (in version 9.00) to assist in the automated enforcement of the identified rules from the Embedded C Coding Standard.

 

Rule(s) Tool Configuration Notes
Which C (1.1) 975 (unrecognized pragma)

+pragma(name, action)

-pragma(name)

Braces (1.3) PC-Lint can help identify missing braces through indentation checking:

525 (negative indentation)

539 (did not expect positive indentation)

725 (expected positive indentation)

Parentheses (1.4) 665 (Unparenthesized parameter in macro is passed an expression)

773 (Expression-like macro not parenthesized)

821 (Right hand side of assignment not parenthesized)

834 (Operator ‘Name’ followed by operator ‘Name’ is confusing. Use parentheses)

973 (Unary operator in macro ‘Symbol‘ not parenthesized)

Casts (1.6) 507, 511, 519 (Size incompatibility in cast)

549, 571, 611 (suspicious cast)

643 (loss of precision in pointer cast)

680 (suspicious truncation in arithmetic expression converted to pointer)

688 (cast used within preprocessor conditional statement)

740, 741 (unusual pointer cast)

920 (cast from ‘type’ to ‘void’)

921-930 (cast from ‘type’ to ‘type’)

1773 (attempt to cast away const or volatile)

Keywords to avoid (1.7) -deprecate( keyword, auto, violates coding standard )

-deprecate( keyword, register, violates coding standard )

-deprecate( keyword, goto, violates coding standard )

-deprecate( keyword, continue, violates coding standard )

Keywords to Frequent (1.8) 818 (Pointer parameter could be declared ptr to const)

843 (Variable could be declared as const)

844 (Pointer variable could be declared as const)

952 (parameter could be declared as const)

953 (variable could be declared as const)

954 (pointer variable could be declared as pointing to a const)

765 (external symbol could be made static)

Comments, Acceptable Formats (2.1) 602 (comment within comment)
Alignment (3.2)

Indentation (3.4)

525 (negative indentation)

539 (did not expect positive indentation)

725 (expected positive indentation)

Header Files (4.2)

Source Files (4.3)

451 (header file repeatedly included but does not have a standard include guard)

766 (Include of header file not used in module)

966 (indirectly included header file not used in module)

967 (Header file does not have a standard include guard)

Fixed Width Integers (5.2)

Signed Integers (5.3)

569 (Loss of information — Integer bits to Integer bits)

570 (loss of sign, assignment being made from a negative constant to an unsigned quantity)

573 (signed-unsigned mix with divide)

574 (signed-unsigned mix with relational)

701, 703 (shift left of signed quantity)

702, 704 (shift right of signed quantity)

712 (loss of precision, one type is larger than another type)

713 (loss of precision, signed to unsigned)

734 (loss of precision, to a quantity smaller than an int)

Structure and Unions (5.5) 38 (Offset of symbol inconsistent – A member of a class or struct appears in a different position (offset from the start of the structure) than an earlier declaration)

39 (Redefinition of symbol conflicts with ‘location’ — a struct or a union is being redefined)

Function-Like Macros (6.3) 665 (Unparenthesized parameter in macro is passed an expression)

773 (Expression-like macro not parenthesized)

Initialization (7.2) 35 (initializer has side-effects)

133 (too many initializers for aggregate)

134 (missing initializer)

530, 603 (symbol not initialized)

540 (excessive size — a string initializer required more space than what was allocated)

644 (variable may not have been initialized)

651 (potentially confusing initializer)

708 (union initialization)

727, 728, 729, 738 (symbol not explicitly initialized)

771, 772 (symbol conceivably not initialized)

784 (nul character truncated from string — During initialization of an array with a string constant there was not enough room to hold the trailing NUL character)

785, 943 (too few initializers for aggregate)

940 (omitted braces within an initializer)

Switch Statements (8.3) 44 (A case or default statement occurred outside a switch)

108 (Invalid context – A continue or break statement was encountered without an appropriate surrounding context)

137 (constant used twice within switch)

408 (type mismatch with switch expression)

744 (switch statement has no default)

764 (switch statement does not have a case)

825 (control flows into case/default)

Equivalence Tests (8.6) 720 (Boolean test of assignment)

 

As a convenience to readers who follow the Netrino Embedded C Coding Standard and may like to use RSM and/or PC-Lint to inexpensively and automatically enforce as many of the rules as possible, here are starter configuration files:

Is “(uint16_t) -1″ Portable C Code?

Thursday, June 2nd, 2011 Michael Barr

Twice recently, I’ve run across third-party middleware that included a statement of the form:

uint16_t variable = (uint16_t) -1;

which I take as the author’s clever way of coding:

0xFFFF

I’m not naturally inclined to like the obfuscation, but wondered if “(uint16_t) -1″ is even portable C code? And, supposing it is portable, is there some advantage I don’t know about that suggests using that form over the hex literal? In the process of researching these issues, I learned a helpful fact or two worth sharing.

Q: Is the result of “(uint16_t) -1″ guaranteed (by the ISO C standard) to be 0xFFFF?

A: No. But it’s likely the result will be 0xFFFF on most compilers/processors, since there is really just the one common internal CPU representation of unsigned integers. (For signed integers, most/all processors will use the common 2′s complement representation underneath–even though that’s not required in any way by the language standard.)

Q: Is there any advantage to writing 0xFFFF that way?

A: According to the C99 Standard, all conforming implementations support uint_least16_t, but some may not support uint16_t. If the platform doesn’t support uint16_t, then “(uint16_t) -1″ won’t compile, but 0xFFFF will compile as a value of some larger unsigned integer type (i.e., a bug waiting to happen).

Of course, platforms that don’t have a fixed-width 16-bit unsigned capability are rare, though it may be that some DSPs fall into that category. The same issue applies to uint32_t and 0xFFFFFFFF, of course. However, I suspect platforms that don’t have a fixed-width 32-bit unsigned capability are even rarer.

Q: What is the best way to represent the maximum unsigned integer value of a given size?

A: The very best way to represent the maximum values for unsigned (and signed) fixed-width types is to use the constants named in C99′s stdint.h header file. These are of the form UINTn_MAX (and INTn_MAX) where n is the number of bits (e.g., UINT16_MAX). That is guaranteed to either work or not compile, with no middle ground for bugs.

Hat Tip: Many thanks to C and C++ standards guru Dan Saks for help with these answers.

How to Enforce Coding Standards (Automatically)

Wednesday, May 25th, 2011 Michael Barr

Coding standards can be an important tool in the fight to keep bugs out of embedded software. Unfortunately, too many well-intentioned (especially, corporate) coding standards are ineffective and gather more dust than followers. The hard truth is that enforcement of coding standards too often depends on programmers already under deadline pressure to be disciplined while they code and/or to make time to perform peer code reviews. And when peer reviews are done in this scenario, they too easily devolve into compliance discussions that miss the forest for the trees.

To ensure your selected coding standard is followed and thus effective, your team should find as many automated ways to enforce as many of its rules as possible. And you should make such automated rule checking part of the everyday software build process. Ideally, you would also restrict version control check-ins to just code that has passed all the automated checks. No code that breaks any of these automatable rules should be allowed in peer code reviews. That way, code reviewers can focus their limited hours on (1) what the code is supposed to do, (2) whether it does so correctly, and (3) whether the code and comments together are easily understood by all involved.

One of the ways Netrino has found to increase compliance with its Embedded C Coding Standard is by configuring static analysis tools we already use to automatically enforce individual rules.

Perhaps the best option is to use a static analysis tool that includes built-in support for your chosen coding standard and/or the ability to be customized to proprietary rules. LDRA‘s static analysis engine, a screenshot from which is shown in the image below, comes preconfigured to check about 80% of the “NETRINO” coding standard rules, as well as a number of other widely used coding standards.

The LDRA Tool Suite Enforces Netrino's Embedded C Coding Standard

But there are other, less expensive, options available as well. Two tools that we have used are RSM and PC-Lint from M Squared Technologies and Gimpel Software, respectively. Neither can easily and independently enforce all of our Embedded C Coding Standard rules. But used together and properly configured, these two tools offer a low-cost automated coding standards enforcement mechanism that covers a large percentage of the rules.

Configuring RSM

The following RSM outputs can be examined and configuration options set (in version 7.75) to assist in the automated enforcement of the identified rules from the Embedded C Coding Standard. Pricing for the RSM tool, which runs on Windows, Linux, and other versions of Unix (including Mac OS X), is online at http://msquaredtechnologies.com/m2rsm/order/.

Rule # Brief Description Tool Configuration Notes
1.2.a Line length limited to 80 characters. Quality Notice 1
1.3.a Braces surround all blocks of code. Quality Notice 22
1.7.c Keyword goto not used. Quality Notice 9
1.7.d Keyword continue not used. Quality Notice 43
1.7.e Keyword break not used outside switch. Quality Notice 44
2.2 Location and content of comments. Quality Notices 17, 20, 51; Options -Es -Ec -EC
3.1 Use of white space. Quality Notices 16, 19
3.5.a No tab characters. Quality Notice 30; Option -Dt
3.6.a UNIX-style (single-character) linefeeds. Option -Du
4.1.a-d Module naming conventions. Option -Rn
4.2.a Precisely one header file per source file. Option -Rn
6.1.a-e Precisely one header file per source file. Quality Notice 2; Option -l
6.2 Cyclomatic complexity of functions. Quality Notices 10, 18, 27; Option -c
6.3.b.i-iii Preprocessor macro safety mechanisms. Option -m
8.2.d If-else if statements always have else. Quality Notice 22
8.3.b Switch statements always have default. Quality Notices 13, 14, 56
8.5.a No unconditional jumps. Quality Notices 9, 43, 444

Configuring PC-Lint

In a future blog post, I will similarly identify PC-Lint configurations that can be used (in version 9.0) to assist in the automated enforcement of specific rules from the Embedded C Coding Standard. Pricing for the PC-Lint tool, which runs on Windows, Linux, and other versions of Unix (including Mac OS X), is online at http://gimpel.com/html/order.htm.

Embedded Software Training in a Box

Friday, May 6th, 2011 Michael Barr

Embedded Software Training in a BoxI am beaming with pride. I think we have finally achieved the holy grail of firmware training: Embedded Software Training in a Box. Priced at just $599, the kit includes Everything-You-Need-to-Know-to-Develop-Quality-Reliable-Firmware-in-C, including software for real-time safety-critical systems such as medical devices.

In many ways, this product is the culmination of about the last fifteen years of my career. The knowledge and skills imparted in the kit are drawn from my varied experiences as:

This kit also–at long last–answers the question I’ve been receiving from around the world since I first started writing articles and books about embedded programming: “Where/How can I learn to be a great embedded programmer?” I believe the answer is now as easy as: “Embedded Software Boot Camp in a Box!”

Beer and Boards at ESC Silicon Valley

Wednesday, April 6th, 2011 Michael Barr

It really looks like I’ve picked the wrong year to miss ESC Silicon Valley (due to a schedule conflict). (The last time I wasn’t at ESC, it was 1997 and White Zombie was still together. The first thing I’d really liked to have seen is Steve Wozniak‘s keynote speech. The second thing I’m really sad to miss is the just announced “Beer and Boards” party/giveaway.

Beer and Boards sounds really fun. Here’s how it works: Every “All Access” attendee will get to choose one of three free development kits to take home:

Once you select your preferred kit you will receive information on the time and place for the relevant Beer and Boards party, at which you will get to drink free beer at a special meet-and-greet with one of your kit’s designers to talk about your new kit and its capabilities. Three boards spread out over three days.

Nerds drinking beer! I love it. What will they think of next?

Before you register for this year’s ESC, be sure to check out my earlier post Save Big on Embedded Systems Conference Registration. Also, remember to use the promo code BARR20 to save an additional 20% off registration and be entered to win a free seat at a future Embedded Software Boot Camp or one of 20 free copies of the Embedded C Coding Standard.