The development of PLC software needs to enter the 21st century. With the increased complexity of developed systems, the amount of software that is going to be developed for a given system will continue to increase. PLC development is partially living on an isolated island, and while most other areas of software development have been modernized, the world of PLC software engineering development is going significantly slower. When we develop more software, there is a need for more automation to remove unecessary manual handling and in the end increase the quality of the software we develop. Now I know that you can’t compare developing software for a web shop with developing software for a PLC that can run software that is critical and maybe even be safety-critical and one line of code can be the difference of life and death. However, developing reliable and robust software and adhering to modern software development processes and tools does not mean they do rule each other out. You can pick both.
Continous integration and continous delivery (CI/CD) is a practice that’s been around in software development for as long as I can remember. CI is about merging all developer working copies to a shared mainline several times a day, whilst CD is an approach in which teams produce software in short cycles, ensuring that the software can be reliably released at any time. PLC development in general has of tradition not adhered to CI/CD, despite the many advantages that it provides. Specifically in the world of TwinCAT software engineering, Beckhoff does not provide a finished “out-of-the-box” solution that makes you and your project “go CI/CD”. Does it mean we should lean back and wait for someone to give us a finished solution? Absolutely not! This is an excellent opportunity to do some really fun stuff! With some open/closed-source projects as well as commercial products and a little code of our own we can get off to a good start.
There is much to be gained by integrating CI/CD into your TwinCAT software development process. I’m a practical person, so instead of just talking of how good technology X or process Y is, I’ve decided to write a series of posts about CI/CD with TwinCAT, with a real-world example. These series will be totalling to a number of four posts which will be about:
- Introduction (this post)
- Preparation & installation
- Writing the automation code and integrating it into the s/w toolchain (part 1)
- Writing the automation code and integrating it into the s/w toolchain (part 2) and discussions
As the topic CI/CD in the realms of TwinCAT software engineering can include almost anything in the process of creating TwinCAT software I need to limit the scope. After some thought and thinking of various use cases of what would be a good example I’ve set the scope of this series to answer the following question:
How can we automatically do static code analysis for our TwinCAT projects, using the same rules for all projects?
By automatically I refer to some software detecting a change in a version control system, opening that project, doing the static code analysis of the TwinCAT software and returning the results. When talking about static code analysis I refer to the analysis of the software that can be done without actually executing any TwinCAT code. The software developer should do nothing else than commiting the code to version control to get his/hers result, and this should be done for all the projects that the developer is working on. Typical checks that we would want to have for all code that is checked in into our version control system are for instance:
- non-assigned return values
- unreachable code
- unusual bit-access
- possible truncated strings
…and over 100 other checks. In the end of the day, we want to increase the quality of our code. We would typically not only want pure functional checks, but we would also like to have checks for naming conventions to make sure all projects follow the same rules. The project could for instance decide to use Beckhoffs own naming convention, or the one from PLCopen, or decide on a complete own set of rules. Which one a project decides to go for is of less importance than having consistency and not having each and every developer going with their own rules.
The static code analysis is done using the same rules for all projects, to guarantee consistency of the code checks. Also, the projects should be able to be created using different versions in TwinCAT 3.1 (such as 4022.0 or 4022.22). The results of the static code analysis are stored in such a way that a person can see the results of this static code analysis for all the projects.
One of the ambitions of this project is that our static code analysis toolchain should support different versions of TwinCAT. For the example, let’s assume we have a project that utilizes a dozen of PLCs, and a mix of three different versions of TwinCAT 3.1:
Now, we need to maintain these three versions because the PLCs are running these different versions. Notice that all versions are 4022.0 or above, as static code analysis in TwinCAT was introduced from that version. Obviously we could could try to consolidate all PLCs to the latest & greatest, but this is often not possible, or most likely not even a particularly good idea. Most likely the software that is running on the older versions of TwinCAT has been developed for some time and is tested. We don’t want to do unecessary upgrades of the TwinCAT runtime (XAR) with the accompanying updated Beckhoff libraries and Codesys compiler risking breaking something. The old saying goes “if it ain’t broken don’t fix it!”, which I often have to remind myself of.
The reason I selected static code analysis as a topic is very simple; almost a year ago I did some initial tests with Beckhoffs (then new) “TE1200 – TC3 PLC static analysis” product. At the end of my post I said I would return to the topic of static code analysis, which is what I’m doing now. But only writing about static code analysis that is done manually is not good enough. The static code analysis process is the perfect canditate for automation! At the point of my first trials (4022.2) TE1200 was buggy, today (4022.22) it’s better (though still not perfect, which I will come back to in later posts).
“Now why would we want to automate the static code analysis? I have my PLC, and my project on my computer, and I can just open Visual Studio and run the static code analysis manually anytime I want!”, I can hear one of my readers think for themself. Yes, if it’s only one PLC and one (relatively simple) project with just one developer working on it the gain might be limited to do static code analysis a’la CI/CD. However, if you are involved in a bigger development project involving a team of software engineers and/or many different TwinCAT-projects running on a bunch of PLCs you will want to have some common checks across the complete software base. By having a common set of rules and doing static code analysis across the complete project, the quality of the code will be significantly increased. Not only will you for instance be able to remove dead code (that doesn’t do anything), detect faulty and unintentional code, but equally important you can make sure that all projects follow and use the same naming conventions, which will increase the readability of the code. It’s also not just a matter of this particular problem, but the question of CI/CD in your TwinCAT software development is much bigger than having an automated static code analysis check for all TwinCAT code. This example of static code analysis is just one example. But I can’t stress it enough of how important it is that you think much bigger than that when you think of CI/CD! Imagine for instance that you had a TwinCAT software development process that made sure all code that is checked into version source control was automatically:
- checked for errors?
- own developed libraries automatically installed in the build-servers for different TwinCAT versions?
- run against a suite of unit tests to find bugs?
- deployed on a PLC and tested against some real or simulated hardware?
This list could get quite big. One final thing before moving on. Including these steps in your development process will significantly improve the maintainability of your software. I would still argue that even if you are working all by yourself and/or with a project of limited size, there are still tasks in the TwinCAT software development process that should be automated as it doesn’t make any sense for a human to execute them. It’s quite a time-saver to check-in some code in a version control system and having it automatically compiled/built, checked and possibly partially tested. In the end of the process you only get a result (e-mail or go to a webpage) where you can see the results. Once you’ve automated these processes once, it’s quite easy to automate other processes as well. By the way, did I also mention that all of this is really fun to do?
I like theory, but I like practice more. How do we get our hands dirty and start about this? A common tool to help with CI/CD is Jenkins, which is an open source automation server helping automating the non-human part of the software development process. Most people that have worked with CI/CD have came across this tool. This is the tool that will detect any changes in our version control repository (where our TwinCAT software resides), and start the artefacts included in the static code analysis. On the subject of version control, I will use GIT (mostly of personal preference), though most popular version control systems are fine. So far all of these are “generic” tools in the sense that they can be used for almost any type of software development project. The final glue that is specific for TwinCAT development is Beckhoffs TwinCAT Automation Interface (from now forward called TcAI), which allows you to do most of what you can do in the TwinCAT IDE (Visual Studio), but through a programming/scripting language. On top of this, we also need a license of TE1200 TC3 PLC Static Analysis. Note that you can still do static code analysis check without a license of TE1200, it’s however limited to a few checks, but for the sake of this guide it’s good enough. TcAI and TE1200 is what we will need to do the actual static code analysis.
Now for the parts in Visual Studio TcAI is not enough. As I’ve mentioned, the TcAI gives access to most (but far from all) functions that are specific for TwinCAT in visual studio (for instance, access to the PLC configuration items). For the rest of the items that are included in the “vanilla” Visual Studio we need to utilize the so called Development Tools Environment interface (DTE). I’ll come back to the TcAI and DTE in future posts.
With that said, this is the end of this part of the series of CI/CD for TwinCAT. In the next part we’ll be looking at doing some software installations and configurations.