Project build version in runtime


When creating TwinCAT software I’ve come across a use case where I want to print out and store the actual version of the project that the program resides in. This can be pretty neat when you do version control, and for instance create a release of your program and want this information available somewhere in the output of the program. I’ve had this scenario when we had a project that was continuously updated. The test/integration team needed constant bug fixes/new software releases. As a software engineer I needed to keep track of what version the test/integration team were actually running at a specific time. By updating the version number in the project information I was being able to log the actual running version of the software in a database, which is important to know when going back to fault trace any strange behavior in a particular test.

The actual information is available under “Project” ->”<Name of project> properties” in Visual Studio 2015.

Project properties

This will give you the following:

Project properties – Common

Now, how do you access this from PLC-code? To start with, for libraries this is easy and is actually documented in the Beckhoff documentation. Here you are supposed to use the type “ST_LibVersion“, and Beckhoff documentation explicitly states “Each library contains a global structure of this data type.” This struct type provides the following data:

TYPE ST_LibVersion : 
STRUCT
    iMajor    : UINT;
    iMinor    : UINT;
    iBuild    : UINT;
    iRevision : UINT;
    sVersion  : STRING(23);
END_STRUCT
END_TYPE

For instance, if you need access to the version of the commonly used “TC2_Standard“-library:

VAR
    sVersion : STRING(23);
END_VAR
    sVersion := stLibVersion_Tc2_Standard;

stLibVersion_Tc2_Standard” is defined as a constant global variable in the project library. In this case it will for instance give you the string ‘3.3.1.0’.

Now, what if you want to include the version of your running program (not library!) that you have defined in your project properties? Because your program is not a library this constant global variable is not available per default as in library projects. What you need to do is to click “Add” next to “POUs for property access” under the project properties.

Project properties – Common (POUs for property access)

This will create the folder “Project Information” and the three functions “F_GetCompany()”, “F_GetTitle()” and F_GetVersion()” in your project. Opening F_GetVersion() gives the following:

Function F_GetVersion()

Perfect, a function returning a “ST_LibVersion” structure holding the Major/Minor/Build/Revision numbers! Even though the “ST_LibVersion” in itself holds a String(23), for some reason this is not included in the call to F_GetVersion (at least not in TwinCAT 3.1.4020.28). Whether this is a bug or not is unknown to me. If you update the project information, this function automatically gets updated with the correct numbers! Now that we have access to this information by calling this function in our own program, we can easily convert this to a string by a mixture of UDINT_TO_STRING and CONCAT.

VAR
    sVersion : STRING(23);
    stProgramVersion : ST_LibVersion;
END_VAR
stProgramVersion := F_GetVersion();

sVersion := CONCAT(UDINT_TO_STRING(stProgramVersion.iMajor), '.');
sVersion := CONCAT(sVersion, UDINT_TO_STRING(stProgramVersion.iMinor));
sVersion := CONCAT(sVersion, '.');
sVersion := CONCAT(sVersion, UDINT_TO_STRING(stProgramVersion.iBuild));
sVersion := CONCAT(sVersion, '.');
sVersion := CONCAT(sVersion, UDINT_TO_STRING(stProgramVersion.iRevision));

Running this code gives the end result:

Program version

Binary code icon by Vectors Market from www.flaticon.com / CC 3.0 BY

  • Share on:

8 Comments, RSS

    • Jakob Sagatowski

      Manually, but it could be done automatically from a build server or such as it’s part of the XML-file definition of the project.

      • Ju-Hsien Lai

        Hi Jakob, can you kindly share the hint of how to trigger automatic version number incremental through build event or the build server you said?

        • Hi Ju-Hsien! I’d solve it by a pre-build step in Jenkins. Simply add a step that opens the .plcproj-file and alters the -tag prior to build. This can be done by any tool, such as a simple Python-script.

  1. wale

    I would like to manage the version incremented automatically and is there a way to do it?
    How can I do it from build server and/or XML file definition of the project?

  2. Stefan Henneken

    Hi Jakob,
    sometimes I use this in my projects too. But I insert the ‘Global version structure’ and ‘POUs for property access’. Inside the global version structure is a constant of the type ST_LibVersion. The element ‘sVersion’ is initialized with the correct string (TwinCAT 3.1.2024).
    stLibVersion_Title : ST_LibVersion := (iMajor := 1, iMinor := 2, iBuild := 3, iRevision := 6, sVersion := ‘1.2.3.6’);
    Now I use this global constant in F_GetVersion:
    FUNCTION F_GetVersion : ST_LibVersion
    VAR_INPUT
    END_VAR
    F_GetVersion := stLibVersion_Title;
    Now, it’s not necessary to build the string for the version number.

  3. Stéphane GUASP ROCA

    Hello,
    do you know if there is a method to have an automatic increment of the build number at the generation of the startup application ?

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.