Coding standards for safe, secure, and reliable embedded software

The MISRA C and MISRA C++ standards are a set of coding guidelines for the C and C++ programing languages that promote safety, security, and reliability in embedded system software. These guidelines are published by the Motor Industry Software Reliability Association (MISRA), a collaboration between vehicle manufacturers, component suppliers, and engineering consultancies. MISRA C guidelines, which originally targeted only the automotive industry, are now widely accepted and used in other industries such as aerospace and defense, industrial automation, and medical devices.

Most engineering organizations originally applied MISRA C and C++ standards to their hand-written C and C++ code. The MISRA standards have since been refined to accommodate the use of code generated from tools such as MATLAB® and Simulink®.

Why Is MISRA C Important for Embedded Systems?

The C programming language is one of the most popular languages for embedded systems because of its intrinsic capabilities, such as performance, portability across hardware, and direct control on memory. However, certain C language constructs can lead to programming errors, undefined behavior, or implementation-defined behavior.

The MISRA C guidelines define a “safe-subset” of the C language to protect against language aspects that can compromise the safety and security of embedded systems.

For example, C99 allows the use of initializer lists with expressions that can be evaluated only at run-time. However, the order in which the elements of the list are evaluated is not defined. Take this simple case:

1   int x=0;
2   int y=1;
3   volatile int v;
5   void func()   {
6        int arr[2] = {x+y, x-y};
7        int arr2[2] = {x++, x+y};
8        int arr3[2] = {v, v};
9   }

On lines 7 and 8, an element of the list modifies the value of a variable that is used in another element. The ambiguity in the evaluation order can cause unexpected values. For instance, arr2[] can be initialized with \( \{1,1\}\) or \( \{1,2\}\), depending on the order in which x++ is evaluated. Hence, MISRA C:2012 Rule 13.1 states that expressions occurring in an initializer list cannot modify the variables used in those expressions.

The Evolution of MISRA C

The first edition of MISRA C was published in 1998. MISRA has since published two more editions, MISRA C:2004 and MISRA C:2012, and two amendments to MISRA C:2012. With each publication, MISRA has added new guidelines and provided more direction on how to achieve MISRA C compliance.

MISRA C:2012 also has the following supplements:

  • MISRA C:2012 - Addendum 1 shows bi-directional rule mappings between MISRA C:2004 and MISRA C:2012.
  • MISRA C:2012 - Addendum 2 maps MISRA C:2012 to ISO/IEC TS 17961:2013 "C Secure" rules.
  • MISRA C:2012 - Addendum 3 maps MISRA C:2012 to CERT C rules.

To address the growing use of modeling and automatic code generation tools such as Simulink, Stateflow®, and Embedded Coder®, MISRA published MISRA AC AGC in November of 2007. This document contains guidance on how to apply the MISRA-C:2004 rules in a code generation tool. This guidance was recently incorporated into MISRA C:2012.

How Do I Ensure Compliance with MISRA C:2012?

MISRA C:2012 guidelines are written as rules or directives. A guideline is labeled as a:

  • Rule if the information provided can be leveraged to unambiguously check the source code for compliance. A rule is further classified as decidable if it can be conclusively verified using a static code analysis tool such as Polyspace®. For instance, MISRA C:2012 Rule 11.1 (“Conversions shall not be performed between a pointer to a function and any other type”) is a decidable rule.
  • Directive if the information provided is open to interpretation or relates to software development processes. For instance, MISRA C:2012 Dir 1.1 (“Any implementation-defined behavior on which the output of the program depends shall be documented and understood”) is a directive.

Each guideline is also labeled as Advisory, Required, or Mandatory. To ensure compliance with MISRA C:2012, the project source code must meet:

  • All mandatory guidelines
  • All required guidelines unless subject to formal deviation
  • Advisory guidelines where practical

MISRA has provided additional compliance guidance through publications such as MISRA Compliance:2016 and MISRA Compliance:2020.

What Are Some Important Considerations for MISRA C:2012 Adoption?

Integrate MISRA C Within Software Development Processes

MISRA recommends that the MISRA C guidelines be integrated within a project’s software development processes. MISRA C does not define a software development process but suggests using processes that can be found in functional safety standards such as ISO 26262, DO 178C, IEC 62304, and IEC 61508.

Generate Compliance Matrix

Each project should create a compliance matrix that documents all guidelines and the corresponding enforcement methods. Manual review is required for guidelines that cannot be fully enforced using a tool such as a static code analyzer.

Document Deviations

MISRA allows deviations from guidelines in situations where those guidelines might be impractical or unreasonable to follow. All such deviations must be documented and authorized. The documentation should include the guideline, situation, rationale for deviation, and risk analysis.

Using Generated Code

Code generation simplifies the MISRA C compliance process. Automatic code generators list guidelines that will not be violated by the generated code. To generate code that is MISRA-compliant, the engineer must use appropriate modeling patterns and code generation options. MISRA C:2012 provides guidance on which rules are less applicable for generated code. For example, rules that focus on readability are less important since generated code is not supposed to be modified by humans.

Using Handwritten Code

The MISRA C rules can be checked manually, but looking at hundreds of thousands, or sometimes millions of lines of code for rule violations is not practical. Therefore, MISRA C recommends the use of static code analysis tools to ensure compliance. MISRA C also recommends that software developers check for compliance as soon as code is written and before code review or unit testing. Addressing violations earlier in the development lifecycle is much less expensive and far more efficient than delaying until later stages.

Key MathWorks Products for Developing MISRA C Compliant Applications

Simulink, Stateflow, Simulink Check™, and Embedded Coder are widely used to generate embedded software that conforms to MISRA C and MISRA-C++. Engineers can achieve compliance with the MISRA C:2012 and MISRA C++ guidelines by adhering to the modeling guidelines, code generation objectives, and Code Generation Advisor checks.

To assist users further in their efforts to achieve MISRA C compliance, MathWorks maintains a feasibility analysis package and recommendations for generating MISRA C code when using Embedded Coder with Simulink and Stateflow models. The MISRA C analysis package includes:

  • Documentation with rules summary and detailed examples
  • Simulink models

Polyspace® code verification products are used to analyze handwritten or generated code for MISRA C compliance. Polyspace Bug Finder™ supports the detection of coding rules in MISRA-C:2004, MISRA C:2012, MISRA AC AGC, and MISRA-C++:2008, AUTOSAR C++14. This tool can be used to check generated code and obtain an independent confirmation that the code indeed complies to MISRA C. Engineers can also trace Polyspace results back to the model and annotate at the model level to justify deviations.

7 Ways to Make Embedded Software Safe and Secure