Coder Social home page Coder Social logo

jmeyer1292 / block_diagram_z3 Goto Github PK

View Code? Open in Web Editor NEW
6.0 6.0 3.0 1.1 MB

Analyze and test safety programs written in the function block diagram language for Siemens' Fail-Safe PLCs with the Z3 SMT solver.

License: Apache License 2.0

Python 100.00%
plc siemens z3 fbd safety iec-61131-3

block_diagram_z3's Introduction

Function Block Diagram Analysis With Z3

โš ๏ธ This is an experimental tool for analyzing safety programs, but it isn't safety rated itself! Please don't rely on this alone for your system designs.

If you find this stuff interesting or useful, please don't hesitate to reach out to me (see email in profile). I want this to be useful!

Forward

Siemens Programmable Logic Controllers (or PLCs) are frequently used in the construction of "safety systems" that mitigate risks to people, but the language and environment used to create software for these systems makes traditional software testing hard. Playing with formal methods in other domains (FPGAs [1]) led me to ask "Why the hell don't we have these tools here?"

This experimental project is comprised of a set of tools that can:

  • consume the serialized (XML) form of a "function block diagram" from Siemens' TIA Portal (V16+), and
  • translate the program into a series of mathematical assertions in that the Z3 SMT solver [0] can understand, and
  • provide some basic tools for you to:
    • symbolically execute the program
    • prove assertions (safety tests)
    • run covers (liveness tests)

Here's an example of what the TIA Portal IDE might show you:

example of a function block diagram

Example

For a slightly more thorough walkthrough, please see the intro doc!

See tests/integration/test_udt_project.py:

def unit_test(program_model: ProgramModel, verbose=True):
    # Symbols here are relative to memory or the entry point.
    # TODO(Jmeyer): No easy way to write inline assertions or reference deeply
    # nested variables. Consider an "in-the-comments" based approach for annotating
    # the actual program.
    exec_and_compare(program_model,
                     # Given
                     {'ToSafety.sensor_ctrl_a.request_mode': 2,
                      'ToSafety.sensor_ctrl_b.request_mode': 1,
                      'ToSafety.app.start':  True,
                      'ToSafety.app.stop':  True,
                      'faults_clear': True},
                     # Expect
                     {'FromSafety.state.running': False})

    # Attempt to prove assertions:
    # Stop => Not(running); Note that the 0 in the read of stop indicates we are asking
    # for the initial state. The final state is given by default.
    stop = program_model.global_mem.read('ToSafety.app.stop', 0)
    running = program_model.root.read('running')
    my_assertion = z3.Implies(stop, z3.Not(running))

    proved, counter_example = run_assertions(
        program_model, [], [my_assertion, ])
    assert proved, f'Counter example: {counter_example}'

    # Run a "cover" to prove a liveness property. Here we try to show that, assuming we
    # are not already running, that "running" is a reachable state.
    initial_running = program_model.root.read('running', 0)
    proved, example = run_covers(program_model,
                                 # Assume
                                 [initial_running == False],
                                 # Show that
                                 [running == True, ])
    assert proved

    if verbose and proved:
        print(f'Our cover passed with the following example:\n{example}')


def main():
    project = fbdplc.project.ProjectContext()

    # The source files:
    project.udt_srcs = glob.glob('testdata/udt_project/PLC_1/**/*.udt')
    project.db_srcs = glob.glob('testdata/udt_project/PLC_1/**/*.db')
    project.tag_srcs = []
    project.fb_srcs = glob.glob('testdata/udt_project/PLC_1/**/*.xml')

    # Execution options:
    project.entry_point = 'Main_Safety_RTG1'

    model = fbdplc.project.build_program_model(project)

    unit_test(model)

Warnings

This is an experimental project meant largely as a proof-of-concept. It SHOULD NOT be used as the primary means by which you validate your programs! It is at best a secondary measure. I can not guarantee that the parsing of programs is bug free nor that behavior of logic operators have the same semantics as the 'real deal'.

The modeling of built-in parts is not comprehensive: Contributions are welcome. The modeling of program execution is very limited, so I would only expect this to work for straight forward safety programs (no control flow manipulation is currently supported).

Installation

See the docs/install.md instructions for information on setting up Python and TIA Portal.

Configuration

Note that this library uses the Python stdlib logging module and logs everything using loggers for each module __name__: You can configure logging for this library globally by accessing the root logger getLogger('fbdplc') and going from there.

References

[0] https://github.com/Z3Prover/z3

[1] https://github.com/YosysHQ/SymbiYosys

block_diagram_z3's People

Contributors

jmeyer1292 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

block_diagram_z3's Issues

Packaging for Pip

This issue represents a desire to for a user to be able to install this library by invoking pip install fbdplc.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.