Lei Mao bio photo

Lei Mao

Machine Learning, Artificial Intelligence, Computer Science.

Twitter Facebook LinkedIn GitHub   G. Scholar E-Mail RSS

Introduction

Although we might have not been aware, many production systems, such as nuclear power plants, railway, autonomous vehicle, etc., have to be functional safety. Otherwise, there would be catastrophic consequences, such as nuclear power plant explosion, train and vehicle collision, causing human life and property losses. The software components in the functional safety systems have also to be developed by following the safety standards.


Functional safety is a complicated topic that I hardly thought of before I really have to develop something for a functional safety system. Although I am definitely still inexperienced in developing a functional safety system, I would like to discuss my shallow understanding of functional safety and safety certification, especially for software development, from a very high level.

Functional Safety

Functional safety is the absence of unreasonable risk due to hazards caused by malfunctioning behavior.


In an ordinary non-safety system development culture, we just have to make sure the system runs correctly under the assumption that the behaviors in the system is expected. Because the behaviors in the system could be expected and the responses and respond time to the behaviors are well-defined, it is relatively straightforward to develop and test the entire system. If there are unexpected behaviors, the responses and respond time might be undefined and there would be unexpected, sometimes extremely catastrophic, consequences.


A non-safety system does not mean there is no safety components in the system at all, instead, the extent of safety in a non-safety system is limited and often unwarranted.


Table saw is a system that cuts wood. Even though there might be many designs in a non-safety table saw that prevent the user from placing his finger onto the saw accidentally, the user can still find a way to place the finger onto the saw on purpose and cut the entire finger. A safe table saw has a saw stop mechanism. Even if the user places the finger onto the saw on purpose, it will automatically stop and minimize the damage to the user.


Autonomous vehicle is a system that takes the passenger to the specified destination. It is possible that the user could specify a destination in a river accidentally, a safe autonomous vehicle should have a mechanism preventing the car from driving into the river.

Safety Standard

To achieve functional safety for a system, there are safety standards to follow. For example, we have ISO 26262 for autonomous vehicle, and IEC 62304 for medical device.


The safety standards specify the requirements of safety design at different levels. For software developers, part of the safety requirements were translated programming guidelines, such as MISRA C/C++ guidelines and AUTOSAR C++ 14 guidelines.


For example, in the AUTOSAR C++ 14 guidelines, we have the rule A20-8-4.

Rule A20-8-4 (required, implementation, automated)
A std::unique_ptr shall be used over std::shared_ptr if ownership sharing is
not required.

The guideline provides rationales and examples.

std::unique_ptr is more predictable in terms of its destruction, as it happens at the end
of the scope unless ownership transfer occurred. It also has lower overhead than a
std::shared_ptr, as it does not keep internal reference counting.
// $Id: A20-8-4.cpp 308507 2018-02-21 13:23:57Z michal.szczepankiewicz 
#include <memory>
#include <cstdint>
#include <thread>

struct A
{
    A(std::uint8_t xx, std::uint8_t yy) : x(xx), y(yy) {}
    std::uint8_t x;
    std::uint8_t y;
};

void Func()
{
    auto spA = std::make_shared<A>(3,5);
    //non-compliant, shared_ptr used only locally
    //without copying it
}

void Foo(std::unique_ptr<A> obj) { }
void Bar(std::shared_ptr<A> obj) { }

int main(void)
{
    std::shared_ptr<A> spA = std::make_shared<A>(3,5);
    std::unique_ptr<A> upA = std::make_unique<A>(4,6);

    //compliant, object accesses in parallel
    std::thread th1{&Bar, spA};
    std::thread th2{&Bar, spA};
    std::thread th3{&Bar, spA};

    //compliant, object accesses only by 1 thread
    std::thread th4{&Foo, std::move(upA)};

    th1.join();
    th2.join();
    th3.join();
    th4.join();

    return 0;
}

The guideline also provides traceability tables that maps the AUTOSAR C++ 14 rules to ISO 26262 and other guidelines. For example, the AUTOSAR C++ 14 rule A20-8-4 maps to the C++ core guideline “prefer unique_ptr over shared_ptr unless you need to share ownership”.


The programming guidelines force the programmer to create “high-quality” implementations. However, simply following the programming guideline is insufficient for creating a safe program. The programmer would also have to create detailed documentations for program design and unit tests which often contains the traceability to the safety requirements. “Usually one line of the code translates to a hundred lines of documentations”.

Safety Certification

Once the program design and unit test documentations have been created and the program and the corresponding unit tests have been implemented, the software component has to be reviewed and audited for safety certification, either by an internal board or a third-party certifier, depending on the safety standard the program is trying to be compliant with. For example, for some industry-specific standards, such as ISO 26262, companies can self-assess their own compliance. This process is usually very rigorous and time-consuming.

Conclusions

A well-defined safety process ensures that an organization keep safety in mind at every step in the software development lifecycle, including requirement analysis, design, implementation, testing, and evolution. The software development in a safety system consists of analyzing the safety standards, creating the safety requirements, designing the interface and exception handling, implementing by following the safety guidelines, and testing the design and safety requirements thoroughly.

References