Coding Standards in Embedded Programming

 

Author: Ayfer KÜÇÜKERDÖNMEZ, Group Manager / Avionic SW Group

“There is no reason anyone would want a computer in their home.”
                                   Ken Olson, President of Digital Equipment Corporation, 1977

Despite the predictions in 70’s, today we have computers in almost every aspect of our lives. We work with computers in our office, we have computers in our house. Even if we realize or not, we get in touch with small or big software when heating our lunch, using the subway or buying and selling stocks in market.

For the next decade or two, it is obvious that we will be wrapped with software even more. There are on-going studies pointing out that there will be driverless cars, automation systems managing cities, face-recognition systems for public security etc. With prevalence of software, of which 90% is covered by embedded systems, safety and security of embedded software has become more crucial than ever before.

Most embedded systems prefer C/C++ programming language because it creates more compact and faster runtime code that is portable and gives much more freedom to developers. With experienced developers this freedom is a grace, giving control of the code and letting them work in very flexible environments. But if not all the developers are experienced enough, the code may become more error-prone, complex, and unreadable and in the end advantages may become disadvantages. Also C/C++ does not provide error checking as much as other languages. Therefore detecting these flaws early is not possible without a strict code review process.

There is no miraculous method that can produce error-free software, but studies show that 80% of errors are injected during development process. These are mainly because;

  • Overlooked side effects or unexpected behaviors due to inexperienced developers.
  • Lack of training about safe and secure code development, which are concepts taught only at graduate programs in universities.
  • Embedded systems are assumed to be too simple and too obscure to be compromised, commonly leading to security and safety being ignored.

Safety critical industries such as automotive, defense, aviation, aerospace, and railway, where any software error can be catastrophic, adheres to industry-specific standards such as ISO 26262 for automotive or DO-178 for aviation and aerospace or IEC 62304 for medical systems. These standards have increasing safety and security requirements and demand certification to compliance via a certification authority or by means of self-certification. Many standards require applying coding standards or companies choose to use them to achieve certification compliance.

In 1998, a set of software development guidelines for the C programming language developed by MISRA (Motor Industry Software Reliability Association) was published, known as MISRA C. It aims to facilitate code safety, security, portability and reliability in the context of embedded systems programmed in ISO C / C90 / C99. [1]

MISRA C has become essential for automation industries with collaborations of big companies and spreads beyond automation industry to the majority of safety-related industries. It is also used to improve software quality even where safety is not the main consideration.

Lockheed Martin Aeronautics Company (LMCO) developed the JSF++ AV Standard during the critical system design and development phase of the Joint Strike Fighter (JSF) project.

Increasing use of C++ in automotive industry led MISRA to define guidelines for C++ specifically, which was named as MISRA C++ and launched in 2008.

These are followed by other standards like Netrino C – The Embedded C Coding Standard by the Barr Group, CERT C, CERT C++. MISRA also continued with updates of MISRA C and addendums of the security guidelines, secure code rules, and compliance guidelines.

Due to MISRA guidelines being so complete and needing only minor improvements, popular embedded compiler vendors implement MISRA rules and show these as warnings to developers.  Since then the usage of MISRA in embedded projects have dramatically increased.

Most of the MISRA rules compliance can be checked using tools like LDRA, PRQA, Parasoft these perform static code analysis. The remaining guidelines require the use of dynamic code analysis and code review. In the new version of MISRA, more effort was spent to make rules be possible to be checked via tools in order to increase usability.

“MISRA C is a subset of the C language. In particular, it is based on the ISO/IEC 9899:1990 C standard, which is identical to the ANSI X3.159-1989 standard, often called C ’89. Thus every MISRA C program is a valid C program. The MISRA C subset is defined by 141 rules that constrain the C language. Correspondingly, MISRA C++ is a subset of the ISO/IEC 14882:2003 C++ standard. MISRA C++ is based on 228 rules, many of which are refinements of the MISRA C rules to deal with the additional realities of C++.” [1]

MISRA classifies guidelines as mandatory, required or advisory.

  • Mandatory guidelines shall always be complied with
  • Required guidelines shall be complied with, unless subject to a deviation
  • Advisory guidelines are considered good practice, but compliance is less formal. [2]

The rules can be divided logically into a number of categories:

  • Avoiding possible compiler differences, for example;
       C Rule 6.3/C++ Rule 3-9-2 (advisory):
       Typedefs that indicate size and signedness should be used in place of the basic numerical
       the size of a C integer may vary but an INT16 is always 16 bits. (C99 standardized on int16_t.) 
  • Avoiding using functions and constructs that are prone to failure, for example;
       MISRA "D4.12 (Required) Dynamic memory allocation shall not be used".
       Dynamic heap memory allocation may lead to memory leaks, data inconsistency,   memory exhaustion, nondeterministic behavior.
       MISRA C Rule 70 (Required) functions shall not call themselves either directly or indirectly
       Inadvertent use of recursion leads to exceed the amount of available stack space and system crash.
       C Rule 18.4: Unions shall not be used.
  • Produce maintainable and debuggable code, for example, naming conventions and commenting.
       C Rule 7.1/C++ Rule 2-13-2 (required): Octal constants (other than zero) and octal escape sequences (other than “\0”) shall not be used.
       Octal numbers almost always cause confusion and are rarely useful. and may misinterpreted as decimal.
       C Rule 13.6: Numeric variables being used within a for loop for iteration counting shall    not be modified in the body of the loop
       C Rule 14.4: The goto statement shall not be used.
       C Rule 14.5: The continue statement shall not be used.
  • Best practice rules.
        C Rule 17.4: Array indexing shall be the only allowed form of pointer arithmetic.
        C Rule 18.3: An area of memory shall not be reused for unrelated purposes.
  • Complexity limits.
        Rule 17.5 (advisory): The declaration of objects should contain no more than 2 levels of pointer indirection. 
        Use of more than 2 levels of indirection can seriously impair the ability to understand the behavior of the code, and should therefore be avoided.
        MISRA "D4.12 (Required) Dynamic memory allocation shall not be used"

 

TOYOTA Motor Cooperation has published research results, which analyzed the inspection sheets from 1997 to 2000, to find causes of malfunctions over more than a thousand cases, where error factors and causes are identified. It shows one “major bug” and three “minor bug” for every 30 coding rule violations, (Kawana 2004): [3]

“Benefits of compliance to programming standards such as MISRA:

  • Promote portability and avoid unexpected results
  • Ensure there is no reliance placed on compiler- or platform-specific constructs
  • Identify unreachable or infeasible code which often indicates a defect that will, at the very least, impact software maintainability
  • Prohibit certain language constructs known to be a source of common errors or security vulnerabilities
  • Measurably reduce program complexity
  • Improve program testability, easing standard compliance and certifiability” [4]

Even developers can benefit from MISRA rules that expend awareness about error prone code and avoid unexpected results.

References:
[1] Using MISRA C and C++ for security and reliability, Greg Davis
[2] MISRA web page
[3] Kawana et al., Empirical Approach for Reliability Assurance of Vehicle Software, Automotive Software Workshop, San Diego, 2004.
[4] MISRA C / MISRA C++ Coding Standards Compliance

Leave a Reply

Your email address will not be published.