The functional safety standard for road vehicles, ISO 26262, does not prohibit software with different Safety Integration Level (SIL) to interact and coexist in the same Electronic Control Unit (ECU), for as long as software elements of a lower safety level cannot interfere with elements at a higher safety level. This can be accomplished using software partitioning. The software is split up into parts of different Safety Integration Levels. Next you need to ensure freedom from interference as defined by ISO 26262.
This would be rather simple if all C modules are completely self-contained, i.e. only calling functions and referring variables within in the same module. Unfortunately, life isn’t that easy. C modules will call external functions and will access data declared in other modules. C is about pointers; pointers to data and even pointers to functions. Addresses of objects, passed as parameters, flow through the whole application. How does one keep track of access violations in a labyrinth of code?
The TASKING Safety Checker is a Safety Integration Level (SIL) aware static analyzer which has the ability to verify those accesses. But how? Let’s take a look at the following example:
We can see that the address of the global variable my_global is passed as parameter from function main() via function foo() to function bar() where it is accessed. Let’s assume the two objects in the left column have ASIL-A, the object in the second column have ASIL-B and the object in the right column has ASIL-C. Given this scenario, is it allowed for function foo() to access variable my_global directly?
How is this checked by the Safety Checker? First it determines all relevant actions per function:
With this information, it is possible to construct the call graph, fill in the function arguments and add the required checks:
For this example, creating the call graph it is rather simple. But constructing this can become really complicated when also function pointers are passed as parameters. See the blog Who is calling whom? for more information.
So we end with three checks:
Whether each access is allowed depends on the configuration of the Safety Class Access Rights Table. For each SIL-combination, this table specifies which type of access (read, write, call) is allowed.
If an ASIL-C object is not allowed to write to an ASIL-A object, the Safety Checker will emit the following messages:
The message reports the access violation, but it also tells you how the address of my_global is passed from main() via function foo() to function bar().
Note that even though the address of my_global is also passed by function foo(), it doesn't count as a violation. The only thing that counts is the actual write access in function bar(). This behaviour is identical to an MPU.
For more background on TASKING Safety Checker, refer to the white paper ‘Freedom From Memory Interference - How Safe and Secure Are Current Defences?’ or ‘Freedom From Memory Interference - An ASIL Aware Static Analysis and Associated Tools’.