Cars are more complex than ever, and that means an exponential potential for software defects. As we discussed in "Automotive Software Engineering Defects on the Rise,” modern cars are brimming with software that bridge safety-critical functions, entertainment features, and advanced communications over a vast supply chain. Under these conditions, a single bug or poorly-conceived bit of code can have significant consequences. And while no single tool or practice is a silver bullet, there are important principles for reducing the risk associated with automotive software development.
Leverage Engineering Concepts to Prevent Software Defects
The best way to eliminate software defects is to create an environment where they can’t be introduced, as well as a process for easily identifying and remediating flaws introduced by an upstream vendor. This is achieved by adopting well-established hardware development principles, such as repeatability, the application of known best practices, and the reliance on standards.
As we explained in "How to Leverage Automotive Software Development Standards to Mitigate Risk," achieving functional safety in embedded software requires following these tenets of engineering while designing and coding:
- Functional safety must be proactive
- Processes must be controlled, measured, and repeatable
- Defects should be prevented through the implementation of standards
Implement Development Standards with Policy
Whether building a two-lane highway or coding an airbag deployment system, standards are critical engineering tools. In the embedded automotive space, standards include ISO 26262-6:2011, which covers functional safety for automotive software, and MISRA, a family of C and C++ development standards for safety-related electronic systems in cars.
Implementing standards starts with encapsulating standards compliance within your development policy. As explained in "Leveraging Automotive Development Standards to Mitigate Risk, Part 2," policies are enforceable statements prescribing in plain language how software should be developed and why it should be developed in this way. For example, a policy might state:
- Software must be developed as defined by ISO 26262
- Code will not be accepted from downstream subcontractors that don’t provide adequate traceability proving compliance with the standard
Automate the Application of Development Policy
Turning plain-language policies into enforceable statements requires tools that can continuously apply software quality techniques predicated on industry standards and best practices throughout the SDLC. A mechanism that collects, correlates, and prioritizes findings is also necessary for visibility into processes that potentially inject risk into the application.
If you have a policy that requires all variables to be initialized and all memory be explicitly allocated, then you need a tool that simply won’t allow code with uninitialized variables or references to unallocated memory to be checked in. If such code slips into the code base, a policy should ensure that the flaws will be discovered by static analysis or runtime error detection.
Additionally, if there’s a team or programmer who continually makes those sorts of errors, metrics and metadata analysis will help management understand how those errors are occurring, make sure they are remediated, and offer guidance on how to improve training to make those mistakes less likely.
Imagine that scenario playing out across hundreds and thousands of rules covering the best practices for the development of embedded software. If the commitment is made to adhere to those standards, the tools can make sure the job is done correctly.
Test to Validate, Not to Debug
Testing must be effective, deterministic, and should be done for complex memory problems. Testing should also take place throughout the SDLC so that acceptance tests validate that the application (or the entire embedded systems, such as a complex car) meets its functional and quality requirements and is ready for release.
Unfortunately, many organizations rely on late-stage acceptance testing as a means of debugging their applications, which adds to the cost and risk of the software. The goal of testing is to verify that the code meets internal, regulatory and industry standards, not identify bugs. Tests should pass and results should be documented for future reference (and to satisfy regulators and certification requirements).
We can’t be complacent and believe that the best way to improve the quality of embedded automotive software is to run more tests on a final or near-final product. We have to design and code the software the correct way, the first time, using an engineering approach with policies to leverage and enforce industry standards and best practices. That’s how we address the automotive software quality challenge.